How to automatize iPhone app generation? - ios

Ok, we wish to do something along the lines of... this:
Someone enters our site, goes through some forms, registers an account, then a script is executed on the server.
This script will more or less do the following:
Create a folder within the root of our hosting.
Clone a repository which contains a "white-label" iPhone project, with all the code and associated files. The clone will be stored in the aforementioned folder.
Some configuration files will be added to said folder as well (JSON files).
Now, here's the tricky part... We don't know how to approach this:
The script needs to -somehow- be able to automatically generate a fully functioning, valid iPhone app (an .ipa file, I assume, feel free to correct me if I'm wrong) using the files provided in the folder where the repository clone was stored.
Important stuff to take into account:
The app files in the repository do not specify a customized name for the application (the one below the app icon in iPhones...). Instead, it comes with a generic name, which must NOT be present in the app once this "automated app generation process" finishes. Instead, it must use an application name contained in a configuration file (a JSON file, that is).
The "finished app" must have our distribution profile included, and it must be codesigned accordingly.
So basically, we wish to have a server script that ultimately automatizes the process one usually goes through when using Xcode to generate a finished iPhone application. This is because our current business project consists of a white-label app that is "customized" for each one of our clients, and we wish to be as time-effective as possible, avoiding manual processes when we can.
Any ideas? Could this be done? What would be needed?

I have used following terminal command for generating a build for one of my project hope it could be of any help to you
From terminal navigate to the folder where Projectname.xcodeproj file is present and then following command.
xcodebuild -project DummyCam.xcodeproj/ -configuration Release CONFIGURATION_BUILD_DIR="Path to directory where build will be copied" PROVISIONING_PROFILE="${DIST_PROVISONING_PROFILE}"

Related

One different key between multiple Info.plist files per scheme?

My application's Info.plist file has around 20/30 keys inside. An external SDK we're implementing requires its app key to be set in the Info.plist, but requires separate keys for debug, enterprise distribution, and release schemes.
Is there a way I can create conditional additions to the Info.plist without having to maintain three duplicates of the file (and duplicate all of the other keys, which are identical across all targets)?
Basically what I'd like is the base plist exactly as it is now, then additional new -Debug, -Distribution and Release ones, which just contain this new key. What I'm trying to avoid is repetition of all keys, since it will make adding new ones in future a hassle.
Is this possible?
There are a few different things you might try.
Xcode run script executed before app build
This is a script that is automatically executed before you build. Let's say the 3 duplicate plist files are called InfoA.plist, InfoB.plist and InfoC.plist which are all exact duplicate. When you build the project the contents of InfoA.plist are duplicated to InfoB.plist and InfoC.plist. This would require some knowledge of writing a shell script to do that, but the script is fairly simple.
You could duplicate and rename the files in the script. Or you could use command line tools to copy the contents of the main file to the duplicate files. Two command line utilities you can use to modify the contents of plist files are plutil and https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man8/PlistBuddy.8.html. These links might help: Add files to an Xcode project from a script?,
Modify scheme and add pre-action
Your schemes also allow you to add pre-actions to your build and you can do the same as above, but have it configured as a pre-action instead of a build phase script.
Here are a few links that might help: how to make xcode run a script before dependencies?, https://www.objc.io/issues/6-build-tools/build-process/, Xcode: Running a script before every build that modifies source code directly but you could also google for “xcode run script before build” for more links.

Resource files not updating with Xcode 5

I have some binary files with a proprietary extension that don't get updated in a build when I compile. In previous versions of Xcode with this same project, it would detect the file was changed, and rarely would I have to perform a 'Clean' as I have to do with this version. Of course this is consuming a lot more time -- I would appreciate it if someone could let me know what's changed with Xcode 5 and/or what I could do about this.
I didn't include any project specifics because it's really just a proprietary binary file with a custom extension in a resource folder, which, used to update automatically upon it being changed since last compile. If you need any specific project settings I would be glad to offer it.
It's using the sort of 'blue' resource folder that is a reference to the folder it's in, and isn't just copied into the project directory. I apologize since I forget what this particular resource folder type is called (I'm guessing Reference).
Version: Xcode 5 (5A1413)
UPDATE:
This only happens when I'm referencing a file that I modify programmatically with fopen,fwrite,etc, and upon using a file editor in OSX to resave the file (without really changing it) Xcode will then see it as changed.
I'm now looking into FSEvents to see if this underlying API is something I need to use, although I'm not exactly sure how to set flags with this just yet.
UPDATE:
Well, just as a simple test, I take the same file and resave it via:
NSData* data = [[NSData alloc] initWithContentsOfFile: #"/location/file.dat"];
[data writeToFile:#"/location/file.dat" atomically:YES];
Sure enough, after I call that and then run the app that uses the resource, it is updated via Xcode during the build. So it would seem that Xcode 5 relies on some special flags not set by the standard io functions. At this point I can either patch what I've got with that 2 line thing or figure out what the flagging mechanism is, and how to write to it. (FSEvents? I don't see a writing mechanism there..)
I had the same problem. I set up an Xcode build-phase script to touch the root resource folder, and it works now. I found the instructions here and they are as follows (see link for more detail):
1) Add your single resource directory (named anything but ‘Resources’) to your project in the Resources section as a blue ‘Folder Reference’
2) Right click on your app target, select Add->New Build Phase->New Run Script Build Phase
3) In the resulting ‘Info’ window, change the shell to /bin/tcsh and copy and past the script below into the ‘Script’ text view.
Script:
touch -cm ${SRCROOT}/../../YourResourceFolder
(Also, you may need to know how to find "Build Phases" in Xcode 5)
I was also running into problems. Everything was fine before Xcode 5, and my referenced resources folder would copy pretty dependably. However, after updating, no matter what I did to an individual file (touch it, delete and re-copy it, etc.), nothing triggered Xcode to scoop it up again.
However, I now modify the last write time on the referenced folder during my build step, and now it's contents seem to be copying correctly again. I Hope that helps you too.
I am using custom tools, but I'm sure a build script can do the same. My guess is that Xcode tries to optimize the dependency step, and checks the folder's last access/write times before diving into it.
well a simpler way would be to just touch the folder from your shell or term.
e.g. on your terminal just run
touch -cm PATH_TO_FOLDER_UNDER_RESOURCES
PATH_TO_FOLDER_UNDER_RESOURCES is actual path to the folder under resource folders which contains the files.
Since changing your files do not necessarily change the timestamp of the folder and Xcode looks into the timestamp of the containing folder.
I had the same issue with xcode5, I need to update javascript frequently. I had to clean and then build, it took long time because my project had many source files. Later I tried to delete the app (choose "move to trash" rather than "delete reference") and then build, it was quite fast, but I had to restart xcode so that app can appear in the project again.

Xcode iOS project, how to store dev user/pass without putting in version control

We develop an ecommerce app. For convenience when developing, we want to automatically populate the username & password that corresponds to whatever account we prefer on our ecom servers.
The best solution I could come up with so far is:
When debug mode is active, get the username and password from a plist file called debug-credential.plist.
To avoid checking this into git I have to put this file in gitignore.
I also have to add this to the Xcode project navigator so that the framework can find this file when I look for it in the bundle.
So, the problem is, I want this file to be optional. If it's not there, and my app can't find it, just don't populate the password.
No problem, except that the project file I have committed is expecting the debug-credential.plist file and can't find it, therefore won't compile. It would be fine to have the plist file with empty fields checked-in except when the dev wants to specify their own ecom credentials, then git will want to check this in.
Basically I want a way to have a local file, ignored by git, where I can put optional params for my app, and have it so that if a dev checks out a fresh clone, and does not create that file, the app will still run, but just won't have access to the parameters.
Thanks!
I also have to add this to the Xcode project navigator so that the
framework can find this file when I look for it in the bundle.
You don't have to, instead add a shell script to Build Phases to copy files from anywhere to the app bundle, e.g.
ditto -V ./Secret/ "$TARGET_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH"

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 :

Xcode iPhone project open source files to distribute

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.

Resources