XCode: How to separate confidential information from source code? - ios

I'm a beginner in iOS development, and trying to build a practice app using Facebook Graph API.
When I integrate with the Facebook API, it requires me to store App ID into Info.plist file of
the project.(https://developers.facebook.com/docs/ios/getting-started#configure)
Although Facebook's app id is not super confidential, I want to open source my repository on GitHub, and having to upload App ID along with source code bothered me.
I could add such file to .gitignore, or make sure I delete confidential information whenever I upload it to GitHub, but they are apparently error prone, and not elegant at all.
Coming form the Java background, I used to store database passwords and other secretive information as system Environment Variables, or stored them in the build tool's setting file such as Maven's settings.xml, so that they are maintained separate from the source code.
Are there known best practices to decouple confidential information from repository in iOS development?
Thank you.

What about this scenario:
Create a file MyId.txt on your Mac (home directory or a directory that can be shared, for example ~/FacebookConfidential/) to store FacebookAppId.
Add Run Script in your Xcode project Build Phases, read MyId.txt file content and set it to info plist using plistbuddy. The purpose is to update information property list so that Facebook SDK can get the Id at run time.
INFO_PLIST="info.plist"
FACEBOOK_ID=$(<~/FacebookConfidential/MyId.txt)
if [ -n ${FACEBOOK_ID} ]; then
/usr/libexec/PlistBuddy -c "Set :FacebookAppID ${FACEBOOK_ID}" ${INFO_PLIST}
fi
Use git pre-commit hook to clean FacebookAppId in info plist or change it a stub value, which make sure FacebookAppId is not committed to repository. You may also want to invoke plistbuddy in the hook.
A collaborator need to do step 1 and create ~/FacebookConfidential/MyId.txt on his system.
This way, the FacebookAppId is saved on your system, the only thing to share is the path. Hope this shed light.

Related

Firebase - Multiple Projects (dev and prod) same app target

I'm looking at Firebase documentation on how to achieve this (see here). Here is the instruction:
If the builds are part of a single target, the best option is to give both configuration files unique names (e.g. GoogleService-Info-Free.plist and GoogleService-Info-Paid.plist). Then choose at runtime which plist to load.
However, at the end of the page, there is "caveat" to this implementation:
On iOS, do not add GoogleService-Info.plist to your project if you are supplying different configuration at run time, as this can result in an apparent change of GOOGLE_APP_ID and result in lost Analytics.
Since I'm trying to add multiple environments to an existing app (live in the App Store) that has a GoogleService-Info.plist added to its project, does that mean I cannot do that since it will result in lost Analytics? Or, can I simply remove the GoogleService-Info.plist and add the environment specific ones, without any problems?
The GoogleService-Info.plist is recommended since it allows Analytics to report early events. If you configure it at run-time, says switching from Google App ID A to B, then you will lose events of A logged before configuring with B. It's more like a warning to let you know the risk of using the runtime API.

How to reverse engineer an Xcode project from an app?

Xcode deleted my project and everything is gone. The only thing that I have is the app in my iPhone 6. So is there any way that I can retrieve the Xcode project of the app?
.. Update ..
i found all the files now i just need to reassemble them in a new project . but I don't know how .
Let's be clear: Xcode did not delete your project, you did, perhaps inadvertently. This does happen to most of us.
The answer is to recover from your remote Git repository or recover from Time Machine or another backup. If you do not have any backup this is your first warning that you need a backup strategy. Make this your last such warning by immediately, as in right now, creating a backup scheme, preferably two. Little is more important.
There are free remote Git repositories such as BitBucket. Setting up Time Machine is simple, just get an external disk, connect it and you will be prompted. Or use another backup scheme such as BackBlaze.
Without a backup you can recover the assets but not code from the ipa from your phone. If you are using the Asset Catalog that is not easy but can still be done.
Unfortunately,
There is no current way to un-archive an app. You must have the .xcodeproj file in order to make changes. The .ipa is useless in terms of editing or changing your app. And if there was a way to do so, it could and would be abused and many clones/copy's/fakes of popular apps will be published. The only accessible files are things in the Main Bundle which only include, .pngs, .jpg, .txt etc but no source code.

How can be an open source project released without publishing a few (private) parameters?

I'd like to release one of my projects (an iPhone app).
The problem I have is that I use Parse, google admob and google analytics, so all of them have private keys or app keys that I have to remove when publish them as open source. But I stil want to continue the development of my app from that repo.
How can I automate the process of removing that data and at the same time add them when I work with the project? I want to avoid uploading that private data by mistake.
I'd like to know your suggestions or ideas about this topic.
BTW, I prefer to use BiitBucket or GitHub, maybe they have some feature or plugin for that, no idea.
A good practice consists in gathering all your private keys in a config file (in the case of your app it would be a header containing several define), and add this config file to the .gitignore of your project. Then in your README simply mention that contributors should create in their workspace this config file with their own private keys.
By doing this you will first have a unique config file, so you know where to look at when you want to update a key, and secondly it will prevent you from publishing it by mistake.

iOS - Distributed applications plist

I'm using git with an iPad xcode project.
I have an application settings plist file (AppSettings.plist) that is included in the projects repo.
I'd like my devs to have this starting AppSettings.plist when they do a fresh clone but I wouldn't like this file to be committed each time it's updated, so each dev can keep their own version.
I though about .gitignoring it and supply an AppSettings.plist.dist but how could we remember the builder guy to update this file each time we want to have him to ?
So you do not just want a static template of the file, but you also want to modify the file and get these modifications merged into the working copy?
Note: Let’s call AppSettings.plist “working copy” and AppSettings.plist.dist “Template”
My proposal would be to add a version number to the file. When you do changes in the repo, you increase the version number. Then when building you check these numbers in the working copy and the template and emit an error if they don’t match.
If you don’t care about newer/older, you can also use git’s ident feature. That will add the blob id of the template to on checkout. If that id is not the same in the working copy, it is obviously not based on that template.

Build information in iOS Application (date/time app was built)

I'm looking for a way to dynamically add in information about the application during the build process of an iOS application.
During testing, it would be great to know when the application I have installed on my device was built and possibly who built it would be a good to know as well.
I'm envisioning a section in settings.app that would give basic build information for debugging purposes. I don't want to have to manually update a build information file before each build - the data should be generated dynamically.
You can also use standard macro __DATE__ which will result string like "Jun 25 1980" of course with proper current date of build.
You can write a shell script build phase in Xcode that runs at the end of your build process. In this phase you can use the defaults command to write data to an arbitrary file. I've used this technique to write to the Info.plist file, but you can write to any file you want[1].
Here's a sample script to write the current git version to Info.plist:
infoplist="$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH"
gitversion="$(cd "$SRCROOT" && git describe --always --dirty 2>/dev/null)"
if [[ -n "$gitversion" ]]; then
defaults write "${infoplist%.plist}" GitVersion "$gitversion"
fi
You should be able to adapt this to point to the file you want (e.g. your Settings bundle) and write the info you want.
[1] Be careful if you write to Info.plist, Xcode has bugs that can prevent it from realizing Info.plist changed during the build, which can break the provisioning when doing a device build.

Resources