How to collaborate on a project with Xcode Storyboards? - ios

For a project I am developing for iOS, I want to collaborate with some freelancers. For collaborating on 'pure' code I want to use GitHub.
But a big portion of the work, will be on the Storyboards and the connection with the code.
What is good practice here? How do I share the Xcode project with them, so they can work on some elements (branches maybe), somewhat similar to the GitHub method?
Or is there a good alternative?
Anybody got any advice in this matter? Help is much appreciated!

As one of the comments pointed out, Storyboards are just XML files. That means git can easily upload them to Github. As to your initial question, you have to be careful not to modify the same views as your freelancer did, for if you do so, it will give you a merge conflict. What will happen then is that GitHub will modify the storyboards XML file inserting the <<<<<<< HEAD/>>>>>>> commit Id tags to show you where you have both changed something. This will then mess up the graphical storyboard and likely lead to Xcode no longer being able to open the Storyboard. This will throw the following error:
"Main.storyboard"could not be opened. The operation couldn't be completed. (com.apple.InterfaceBuilder error -1.)
To avoid that, simply edit other views, or always pull before starting to edit anything in the Storyboard. And even when using branches, when you'll try to merge you'll run into the same problem. However, it's noteworthy that you could just be working on different branches and the manually apply all the changes to one storyboard. This is tedious, but it works.
Hope that helps,
Julian

Related

Main storyboard on Swift gives Github error

We are coding for senior project. But when I pull project on Xcode, main.storyboard gives an error like in picture. I discarded all changes and cleaned my project, but it did not work. Half of project is on my friend computer, half of is on mine. How can I fix this GitHub error and how can we compound this parts ? Ps : I have backup of my project in another folder.
Storyboards are .xml files. The issue you have recently happened to me after I didn't properly resolve GitHub merge conflicts. When you don't edit the stuff in the <<<<< >>>>>> brackets properly, inside the file that has merge conflicts, you can generate the ID conflicts.
You either have to open the xml file of the storyboard with Xcode itself (or with a Texteditor like Sublime) and fix it manually (if you know what you are doing and where the duplicate elements are, as the file xml-structure is quite complex). The BEST way (especially since you have a backup) would be to go inside the project folder and replace the storyboard file with the old one. You will loose changes made since the backup, but if you commit frequently, it should not be too far behind.
EDIT: If the rest of the stuff you merged relies on a newer version of the storyboard (e.g. IBOutlets or IBActions), you will have to recreate those assets in the storyboard and re-connect them to your code.
Another route instead of replacing the storyboard file would be to do a git hard reset to your last commit before the merge and then attempt to merge again. At that point try to resolve the storyboard conflicts better, which may be very difficult. Don't worry, storyboard merge conflicts are a big pain to every developer. If nothing helps, resetting by replacing the file above should always work.
GENERAL RULE: Try to use multiple storyboards for your viewcontrollers. Group them into storyboards as you see fit. That way if one storyboard gets conflicted, it will easier to reset it and then manually adjust it to the latest state. It is also less likely to get merge conflicts in the first place because it's unlikely that two coders will work on the same storyboard file. Usually working on the same file is fine, when editing different lines but storyboards are different. As soon as you open them you get all sorts of view misplaced stuff and other things edited into the xml automatically. So if you open one and didn't actually change anything, reset the changes and don't commit it.

iOS xib file difference comparison

I pulled code from github and run code, and see the code change as listed in the picture. Please help me clarify what is this info is about, why this happens and does it have any side-effects. Thanks very much!
It's nothing to worry about. When you open an xib it just updates the version number. It has no effect on the resulting xib and you can either revert the change or push it to your repo.
Edit:
Only effect it may have is causing conflicts when using version control but they're easy to resolve conflicts. It doesn't matter which version you decide to keep.

How to reuse an Xcode project into a new project? Static library, Framework, Targets?

I built an iOS project (actually workspace because of Pods) that is 100% functional, with its logic and UI (Storyboard and xibs). Now I would like to reuse this app/project as a "core" for future apps.
I've been searching about it and there are several solutions like Static libraries, Frameworks and Targets. But I am not sure which one would be the best in my case. I would like to reuse all the UI part as well.
I saw that most of the people agree that the best approach for reusing code is static libraries, even thought it looks not so straight forward. But I think for reusing UI probably Targets is the best solution. The problem I see is that if a build 10 apps based on my core project, the new project will be huge, so probably it is not the best option.
I don't know if you guys have any better idea or opinion.
Thanks in advance!!
There are several things you can do, and I will try to go through them.
If you have minor changes on your "base" app, then the best thing would be using targets(build schemes). This way you can add things to build phases and therefore, add files that you need. This might be the quickest possible way to do what you want but here are some drawbacks: What if you have 5 apps, and for each one you have QA and prod. That 10 build phases. If you keep using your app in no time you will find hard to manage it.
Another thing could be to create different project, and include all the files you have (and you need), inherit from there and have extended functionality/UI/UX. This is slower approach then number 1, but you will have dependency on the files that you might change in one app and don't want to propagate that change in other apps. So the drawback would be that you have to be extra careful, and plan a lot of things in advance.
Third thing could be to create base app group(or project) and then you are certain what to do, where and what that change could do to other apps(since you know that this file is actually being reused).
And finally, there is a framework, which is my favorite. I am working on one project that inherits base app and we found that is a huge problem. You start separated and then, one thing by one, you have entangled code for specific app and base app like headphones in pocket. And if you don't refactor it ASAP, it will became really hard to resolve these kind of issue. Not to mention merging and other stuff. Here is an excellent article about creating framework http://www.raywenderlich.com/65964/create-a-framework-for-ios . Off course, there is a price to pay and that's every change that you create you must update library and add it again to project. This thing can be easily forgotten and if you are working in team could produce build crash.
All after all, you predicate that you will have more then 5 apps, so I would say go with the framework. This way you will have much cleaner and separated app, and won't have to think about changing things and how these changes would affect your other apps.
I recommend you use a custom project template. I did it perfectly today. I had the same needs as your. Follow this link: https://github.com/reidmain/Xcode-6-Project-Templates/tree/master/iOS%20Application.xctemplate
Download it. You can add all the files from existing project into this template, storyboards too. If you have any doubts I will help you.

Xcode changes unmodified storyboard and XIB files

Storyboards are rather a royal pain from a git workflow perspective when multiple people are collaborating on them. For example, the XML in the .storyboard file has its starting <document> tag's toolsVersion and systemVersion attributes altered by whatever configuration the most recent file manipulator happens to be running. Synchronizing everybody's Xcode versions precisely seems to help with toolsVersion, but systemVersion changes no matter what, depending on the specific Mac and/or OS X version the developer is running.
This is idiotic, but mostly harmless. What worries us, though, is that at other times some other changes are automatically made to the storyboard just by opening them after a git pull. That is to say, Alice makes changes to a storyboard, commits and pushes them to the repository. Bob then pulls Alice's changes and opens up the storyboard to make further changes. The moment he opens the storyboard, the file icon immediately changes to a modified-but-unsaved state, and a git status shows that any number of weird changes have occurred. All this without Bob having changed anything or saved the file himself.
The most common automated change we're seeing is the disappearance or reappearance of the entire <classes> tag hierachy near the end of a storyboard file. We haven't figured out what is causing this. We may have several localized versions of a storyboard in various .lproj directories, and when opening them inside Interface Builder, the class hierarchy may spontaneously be removed from some and added into others, or left alone in some. This causes a lot of noise in git diff, but it doesn't actually break any functionality. We will often selectively add the actual changes we made into git's index, commit those, and then just discard the spontaneous, nonsensical <classes> changes. This is to keep commits small and nice, as they should be. Eventually, though, it just becomes too much to bother with since Xcode keeps re-doing the changes, and someone just ragecommits them along with some other stuff... which is fine until someone else's Xcode decides to want to change them back for no apparent reason. (Our commit history has a lot of swearing over this.)
Is anyone else seeing this behaviour? Is this an Xcode bug or a configuration issue on one or more of our developer Macs? We've seen some similar behaviour when collaborating with XIB files, but storyboards seem more susceptible to this.
This is not a bug, this is a consequence of how Xcode processes storyboard files.
I am writing a diff and merge program for storyboard files (GitHub link) and I have spent hours analyzing the storyboard files logic and how Xcode processes it. This is what I discovered:
Why do weird changes occur in storyboard files?
Xcode uses the NSXML API to parse storyboard files into some NSSet-based logical tree structure. When Xcode needs to write changes it creates an NSXMLDocument based on the logical tree structure, clears the storyboard file and calls XMLDataWithOptions: to fill the file again. Because sets do not preserve the order of their elements, even the slightest modification could change the whole storyboard XML file.
Why does the class tag disappear or reappear randomly?
The <class> section is nothing more than an internal Xcode cache. Xcode use it to cache information about classes. The cache changes often. Elements are added when class .h/.m files are opened and removed when Xcode suspects they are outdated (at least older Xcodes behave like this). When you save the storyboard, the current version of the cache is dumped, which is why the <class> section often changes or even disappears.
I have not reverse-engineered Xcode; I made these observations by experimenting with Xcode and storyboard files. Nevertheless, I am almost 100% sure it works this way.
Conclusions:
Cache section is unimportant; you can safely ignore any change in it.
Contrary to what you can find on all forums, merging storyboards files is not a complicated task. For example, let’s assume you changed MyController1 view controller in a storyboard document. Open the storyboard file, and find something like this
<viewController id=”ory-XY-OBM” sceneMemberID=”MyController1”>.
You can safely commit only changes in this section and ignore everything else. If you changed segues or constraints, also commit anything that has “ory-XY-OBM” inside. Simple!
This is a bug in XCode 4.5+, I hope it gets fixed, and yes its a PITA.
Here's the full bug at Apple
How to avoid Xcode gratuitous edits to storyboard files?
This issue can be mitigated somewhat by extremely judicious use of git add -p on any of Xcode's generated files, including storyboards, XIBs, Core Data models, and project files, all of which suffer from similar transient modifications that have no impact on the actual interface/model/project.
The most common junk changes I've seen on storyboards are the system version numbers (as you mention) and the constant addition and removal of the <classes> section, the omission of which I have never seen cause problems. For XIBs, it's the addition and removal of <reference key="NSWindow"/>, which isn't even a class in Cocoa Touch. Just wow.
Think of it like the sea: there is both a high and low tide. Let it wash over you.
Ahh. That's it.
You can ignore these modifications when staging your changes, reset the junk changes, and make a clean commit.
The single advantage I've seen with storyboards over XIBs from a technical standpoint is that Apple has not yet neutered FileMerge to refuse to merge conflicted storyboards. (FileMerge used to be able to merge XIBs, but newer versions broke that. Thxxxx guys 💜!!!)
Please file lots of bugs about all of these problems at http://bugreporter.apple.com/! And don't forget to create entries on OpenRadar.
Throwing on another answer here because this situation has improved greatly. The XML for the XIB file that represents the StoryBoard has been greatly simplified.
I have also recently bitten the bullet and started to use the interface in Xcode to Source Control. I have been on the command line for years and happy there, but the interface is nice and it lets you split commits, which is really important if you use a ticketing system that links to commits.
Anyway, I noticed today that there was a change on the storyboard and the built in diff showed me it was a single attribute in the document tag (systemVersion). So not a big deal.
I have read articles where people say SBs were outlawed on their teams because of merging issues. Total madness. They are so amazing, especially now that they have intelligent autolayout built in, you are really missing out if you are not using them.
It's helpful to know why this insanity is happening, but for those who believe in keeping their projects free of warnings and who just want a quick-and-dirty to get their projects back to a healthy state:
Don't commit anything until explicitly instructed.
Open Xcode and create a new storyboard (Command+N > iOS > User Interface > Storyboard). I'll assume you call it the default name of Storyboard.storyboard.
Open the storyboard that Xcode has violated. I'll assume this is Base.lproj/Main.storyboard.
Select and copy everything on the storyboard (Command+A then Command+C).
Open Storyboard.storyboard.
Copy and paste everything into Storyboard.storyboard.
Close Xcode.
Open a terminal and change directories to your repository.
Replace Main.storyboard with Storyboard.storyboard (mv Storyboard.storyboard Base.lproj/Main.storyboard).
git add Base.lproj/Main.storyboard; git commit -m "Fix Xcode's insanity."
Disregard the changes to project.pbxproj via git checkout -- project.pbxproj. If you git diff the file, you'll see that it has just added information about our temporary storyboard (which no longer exists).
Open Xcode back up and see that the warnings has disappeared.
Breathe.
Working on same storyboard is not a problem. But working on same viewcontroller which creates conflicts on pull/merge is frightening. we can not really avoid that working in same viewcontroller for a large team.
Good thing is, most of the time we can fixed the same viewcontroller conflicts if we understand the xml structure. I never failed to merge these while working in team. Suppose you are working with a viewcontroller. Your view is blank currently. Please ,have a look at the viewcontroller's xml structure from source code option.
Storyboard is xml bounded by document type tag. Everything in the storyboard contains in scene sceneID= tag. scene tag holds every viewcontrollers. Thats the basic.
Now we added a UILabel and a UIButton on the view. Also set the autolayout of the elements. Now it's looks like :
Adding a level/button to viewcontroller added some new code inside the subview tag of the view. Same thing will go for further element addition or any UI changes. Carefully check the tag structure which is really important to fix any conflicts.
Now we add another viewcontroller in the storyboard name Homeviewcontroller. Adding a new viewcontroller means it adds a new scene under scenes tag. Look at this:
At this point, we will change the structure randomly and observe the issues/warnings. We change first viewcontroller label end tag and save the file. Now run it and look at the warning. Error says end tag is not correct which created from line 23. In line 23 , we see a label constrains is set with no end tag. That's the problem. Now we put the end tag and build the project. After setting end tag, we can view the storyboard successfully.
When face any warning of conflicts , please compare with your previous source and changes source. We remove the old/redundant code , keep the new code with proper tag start-end and get things fixed.
[N.B , i will update the answer with some more test cases when get times]

Storyboards and SVN conflicts

This is a problem we never had to deal with until storyboards were introduced - Whenever there was a chance of conflict in UI, we just made sure that no 2 developers ever worked on the same XIB file simultaneously. The reason we refrained from resolving XIB conflicts is that there may be problematic side-effects (XIB is represented in XML format so there isn't a "good" way to merge 2 versions).
Now we are facing this issue because all of our UI elements are within the same .storyboard file - prevention of simultaneous work on any 2 UI elements in the project makes working in parallel very difficult.
Any suggestions as to how to tackle this issue? Thanks in advance for your efforts.
Break up your storyboard into multiple storyboards.
There is no reason for your app to contain only one storyboard. Break your storyboard up into module storyboards. You can use +storyboardWithName:bundle: to load storyboard modules.
See: UIStoryboard Best Practices for other good storyboard ideas.
Update
It's important to note this is not a complete solution to the problem. In the same way you cannot completely avoid the possibility of merge conflicts in source code decomposing a giant class into smaller modules, you can't avoid the possibility storyboard merge conflicts either. The idea is to reduce the likelihood until it becomes a manageable problem.
There will alway be tricky merge situations in a large codebase. A properly decomposed solution will reduce the number of conflicts and minimize the number of lock out needed.
Here's something I came up with when I was just messing around, trying to find a solution.
If you right click your storyboard file in Xcode and navigate to "Open As" you'll see that there are multiple options - the default is "Interface Builder - iOS Storyboard". However, you can also select "source code".
If you open storyboard up in source code mode, it's possible to make changes (although kind of a pain). But you can add code from other storyboards and make changes in your own - I haven't used SVN but with a git repository I can view other versions of the storyboard and copy code in.
I wouldn't say that this is a great solution - I've had some trouble with Xcode randomly crashing when I try to reopen the storyboard in IB. Sometimes pasting code in works, sometimes it doesn't. A few times I had to change the <scene> tag's value. In my experience it's pretty hit-or-miss but if you back up your files before you try anything it might work.
If it does work, let me know - I'm interested in seeing whether a solution can be found to this problem.
Is this about merging XML files?
Fortunately, SVN allows you to change the merge tool you use to perform merging for different types of file. (eg tutorial for using P4Merge)
So now you just need to find a great tool for merging XML files (good luck :) )
there's WinMerge (with the DisplayXMLFiles prefilter), or diffxml, or XMLMerger or a java xmlmerge tool
You can also have a look at a modern source code management tool. Git for example has intelligent merge features. See this link for why you should consider upgrading your workflow.

Resources