Storyboards são uma verdadeira dor de uma perspectiva de fluxo de trabalho git quando várias pessoas estão colaborando neles. Por exemplo, o XML no arquivo .storyboard tem suas <document>
tags toolsVersion
e systemVersion
atributos iniciais alterados por qualquer configuração que o manipulador de arquivos mais recente esteja executando. Sincronizar todas as versões do Xcode parece ajudar com precisão toolsVersion
, mas systemVersion
muda não importa o que aconteça, dependendo da versão específica do Mac e / ou OS X que o desenvolvedor está executando.
Isso é idiota, mas principalmente inofensivo. O que nos preocupa, porém, é que, em outras ocasiões, algumas outras alterações são feitas automaticamente no storyboard apenas abrindo-as após um git pull
. Ou seja, Alice faz alterações em um storyboard, confirma e envia por push para o repositório. Bob então puxa as mudanças de Alice e abre o storyboard para fazer outras mudanças. No momento em que ele abre o storyboard, o ícone do arquivo muda imediatamente para um estado modificado, mas não salvo, e git status
mostra que várias mudanças estranhas ocorreram. Tudo isso sem que Bob tenha alterado nada ou salvo o arquivo por conta própria.
A alteração automatizada mais comum que vemos é o desaparecimento ou reaparecimento de toda a <classes>
hierarquia de tags próximo ao final de um arquivo de storyboard. Não descobrimos o que está causando isso. Podemos ter várias versões localizadas de um storyboard em vários diretórios .lproj e, ao abri-los dentro do Interface Builder, a hierarquia de classes pode ser removida espontaneamente de alguns e adicionada a outros, ou deixada sozinha em alguns. Isso causa muito ruído git diff
, mas não interrompe nenhuma funcionalidade. Frequentemente adicionaremos seletivamente as mudanças reais que fizemos no índice do git, as confirmaremos e, em seguida, apenas descartamos as alterações espontâneas e sem sentido<classes>
alterar. Isso é para manter os commits pequenos e agradáveis, como deveriam ser. Eventualmente, porém, torna-se muito incômodo, já que o Xcode continua refazendo as alterações, e alguém apenas as confirma junto com outras coisas ... o que está bem até que o Xcode de outra pessoa decida alterá-las de volta para não razão aparente. (Nosso histórico de commits tem muitos juramentos sobre isso.)
Alguém mais está vendo esse comportamento? É um bug do Xcode ou um problema de configuração em um ou mais de nossos Macs de desenvolvedor? Vimos algum comportamento semelhante ao colaborar com arquivos XIB, mas os storyboards parecem mais suscetíveis a isso.
fonte
Respostas:
Isso não é um bug, é uma consequência de como o Xcode processa arquivos de storyboard. Estou escrevendo um programa diff e merge para arquivos de storyboard (link do GitHub) e passei horas analisando a lógica dos arquivos de storyboard e como o Xcode os processa. Isto é o que descobri:
Por que mudanças estranhas ocorrem em arquivos de storyboard? O Xcode usa a API NSXML para analisar arquivos de storyboard em alguma
NSSet
estrutura de árvore lógica. Quando o Xcode precisa gravar alterações, ele cria umNSXMLDocument
baseado na estrutura de árvore lógica, limpa o arquivo de storyboard e chamaXMLDataWithOptions:
para preencher o arquivo novamente. Como os conjuntos não preservam a ordem de seus elementos, mesmo a menor modificação pode alterar todo o arquivo XML do storyboard.Por que a tag de classe desaparece ou reaparece aleatoriamente? A
<class>
seção nada mais é do que um cache interno do Xcode. O Xcode o usa para armazenar informações sobre as classes. O cache muda frequentemente. Elementos são adicionados quando os.h/.m
arquivos de classe são abertos e removidos quando o Xcode suspeita que eles estão desatualizados (pelo menos os Xcodes mais antigos se comportam assim). Quando você salva o storyboard, a versão atual do cache é despejada, e é por isso que a<class>
seção costuma mudar ou até mesmo desaparecer.Eu não fiz engenharia reversa do Xcode; Fiz essas observações experimentando arquivos Xcode e storyboard. No entanto, tenho quase 100% de certeza de que funciona assim.
Conclusões :
MyController1
controlador de visualização em um documento de storyboard. Abra o arquivo de storyboard e encontre algo assim<viewController id=”ory-XY-OBM” sceneMemberID=”MyController1”>
. Você pode confirmar com segurança apenas as alterações nesta seção e ignorar todo o resto. Se você alterou segues ou restrições, também comprometa tudo o que estiver“ory-XY-OBM”
dentro. Simples!fonte
Este é um bug no XCode 4.5+, espero que seja corrigido, e sim é um PITA.
Aqui está o bug completo da Apple
Como evitar edições gratuitas do Xcode em arquivos de storyboard?
fonte
Esse problema pode ser atenuado de alguma forma pelo uso extremamente criterioso de
git add -p
qualquer um dos arquivos gerados pelo Xcode, incluindo storyboards, XIBs, modelos de dados centrais e arquivos de projeto, todos os quais sofrem modificações transitórias semelhantes que não têm impacto na interface / modelo / projeto.As mudanças inúteis mais comuns que vi nos storyboards são os números da versão do sistema (como você mencionou) e a constante adição e remoção da
<classes>
seção, cuja omissão nunca vi causar problemas. Para XIBs, é a adição e remoção de<reference key="NSWindow"/>
, o que nem é uma classe no Cocoa Touch. Apenas Uau.Pense nisso como o mar: há maré alta e maré baixa. Deixe isso passar por você.
Ahh. É isso aí.
Você pode ignorar essas modificações ao preparar suas alterações, redefinir as alterações indesejadas e fazer um commit limpo.
A única vantagem que vi nos storyboards sobre os XIBs de um ponto de vista técnico é que a Apple ainda não castrou o FileMerge para se recusar a mesclar storyboards em conflito. (O FileMerge costumava ser capaz de mesclar XIBs, mas as versões mais recentes quebraram isso. Thxxxx pessoal 💜 !!!)
Registre muitos bugs sobre todos esses problemas em http://bugreporter.apple.com/ ! E não se esqueça de criar entradas no OpenRadar .
fonte
Colocando em outra resposta aqui, porque esta situação melhorou muito. O XML para o arquivo XIB que representa o StoryBoard foi bastante simplificado.
Recentemente, também mordi a bala e comecei a usar a interface no Xcode to Source Control. Estou na linha de comando há anos e estou feliz por isso, mas a interface é boa e permite dividir commits, o que é muito importante se você usar um sistema de tíquetes com links para commits.
De qualquer forma, notei hoje que houve uma mudança no storyboard e o diff integrado me mostrou que era um único atributo na tag do documento (systemVersion). Portanto, não é grande coisa.
Eu li artigos onde as pessoas dizem que os SBs foram proibidos em suas equipes por causa de problemas de fusão. Loucura total. Eles são tão incríveis, especialmente agora que têm autolayout inteligente integrado, você realmente está perdendo se não os estiver usando.
fonte
É útil saber por que essa insanidade está acontecendo, mas para aqueles que acreditam em manter seus projetos livres de avisos e que querem apenas um rápido e sujo para que seus projetos voltem a um estado saudável:
Não comprometa nada até que seja explicitamente instruído.
Abra o Xcode e crie um novo storyboard (Command + N> iOS> Interface do usuário> Storyboard). Presumo que você o chame de nome padrão de
Storyboard.storyboard
.Abra o storyboard que o Xcode violou. Vou assumir que sim
Base.lproj/Main.storyboard
.Selecione e copie tudo no storyboard (Command + A, em seguida, Command + C).
Aberto
Storyboard.storyboard
.Copie e cole tudo em
Storyboard.storyboard
.Feche o Xcode.
Abra um terminal e mude os diretórios para o seu repositório.
Substitua
Main.storyboard
porStoryboard.storyboard
(mv Storyboard.storyboard Base.lproj/Main.storyboard
).git add Base.lproj/Main.storyboard; git commit -m "Fix Xcode's insanity."
Desconsidere as alterações para
project.pbxproj
viagit checkout -- project.pbxproj
. Se vocêgit diff
o arquivo, verá que ele acaba de adicionar informações sobre nosso storyboard temporário (que não existe mais).Abra o Xcode novamente e veja se os avisos desapareceram.
Respirar.
fonte
Trabalhar no mesmo storyboard não é um problema. Mas trabalhar no mesmo viewcontroller que cria conflitos no pull / merge é assustador. não podemos evitar que trabalhe no mesmo viewcontroller para uma grande equipe.
O bom é que, na maioria das vezes, podemos consertar os mesmos conflitos do viewcontroller se entendermos a estrutura xml. Nunca deixei de mesclar estes enquanto trabalhava em equipe. Suponha que você esteja trabalhando com um viewcontroller. Sua visão está em branco no momento. Por favor, dê uma olhada na estrutura xml do viewcontroller da opção de código-fonte.
Storyboard é xml delimitado pela tag de tipo de documento. Tudo no storyboard contém na cena sceneID = tag. a marca de cena contém todos os controladores de visualização. Isso é o básico.
Agora adicionamos um UILabel e um UIButton na visualização. Defina também o layout automático dos elementos. Agora parece:
Adicionar um nível / botão ao viewcontroller adicionou algum código novo dentro da tag subview da view. A mesma coisa acontecerá com a adição de mais elementos ou quaisquer alterações da IU. Verifique cuidadosamente a estrutura da tag, que é realmente importante para corrigir quaisquer conflitos.
Agora adicionamos outro viewcontroller no nome do storyboard Homeviewcontroller. Adicionar um novo controlador de visualização significa que ele adiciona uma nova cena sob a marca de cenas. Veja isso:
Neste ponto, vamos mudar a estrutura aleatoriamente e observar os problemas / avisos. Mudamos a etiqueta final do primeiro viewcontroller e salvamos o arquivo. Agora execute-o e veja o aviso. O erro diz que a tag final não está correta, criada a partir da linha 23. Na linha 23, vemos que uma restrição de rótulo está definida sem tag final. Esse é o problema. Agora colocamos a tag final e construímos o projeto. Depois de definir a tag final, podemos visualizar o storyboard com sucesso.
Ao enfrentar qualquer aviso de conflito, compare com sua fonte anterior e altere a fonte. Removemos o código antigo / redundante, mantemos o novo código com tag start-end adequada e consertamos as coisas.
[NB, vou atualizar a resposta com mais alguns casos de teste quando chegar o momento]
fonte