Xcode는 수정되지 않은 스토리 보드 및 XIB 파일을 변경합니다


132

스토리 보드는 여러 사람이 공동 작업 할 때 git 워크 플로 관점에서 볼 때 가장 큰 고통입니다. 예를 들어, .storyboard 파일의 XML 에는 가장 최근의 파일 조작자가 실행중인 구성에 따라 시작 <document>태그 toolsVersionsystemVersion속성이 변경됩니다. 동기화 모두의 엑스 코드 버전은 정확하게 도움 보인다 toolsVersion,하지만 systemVersion개발자가 실행중인 특정 Mac 및 / 또는 OS X 버전에 따라 무엇을, 아무리을 변경합니다.

이것은 바보이지만 대부분 무해합니다. 그러나 걱정스러운 점은 다른 경우에는 git pull. 다음에 스토리 보드를 열어서 스토리 보드를 자동으로 변경하는 것 입니다. 즉, Alice는 스토리 보드를 변경하고이를 커밋하여 리포지토리에 푸시합니다. Bob은 Alice의 변경 사항을 가져와 스토리 보드를 열어 추가 변경을 수행합니다. 스토리 보드를 여는 순간, 파일 아이콘은 즉시 수정되었지만 저장되지 않은 상태로 변경되며, git status이상한 변화가 많이 발생했음을 나타냅니다. Bob이 아무것도 변경하지 않았거나 파일을 직접 저장하지 않고이 모든 것을 수행했습니다.

우리가보고있는 가장 일반적인 자동 변경 <classes>은 스토리 보드 파일의 끝 부분에서 태그 계층 전체가 사라지거나 다시 나타나는 것입니다 . 우리는 이것을 일으키는 원인을 알지 못했습니다. 여러 .lproj 디렉토리에 여러 현지화 된 스토리 보드 버전이있을 수 있으며 Interface Builder에서이를 열 때 클래스 계층 구조가 일부에서 제거되어 다른 계층에 추가되거나 단독으로 남겨질 수 있습니다. 이로 인해 많은 소음이 발생 git diff하지만 실제로는 기능이 손상되지 않습니다. 우리는 종종 git의 인덱스에 실제로 변경 한 내용을 선택적으로 추가하고, 커밋 한 다음 자연스럽고 무의미한 것을 버립니다.<classes>변화. 이것은 커밋을 작고 멋지게 유지하는 것입니다. Xcode가 변경 사항을 계속 다시 수행하기 때문에 결국 귀찮게하기가 너무 어려워지고 누군가 다른 것들과 함께 분노를 범하게됩니다 ... 다른 사람의 Xcode가 변경하지 않기로 결정할 때까지는 괜찮습니다. 명백한 이유. (우리의 커밋 역사는 이것을 맹세합니다.)

다른 사람이이 행동을보고 있습니까? 하나 이상의 개발자 Mac에서 Xcode 버그 또는 구성 문제입니까? 우리는 XIB 파일과 공동 작업 할 때 비슷한 동작을 보았지만 스토리 보드는 이에 더 취약 해 보입니다.


실제로 Xcode 프로젝트와 Git은 잘 작동하지 않습니다. 필자는 불필요한 변경 사항을 버리는 것 이외의 다른 방법 으로이 혼란을 피할 수 있다고 생각하지 않습니다. 거의 항상 프로젝트 파일 변경 사항과 다른 xml 파일에 대해서는 변경되지 않았습니다. 어떤 종류의 '솔루션'이 있으면 기쁠 것입니다. 편리한 잠금 기능으로 Xcode가 너무 많이 변경되는 것을 허용하지 않는 Perforce가 마음에 듭니다. 아마 변경하지 않고 검토 만 할 파일에 대해 수동으로 수행 할 수 있습니다.
A-Live

3
자식이나 다른 것과 함께 스토리 보드를 사용할 가치가 없습니다. 친근감있게 설계되지 않았습니다. 우리는 포기하고 .xib를 사용했습니다. .xib는 그다지 크지 않지만 적어도 세분화되었습니다.
ahwulf

스토리 보드는 실제로 많은 것들에 대해 매우 깔끔하지만 XIB와 혼합해야하는 경우가 많습니다. 이 버그가 수정되면 대부분의 시간 동안 그들과 함께 일하게되어 매우 기쁠 것입니다.
JK Laiho

나는 단지 ahwulf의 의견에 대해 언급해야합니다. 세상에서 그들이 친근하지 않다는 것은 무엇을 의미합니까? 그것들은 XML / 텍스트 파일이며 가능한 한 커밋 친화적입니다. 그리고 스토리 보드 및 버전 관리 시스템에 '아니오'문제가 있었지만 유일한 문제는 xcode가 때때로 <classes> 태그를 삭제 한 다음 나중에 읽습니다. 그러나 변경 사항을 보면 쉽게 볼 수 있습니다 git GUI 또는 git -p 또는 모든 dvc에 해당합니다. 나는 .pbxproj 파일을 fyi로 한 적이 없었습니다.
mgrandi

클래스 파일을 읽음으로써 블록을 생성 할 수 있다면 xcode가 클래스 보드를 스토리 보드 안에 넣는 이유를 이해할 수 없습니까? 그들은 일종의 "캐시"입니까? 그렇다면, 그것들을 classes.cache 파일에 넣어 버전 관리에서 제외시킬 수 있도록하겠습니다.
hariseldon78

답변:


78

이것은 버그가 아니며, Xcode가 스토리 보드 파일을 처리하는 방식의 결과입니다. 스토리 보드 파일 (GitHub 링크)에 대한 diff and merge 프로그램을 작성 중이며 스토리 보드 파일 논리 및 Xcode가 처리하는 방법을 분석하는 데 몇 시간을 보냈습니다. 이것이 내가 발견 한 것입니다.

  • 스토리 보드 파일에서 왜 이상한 변화가 발생합니까? Xcode는 NSXML API를 사용하여 스토리 보드 파일을 일부 NSSet논리 트리 구조 로 구문 분석합니다 . Xcode는 변경 사항을 작성해야 할 때 NSXMLDocument논리 트리 구조를 기반으로 작성 하고 스토리 보드 파일을 지우고 XMLDataWithOptions:파일을 다시 채우기 위해 호출 합니다. 세트는 요소의 순서를 유지하지 않으므로 약간만 수정해도 전체 스토리 보드 XML 파일이 변경 될 수 있습니다.

  • 클래스 태그가 사라지거나 무작위로 다시 나타나는 이유는 무엇입니까? <class>섹션은 내부 Xcode 캐시에 지나지 않습니다. Xcode는이를 사용하여 클래스에 대한 정보를 캐시합니다. 캐시는 자주 변경됩니다. .h/.mXcode에서 클래스 파일이 오래되었다고 의심 되면 클래스 파일을 열거 나 제거 할 때 요소가 추가됩니다 (적어도 오래된 Xcode는 이와 같이 동작 함). 스토리 보드를 저장하면 현재 버전의 캐시가 덤프되므로 <class>섹션이 자주 변경되거나 사라집니다.

Xcode를 리버스 엔지니어링하지 않았습니다. Xcode 및 스토리 보드 파일을 실험하여 이러한 관찰을 수행했습니다. 그럼에도 불구하고, 나는 거의 100 %가 이런 식으로 작동한다고 확신합니다.

결론 :

  • 캐시 섹션은 중요하지 않습니다. 변경 사항을 무시해도됩니다.
  • 모든 포럼에서 찾을 수있는 것과는 달리 스토리 보드 파일을 병합하는 것은 복잡한 작업이 아닙니다. 예를 들어 MyController1스토리 보드 문서에서 뷰 컨트롤러 를 변경했다고 가정 해 봅시다 . 스토리 보드 파일을 열고 이와 같은 것을 찾으십시오 <viewController id=”ory-XY-OBM” sceneMemberID=”MyController1”>. 이 섹션의 변경 사항 만 안전하게 커밋하고 다른 모든 항목은 무시할 수 있습니다. segues 또는 constraints를 변경 한 경우 “ory-XY-OBM”내부에있는 내용 도 커밋하십시오 . 단순한!

9
xcode diff / merge 도구에 대한 업데이트가 있습니까? 이 커뮤니티에 매우 유용한 것 같습니다.
Tony

1
내 웹 페이지에서 앱을 얻을 수 있습니다 (프로필 참조). 이 앱은 100 % 무료입니다.
Marcin Olawski

1
XIB를 사용하여 가능한 한 == 스토리 보드를 분할하는 경우. 모든 것을 슬라이스하고 싶다면 XIB를 사용하는 것이 더 쉽고 좋습니다.
Marcin Olawski

7
"저는 Xcode를 리버스 엔지니어링하지 않았습니다. Xcode와 스토리 보드 파일을 실험하여 이러한 관찰을했습니다." 즉 이다 (얕은) 리버스 엔지니어링, 그것의 차가운 . :-)
Constantino Tsarouhas

13
"이것은 버그가 아니며, 이것은 Xcode가 스토리 보드 파일을 처리하는 방식의 결과입니다."물론,이 문장의 후반부는 첫 번째 문장을 설명하거나 합리화하지 않습니다. "이것은 버그입니다. 불행히도 XCode가 .xib 파일을 처리하는 방식의 결과는 불행히도 해결되지 않고 성가신 결과입니다." XCode 5.x부터 6.2까지 (오늘 150311) .xib 파일은 개발자가 수정하지 않으며 IB에서만 볼 수 있으며, xml 변경이 많이 발생합니다. 이것은 생산성에 영향을 미치는 심각한 버그입니다. "NBD, git에서 덩어리를 다루는 것"과 같은 응답은 말이 없습니다.
cweekly

18

이것은 XCode 4.5 +의 버그이며 수정되기를 바랍니다.

Apple의 전체 버그는 다음과 같습니다.

스토리 보드 파일에 대한 Xcode의 무의미한 편집을 피하는 방법은 무엇입니까?


1
4.6에서도 마찬가지입니다. 아마도 버그가 아닐 수도 있습니다.
Thromordyn

4.6.3에는 여전히 있습니다. 스토리 보드 / xibs가 잘 작동한다고 말할 수는 없습니다.
houbysoft

1
"버그가 아니라 기능이다": -S
MrTJ

이것이 버그라는 증거는 없습니다 – 성가신 예,하지만 Xcode가 어떻게 작동하는지
Thomas Watson

1
7.0.1은 이에 아무런 변화를주지 않았다.
Andris Zalitis

11

이 문제는 매우 신중하게 사용함으로써 다소 완화 될 수 있습니다. git add -p 스토리 보드, XIB, 코어 데이터 모델 및 프로젝트 파일을 포함하여 Xcode에서 생성 된 모든 파일 모두는 실제 인터페이스 / 모델 / 계획.

스토리 보드에서 본 가장 일반적인 정크 변경 사항은 시스템 버전 번호 (설명한대로)와 <classes>섹션 의 지속적인 추가 및 제거입니다 . XIB의 경우 <reference key="NSWindow"/>Cocoa Touch의 클래스가 아닌을 추가 및 제거 합니다. 와우

바다처럼 생각하십시오. 만조와 간조가 있습니다. 당신을 씻어 보자.

아 그게 다야.

변경 사항을 스테이징 할 때 이러한 수정 사항을 무시하고 정크 변경 사항을 재설정하고 깔끔하게 커밋 할 수 있습니다.

기술적 인 관점에서 XIB에 비해 스토리 보드에서 내가 본 단일 이점은 Apple이 충돌하는 스토리 보드 병합을 거부하기 위해 FileMerge를 아직 중립화하지 않았다는 것입니다. (FileMerge는 XIB를 병합 할 수 있었지만 최신 버전에서는 문제가 발생했습니다. Thxxxx guys 💜 !!!)

http://bugreporter.apple.com/ 에서 이러한 모든 문제에 대한 버그를 많이 제출하십시오 ! OpenRadar에서 항목을 작성하는 것을 잊지 마십시오 .


6

이 상황이 크게 개선되었으므로 여기에 다른 대답을 던졌습니다. StoryBoard를 나타내는 XIB 파일의 XML이 크게 단순화되었습니다.

또한 최근에 글 머리 기호를 물었고 Xcode의 인터페이스를 소스 제어에 사용하기 시작했습니다. 나는 수년간 커맨드 라인에 있었고 행복했지만 인터페이스는 훌륭하고 커밋을 분할 할 수 있습니다. 커밋에 연결되는 티켓팅 시스템을 사용하는 경우 정말 중요합니다.

어쨌든, 오늘 스토리 보드에 변경 사항이 있으며 내장 diff가 문서 태그 (systemVersion)의 단일 속성이라는 것을 알았습니다. 큰 문제는 아닙니다.

나는 사람들이 합병 문제로 인해 SB가 팀에서 불법화되었다고 말하는 기사를 읽었습니다. 총 광기. 그들은 특히 놀랍습니다. 특히 지능형 자동 레이아웃이 내장되어 있으므로 사용하지 않으면 실제로 빠져 있습니다.


3

이런 광기가 발생 했는지 아는 것이 도움 이되지만, 프로젝트를 경고없이 유지하고 프로젝트를 건강 상태로 되돌릴 수있는 빠르고 더러운 것을 원하는 사람들에게는 다음과 같습니다.

  1. 명시 적으로 지시 할 때까지 아무것도하지 마십시오.

  2. Xcode를 열고 새 스토리 보드를 만듭니다 (Command + N> iOS> 사용자 인터페이스> 스토리 보드). 기본 이름 인이라고 가정합니다 Storyboard.storyboard.

  3. Xcode가 위반 한 스토리 보드를 엽니 다. 이것이라고 가정합니다 Base.lproj/Main.storyboard.

  4. 스토리 보드의 모든 것을 선택하여 복사하십시오 (Command + A, Command + C).

  5. 를 엽니 다 Storyboard.storyboard.

  6. 에 모든 내용을 복사하여 붙여 넣습니다 Storyboard.storyboard.

  7. Xcode를 닫습니다.

  8. 터미널을 열고 디렉토리를 저장소로 변경하십시오.

  9. 교체 Main.storyboard와 함께 Storyboard.storyboard( mv Storyboard.storyboard Base.lproj/Main.storyboard).

  10. git add Base.lproj/Main.storyboard; git commit -m "Fix Xcode's insanity."

  11. project.pbxproj통한 변경 사항은 무시하십시오 git checkout -- project.pbxproj. git diff파일 인 경우 임시 스토리 보드 (더 이상 존재하지 않음)에 대한 정보를 추가 한 것입니다.

  12. Xcode 백업을 열고 경고가 사라 졌는지 확인하십시오.

  13. 숨 쉬세요.


0

동일한 스토리 보드에서 작업하는 것은 문제가되지 않습니다. 그러나 끌어 오기 / 병합시 충돌을 일으키는 동일한 뷰 컨트롤러에서 작업하는 것은 무섭습니다. 우리는 큰 팀을 위해 동일한 뷰 컨트롤러에서 작업하는 것을 피할 수 없습니다.

XML 구조를 이해하면 대부분 동일한 뷰 컨트롤러 충돌을 해결할 수 있습니다. 팀에서 일하는 동안 나는 이것을 병합하지 못했습니다. 뷰 컨트롤러로 작업한다고 가정 해보십시오. 보기가 현재 비어 있습니다. 소스 코드 옵션에서 viewcontroller의 xml 구조를 살펴보십시오.

여기에 이미지 설명을 입력하십시오

스토리 보드는 문서 유형 태그로 묶인 xml입니다. 스토리 보드의 모든 내용은 scene sceneID = 태그에 포함됩니다. 장면 태그는 모든 뷰 컨트롤러를 보유합니다. 그게 기본입니다.

이제 뷰에 UILabel과 UIButton을 추가했습니다. 요소의 자동 레이아웃도 설정하십시오. 이제 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

viewcontroller에 레벨 / 버튼을 추가하면 뷰의 subview 태그 안에 새로운 코드가 추가되었습니다. 요소를 추가하거나 UI를 변경해도 마찬가지입니다. 충돌을 해결하는 데 정말로 중요한 태그 구조를 신중하게 확인하십시오.

이제 스토리 보드 이름 Homeviewcontroller에 다른 viewcontroller를 추가합니다. 새로운 뷰 컨트롤러를 추가한다는 것은 scenes 태그 아래에 새로운 장면을 추가한다는 것을 의미합니다. 이거 봐요:

여기에 이미지 설명을 입력하십시오

이 시점에서 우리는 구조를 무작위로 바꾸고 이슈 / 경고를 관찰 할 것입니다. 첫 번째 viewcontroller 레이블 끝 태그를 변경하고 파일을 저장합니다. 이제 실행하고 경고를보십시오. 23 행에서 작성된 종료 태그가 올바르지 않다는 오류가 표시됩니다. 23 행에서 레이블 제한이 종료 태그없이 설정되어 있습니다. 그게 문제입니다. 이제 종료 태그를 넣고 프로젝트를 빌드하십시오. 종료 태그를 설정하면 스토리 보드를 성공적으로 볼 수 있습니다.

여기에 이미지 설명을 입력하십시오

충돌에 대한 경고가 발생하면 이전 소스와 변경 소스를 비교하십시오. 이전 / 이중 코드를 제거하고 새 코드를 적절한 태그 시작으로 유지하고 문제를 해결합니다.

[NB, 시간이 걸리면 더 많은 테스트 사례로 답변을 업데이트합니다.]

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.