Xcode iPhone project open source files to distribute - ios

I've written an iPhone application and I'm planning to open source it. I'm concerned about distributing the source and making sure I get only the required files distributed. I'm also concerned that since I've signed my app for distribution on the AppStore that open sourcing the project would possibly expose some part of the singing certificates.
Is there an accepted practice for what to distribute? I was going to exclude the build directory but wanted to included what was required for anyone to easily open and build the project. I tried this as a test by copying all but the build folder and was able to open and build the project from the copy which didn't contain the build folder so that seems fine.
I guess the bottom line is can I safely distribute the entire project minus the build directory or are there things embedded in the project files I'd want to exclude beyond the build directory?
Thanks for any responses I'm pretty new to xcode

The Code Signing Identity setting (of either your project and/or target) sometimes contains your name (or your organization's name).
So I'd clear out that setting (in all configurations) from the project file.
All the really sensitive items (e.g., your private key) are kept in the OS X keychain, not in any project files.
Inside ProjectName.xcodeproj, you'll find project.pbxproj and some other files. You only want to distribute project.pbxproj, the other files are specific settings for you/your computer. Also, project.pbxproj is just a text file. You can take a look inside and see what you're giving out.

Related

When to check "Copy items if needed" for embedded binaries?

When I tried to put a third-party framework(installed by carthage) in the embedded binaries, I got such an option. I got confused, since "Embedded binaries are binary files that are copied to your application bundle when you build the project", It is already a copy instead of a link, why do I want a copy of a copy?
"Copy items if needed" has nothing to do with the building of your app. It means copied into the project folder, right now (if it isn't in the project folder already). I suggest you always say yes, because otherwise your project might end up depending upon stuff that isn't in the project folder, and which you might therefore throw away or rename by accident, thus causing your project to break.
Like matt has said, I recommend you always leave it selected as well. I have had troubles uploading the app, even though I know I have not moved or renamed the file. Also an extra benefit of leaving it enabled is that it makes it easier to share the project with others without having to track down the files not in the project folder.
I can see two cases why leaving it off might be convenient:
You have multiple projects which share the same file and want to reduce space,
You desperately need to save the space on your computer, in which case I would buy extra storage for your computer.
Edit: Even though you copied the file in, XCode treats it as a link to the file, this is why you are seeing this message.
Xcode Copy items if needed
Copy items if needed usually (but not always, e.g. the project already contains this item) copies files into your project directory as a result you can use relative path(instead of absolute) safely. For example when you use some version control(Git, SVN...) your team members will not have some troubles with solving issues with paths
In case of third-party framework you can use $(PROJECT_DIR) in Build Settings -> Framework Search Paths
*Also do not forget additionally set dependency if not dyld: Library not loaded[About]
[Create groups vs Create folder reference]

$(AppIdentifierPrefix) is not resolved during build time

$(AppIdentifierPrefix) in .entitlements file is not getting replaced with the actual AppIdentifierPrefix. Can someone please shine some light onto this issue?
So here is my understanding of the YourApp.entitlements file that gets added to your project when you add capabilities like iCloud or Game Centre to your application.
(I'd love to see some pointers to official documentation ... if any exists.)
What are these entitlements files used for?
So first of all, the .entitlements is only in your project for the build process. It should not end up in the final .app product. If it does, select the .entitlements file and in the File Inspector, clear it's Target Membership. (This is how Xcode generated these files actually, without any target membership)
So what is the .entitlements file used for then? It is part of the build process where it is taken and processed and put in your final application bundle in two forms:
First: the contents of the .entitlements file is embedded in the embedded.mobileprovision file. This is a signed property list with a binary signature on top but if you open it up in a text editor you can see there is a <key>Entitlements</key> section that should have the processed entitlements in there.
Second: there is also a copy of the .entitlements file called archived-expanded-entitlements.xcent. This is essentially the same file as the original .entitlements file except that it has been processed.
What preprocessor values can be used in the .entitlements file
I don't think the processing of the .entitlements file is documented anywhere. There most certainly is a pre-processor running over it, so that things like $(AppIdentifierPrefix) are replaced with the actual value. However, this seems to be not the same as the one that is used for the Info.plist file.
The $(AppIdentifierPrefix) is the same as the Team Identifier that you may have configured in your Xcode project. You can find the configured Team under your target's General settings in the Identity section. If team is set to None then there is a good change that $(AppIdentifierPrefix) won't be set.
So to finally answer your question: if you look at those two files that I mentioned above, and you still see the $(AppIdentifierPrefix) is not correctly substituted, make sure your project has a Team Identifier configured.
How does Xcode know what entitlements file to use for your target?
In your build settings you can look at the Code Signing Entitlements settings to find out what file Xcode uses for each build configuration. Usually Debug and Release use the same entitlements file but you can change that.
(For example, for Firefox for iOS we have build configurations for Nightly, Aurora, Beta and Release builds. These all have different entitlements files. The reason we have different entitlements files is because we could not make the .entitlements pre-processor recognize settings like $(PRODUCT_NAME:rfc1034identifier) - i'd love to hear if there is a way to do that because that will make our build simpler.)
What tool processes the .entitlements files?
Not entirely sure. But if you look in the build logs, you will see some reference to a builtin-productPackagingUtility tool. This seems to be an internal Xcode command, not something actually present as a command line tool. So that is not very useful.
Now you know pretty much everything that I know about .entitlements files :-)
(I'd love comments and turn this answer into the definitive guide to entitlements files - i think there is a lot of confusion around them)

Xcode has started making archives, not apps. How do I change it back?

Im' writing an phone app in Xcode 4.2. At some point in the last few days, I changed something - I don't know what, and there's nothing obvious in the git history - and although I can still run it on my device and in the simulator, when I archive the build it makes an archive instead of an app. I can't share these archives as IPA files; if I try I get told "No packager exists for this type of archive".
What did I do? How do I change it back so I can produce IPAs again?
I did the following to make it work for me:
for the three20 static library, I used cocoapods to include the files within the main project.. it just got rid of all the trouble three20 was giving me (and they are lots..) btw i tried replacing three20 with Nimbus.. but Nimbus was lacking on some of the features that my project was using three20 for.. so Nimbus wasn't helpful.
set skip install to yes under build settings for all other sub projects/static libraries and switched the copy headers from public to project under build phases
most importantly: under the sub libraries.. under build phases i ensured that copy files destination was changed from Absolute path to products directory.
and that was it!
hint: to get an idea of the offending files that's causing your archive to create an archive file rather than an ipa do this:
Select the archive and click the Distribute button.
Select the 'Save Built Products' option.
Hit Next and Save.
Browse the created directory in Finder.
The 'libraries' subdirectory will identify the libraries that you need to set the Skip Install to Yes.
in some cases usr/local/include will identify the culprit header files you need to move from Public to Project or the files that you have to change from absolute path to products directory. but that directory (ie usr/local/include) varies depending on your sublibrary directory structure
Make sure for any intermediate targets you select "Skip Install" for its build settings.
Click ont the build dropdown in the top-right of your Xcode window and select "edit scheme" and see if anything is wrong there.
If you can't see anything, try selecting "manage schemes" then delete your old schemes and press "autocreate schemes now" to make a new one.
You only want one scheme, for your app build (or one for each target if there are multiple targets). If there are other schemes (e.g. for embedded sub projects used to create static libraries used by your project) delete them.
Also, as jrtc27 says, if you have got any sub-projects that produce static libs, you need to mark them as "skip install" in the build settings. There's another question here that relates specifically to that issue and has a more detailed explanation of how to fix it:

What's the best way to swap Xcode contents for projects intended for many clients?

I've got a relatively large Xcode project that produces a single app. However, I have many clients/customers who require deep customization and branding of said app. These configurations include different graphics, a few different interfaces and implementations, and, perhaps most importantly, .xcconfig files.
My Xcode project has a dedicated group that points to a particular client's customization folder on disk, so by opening the Xcode project and building, you get a build of the single app with the current client's customizations. To switch to another client, I change where that group points to on disk. (I also change and switch-back the xcconfig "Based On" settings in the project's Info pane to reload the full xcconfig inheritance; Simply changing the group containing one or more xcconfig files doesn't reload this!) This has worked great for 100+ clients. It's a little tedious to switch this folder every time you need to build the app for a different client and ensure the xcconfig is correct, but it works.
Now I'm in the process of automating builds via the command line, and running into troubles. The quick and dirty solution to pointing the aforementioned Xcode group at a different customization folder was to copy the ProjectName.xcodeproj/project.pbxproj file to ProjectName.xcodeproj/project-template.pbxproj and put placeholders inside this file that can be grepped and replaced with the name and path of the desired customization folder. Then, temporarily overwrite project.pbxproj with the modified project-template.pbxproj, and build to get the correct app.
As you've probably observed, the project.pbxproj was duplicated and modified, and will therefore get out of sync as developers modify the original and forget to also update the template. And besides, I shouldn't really be messing with pbxproj files in this fashion anyway -- that's Xcode's private stuff.
So, is there a better way to tell Xcode about a folder full of resources, code, and config files perhaps during the Build Phase with a script or environment variable, rather than at the project group level? The most complicated bit seems to be the xcconfig chain, since each client has their own xcconfig file that inherits from the single app's Debug, Development, and Distribution xcconfig files.
Sorry for the long-windedness of this question, but it's a little complicated! Any suggestions would be greatly appreciated!
I think you would way better off using the targets feature in Xcode. Have one project and the resources of every clients in that project.
You can then duplicate the target you already have (right-click on your target, by selecting the project file in Xcode's Project Navigator).
All your targets will be compiled with the same code. You just need to change the resources in Build Phases > Copy Bundle Resources to have different app created for each target. No need to look at Xcode's internal files.
You can even change the code in your source files by adding a preprocessor macro in your build options (something like FIRST_CLIENT=1) and then look for these definition in your file with #if FIRST_CLIENT.
I have a project set-up like this and it works pretty well :

How can I copy a file to the iOS simulator using Xcode?

I need to know how to copy resources (help files, images, pLists) to the iOS simulator and ultimately device. I recall this was done through Xcode but what is the exact procedure?
Just drag the file to your simulator
For iOS 6, the directory seems to be a bit different. I'm seeing:
~/Library/Application Support/iPhone Simulator/6.0/Applications/your app here/Documents, where 'your app here' is a long string. Fortunately, if you click on each directory, you'll see the name of the app you're building in the child directory. From there, it's straightforward to find the Documents folder.
You can drag your file to simulator or you can right click to file then send->Simulator.
Both work for me.
Just drag your file to the project. It will be copied to your app bundle when the app is installed (on the simulator).
Alternatively, put the file into ~/Library/Application Support/iPhone Simulator/User/Applications/... (if you have the 3.2 SDK.)
From the XCode docs.
A Copy Files build phase allows you to copy files and resources of any type to specific locations as part of the build process. It complements the build phases that copy specific types of files. An example is the Copy Headers build phase, which deals only with header files. You can have as many Copy Files build phases as you need in a target.
For example, using a Copy Files build phase, you can copy fonts to/Library/Fonts. Or, if you’re developing a plug-in, a Copy Files build phase can copy the generated plug-in to the appropriate location. You can have as many Copy Files build phases in a target as you need.
To create a Copy Files build phase:
In the project window, open the target to which you want to add the build phase, and select the build phase after which to add the new build phase.
Choose Project > New Build Phase > New Copy Files Build Phase. Xcode adds the new Copy Files build phase after the build phase selected in the Groups & Files list.
Drag the files you want to copy from the Groups & Files list to the Copy Files build phase.
To configure the new Copy Files build phase, select it and open the Copy Files build phase editor, shown in Figure 2-5.
Just copy files to iCloud Drive. Then open the files app on the simulator and sign into your iCloud account.
Get the folder in the Mac Finder and make an Alias
Yes getting the Path by Xcode, but using the Mac Finder and an Alias to get there, doing the file copy operations, is very smooth and solid.
I get my files into my Simulator units by:
Getting the path by putting a breakpoint in Xcode at (anywhere you like in the app code):
let FilePathName: String = NSTemporaryDirectory()
Using the Mac Finder going to, the simulator unit disk and application location (yes, it is in the Mac). There you find all the local folders of the simulator unit.
The path to the the Device unit and to the Application is like a crypto string and not that easy to separate from many other such in the folders alike, but quickly made.
Finding the folder of your choice, make an Alias, move the alias to the Mac Desktop.
Then you have a smooth way to the simulator units app storage
But an Alias must be made for each simulator unit and app.
The advantage is that you are dealing with the regular tool of Mac Finder folder/Alias and it is quite capable of handling large volumes of files, very smoothly.
You put the files exactly where you want them.
The Alias works like regular Alias works in a Mac.
By some upgrades of Xcode the simulator units are rest and the data has to be re-copied into the units.
The other suggestions are not that bad
Just copy files to iCloud Drive, works very smooth, is a good alternative.
But need to login,
But then the files need to be copied from the iCloud Drive to the simulator units storage, unless you want to use data in the iCloud? (The topic of the question was How can I copy a file to the iOS simulator using Xcode?)
Drag'n drop to the Simulator unit, should be the obviously most smooth way of doing it.
But I find it slow and not really reliable, I found it hanging copying volumes of files
I find also my suggested way giving much better control over the file storage, the desktop Mac is by far more easier to handle data than a phone or tablet?

Resources