This article was written by IZEA Engineer Ben Hanzl. It is for Xcode 7.0 beta 4 and Swift 2.0.
At IZEA, our Engineering team uses the latest tools and technology to build the applications and services that make up the IZEA Exchange platform. Security is very important to us and our users. Hopefully many of your users store their passwords in a password manager such as 1Password. If they do, the user experience of switching between your app and the password manager to find the password they need can be frustrating on mobile. Fortunately, App Extensions, released in iOS 8, allow apps like 1Password to extend their functionality to other apps.
Adding the 1Password Extension
The creators of 1Password have done most of the heavy lifting for you by maintaining an open source extension that you can easily include in your app. You can add the source files directly to your project, but we prefer to use CocoaPods for including third-party libraries.
Add the following to your Podfile and run pod install from your project directory:
pod "1PasswordExtension", git: "https://github.com/AgileBits/onepassword-app-extension.git", branch: "swift2.0"
Check for 1Password
Users will launch 1Password from a button on your sign in view. Since it can be confusing for users that don’t have 1Password installed to see this button, you should check if 1Password is available with the following code and use it toggle the button’s visibility:
let onePasswordAvailable = OnePasswordExtension.sharedExtension().isAppExtensionAvailable() onePasswordButton.hidden = !onePasswordAvailable
Starting in iOS 9, Apple has required that applications explicitly specify the other applications they want to interact with. If you don’t specify an application and attempt to communicate with it, you will see an error message similar to canOpenURL: failed for URL: “org-appextension-feature-password-management://. You can specify that your application will communicate with 1Password by adding a LSApplicationQueriesSchemes array with an org-appextension-feature-password-management item to your Info.plist:
Using Saved Passwords
Populating your form fields with credentials from 1Password is fairly straightforward. Your button would have an action similar to:
@IBAction func populateFieldsFromOnePassword(sender: UIButton) { OnePasswordExtension.sharedExtension().findLoginForURLString("https://domain.com", forViewController: self, sender: sender) { (credentials, error) -> Void in guard error == nil else { print("Error: \(error)") return } guard let credentials = credentials where credentials.count > 0 else { print("No credentials selected") return } self.emailTextField.text = credentials[AppExtensionUsernameKey] as? String self.passwordTextField.text = credentials[AppExtensionPasswordKey] as? String } }
The URLString should be the URL to the website for your app. If you do not have a website, it is recommended that you use your bundle identifier like app://com.company.my-app.
Creating New Passwords
You can also integrate 1Password with user registration, which allows users to have 1Password generate a password and automatically save it. An action from your registration controller would be similar to:
@IBAction func generatePasswordAndSaveInOnePassword(sender: UIButton) { let loginDetails: [String: AnyObject] = [ AppExtensionTitleKey: "APP", AppExtensionUsernameKey: emailTextField.text!, AppExtensionPasswordKey: passwordTextField.text! ] let passwordGenerationOptions: [String: AnyObject] = [ AppExtensionGeneratedPasswordMinLengthKey: 10, AppExtensionGeneratedPasswordMaxLengthKey: 100 ] OnePasswordExtension.sharedExtension().storeLoginForURLString("https://domain.com", loginDetails: loginDetails, passwordGenerationOptions: passwordGenerationOptions, forViewController: self, sender: sender) { (credentials, error) -> Void in guard error == nil else { print("Error: \(error)") return } guard let credentials = credentials where credentials.count > 0 else { print("No credentials selected") return } self.emailTextField.text = credentials[AppExtensionUsernameKey] as? String ?? "" self.passwordTextField.text = credentials[AppExtensionPasswordKey] as? String ?? "" } }
Conclusion
You should encourage your users to create strong passwords by integrating with the password managers they already have installed. 1Password is an example of one of the popular password managers on iOS. Several others, such as Dashlane have also created extensions for integrating with them. An example project for using the 1Password extension can be found on GitHub.
If mobile development, application security, or social media interest you, IZEA is currently looking for talented software engineers to join our team. Check out our jobs page for more information, and follow @IZEAengineering and @benhanzl on Twitter.