31

Hello I'm trying to publish a iOS (SWIFT) personal project in GitHub but I'm afraid of sharing my private API keys and secrets with everybody.

I'm using parse so I have in my AppDelegate something like this:

let applicationId = "mySecretApplicationId"
let clientKey = "mySecretClientKey"
Parse.setApplicationId(applicationId!, clientKey: clientKey!)

I would like to hide "mySecretApplicationId" and "mySecretClientKey", is there private place or directory in my project where I can put this variables?

Thanks!

Manuel Martín
  • 338
  • 4
  • 8

3 Answers3

38

You can use a .plist file where you store all your important keys. It is very important to put this file into your .gitignore file.

In your case, you need to set your keys.plist file like this: enter image description here

And use it inside your AppDelegate as follows:

    var keys: NSDictionary?

    if let path = NSBundle.mainBundle().pathForResource("Keys", ofType: "plist") {
        keys = NSDictionary(contentsOfFile: path)
    }
    if let dict = keys {
        let applicationId = dict["parseApplicationId"] as? String
        let clientKey = dict["parseClientKey"] as? String

        // Initialize Parse.
        Parse.setApplicationId(applicationId!, clientKey: clientKey!)
    }

SWIFT 3 Update:

 if let path = Bundle.main.path(forResource: "Keys", ofType: "plist") {
        keys = NSDictionary(contentsOfFile: path)
    }
EnriMR
  • 3,924
  • 5
  • 39
  • 59
  • 3
    It should also be noted that even once you've done this, those keys will still be in your git history. To get around this, just generate new API keys that have never been in the repository in the first place. – rpowell Oct 07 '15 at 05:00
  • 10
    How do you prevent them from being included in "Copy bundled resources"? Wouldn't the end user still be able to just show package contents and see the keys.plist file inside the Resources folder? – xandermonkey Dec 17 '16 at 04:11
2

Put them in a configuration file that you add to the .gitignore file. Check in a sample configuration file that every developer can use to create their own configuration.

Gregor Raýman
  • 3,051
  • 13
  • 19
0

If you want to share your project without keys then:

  1. Add Keys( as you prefer - enum, struct, or even object/singleton)
struct Keys {
    static let sandboxToken = "Tpk_hh43nneu3jwsu3u"
    static let productionToken = "pk_b5h4uend8ejwnw8"
}
  1. In your code add follow code:
extension APIManager {
    enum Environment {

        case sandbox, production

        var apiKey: String {
            switch self {
            case .sandbox:
                return Keys.iexSandboxToken // <- Here

            case .production:
                return Keys.iexProductionToken // <- Here
            }
        }
    }
}

or if you want to deal with optionals then you can add something similar to:

struct Keys {
    static let sandboxToken: String? = "Tpk_hh43nneu3jwsu3u"
    static let productionToken: String?
}

and on use add assert

        var apiKey: String {
            switch self {
            case .sandbox:
                guard let token = Keys.iexSandboxToken else {
                    assertionFailure("Please fill the tokent in Keys.swift")
                    return "anything you want"
                }
                return token

            case .production:
                guard let token = Keys.iexProductionToken else {
                    assertionFailure("Please fill the tokent in Keys.swift")
                    return "anything you want"
                }
                return token
            }
        }

So, in production, it will fail.

  1. Add it on .gitignore. So, your keys are hidden.
WINSergey
  • 1,977
  • 27
  • 39