• Stars
    star
    3,072
  • Rank 14,658 (Top 0.3 %)
  • Language
    Objective-C
  • License
    MIT License
  • Created about 13 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

UICKeyChainStore is a simple wrapper for Keychain on iOS, watchOS, tvOS and macOS. Makes using Keychain APIs as easy as NSUserDefaults.

UICKeyChainStore

CI Status Coverage Status Carthage compatible Version License Platform

UICKeyChainStore is a simple wrapper for Keychain that works on iOS and OS X. Makes using Keychain APIs as easy as NSUserDefaults.

Looking for the library written in Swift?

Try KeychainAccess.
KeychainAccess is next generation of UICKeyChainStore.

Transitioning from 1.x to 2.0

synchronize method is deprecated. Calling this method is no longer required (Just ignored).

Features

Usage

Basics

Saving Application Password

UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:@"com.example.github-token"];
keychain[@"kishikawakatsumi"] = @"01234567-89ab-cdef-0123-456789abcdef";

Saving Internet Password

UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithServer:[NSURL URLWithString:@"https://github.com"]
                                                          protocolType:UICKeyChainStoreProtocolTypeHTTPS];
keychain[@"kishikawakatsumi"] = @"01234567-89ab-cdef-0123-456789abcdef";

Instantiation

Create Keychain for Application Password

UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:@"com.example.github-token"];
UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:@"kishikawakatsumi.git"
                                                            accessGroup:@"12ABCD3E4F.shared"];

Create Keychain for Internet Password

UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithServer:[NSURL URLWithString:@"https://github.com"]
                                                          protocolType:UICKeyChainStoreProtocolTypeHTTPS];
UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithServer:[NSURL URLWithString:@"https://github.com"]
                                                          protocolType:UICKeyChainStoreProtocolTypeHTTPS
                                                    authenticationType:UICKeyChainStoreAuthenticationTypeHTMLForm];

Adding an item

subscripting

keychain[@"kishikawakatsumi"] = @"01234567-89ab-cdef-0123-456789abcdef"

set method

[keychain setString:@"01234567-89ab-cdef-0123-456789abcdef" forKey:@"kishikawakatsumi"];

error handling

if (![keychain setString:@"01234567-89ab-cdef-0123-456789abcdef" forKey:@"kishikawakatsumi"]) {
    // error has occurred
}
NSError *error;
[keychain setString:@"01234567-89ab-cdef-0123-456789abcdef" forKey:@"kishikawakatsumi" error:&error];
if (error) {
    NSLog(@"%@", error.localizedDescription);
}

Obtaining an item

subscripting (automatically converts to string)

NSString *token = keychain[@"kishikawakatsumi"]

get methods

as String
NSString *token = [keychain stringForKey:@"kishikawakatsumi"];
as NSData
NSData *data = [keychain dataForKey:@"kishikawakatsumi"];

error handling

First, get the failable (value or error) object

NSError *error;
NSString *token = [keychain stringForKey:@"" error:&error];
if (error) {
    NSLog(@"%@", error.localizedDescription);
}

Removing an item

subscripting

keychain[@"kishikawakatsumi"] = nil

remove method

[keychain removeItemForKey:@"kishikawakatsumi"];

error handling

if (![keychain removeItemForKey:@"kishikawakatsumi"]) {
    // error has occurred
}
NSError *error;
[keychain removeItemForKey:@"kishikawakatsumi" error:&error];
if (error) {
    NSLog(@"%@", error.localizedDescription);
}

Label and Comment

UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithServer:[NSURL URLWithString:@"https://github.com"]
                                                          protocolType:UICKeyChainStoreProtocolTypeHTTPS];
[keychain setString:@"01234567-89ab-cdef-0123-456789abcdef"
             forKey:@"kishikawakatsumi"
              label:@"github.com (kishikawakatsumi)"
            comment:@"github access token"];

Configuration (Accessibility, Sharing, iCould Sync)

Accessibility

Default accessibility matches background application (=kSecAttrAccessibleAfterFirstUnlock)
UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:@"com.example.github-token"];
For background application
Creating instance
UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:@"com.example.github-token"];
keychain.accessibility = UICKeyChainStoreAccessibilityAfterFirstUnlock;

keychain[@"kishikawakatsumi"] = @"01234567-89ab-cdef-0123-456789abcdef"
For foreground application
Creating instance
UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:@"com.example.github-token"];
keychain.accessibility = UICKeyChainStoreAccessibilityWhenUnlocked;

keychain[@"kishikawakatsumi"] = @"01234567-89ab-cdef-0123-456789abcdef"

Sharing Keychain items

UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:@"kishikawakatsumi.git"
                                                            accessGroup:@"12ABCD3E4F.shared"];

Synchronizing Keychain items with iCloud

Creating instance
UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:@"com.example.github-token"];
keychain.synchronizable = YES;

keychain[@"kishikawakatsumi"] = @"01234567-89ab-cdef-0123-456789abcdef"

Touch ID integration

Any Operation that require authentication must be run in the background thread.
If you run in the main thread, UI thread will lock for the system to try to display the authentication dialog.

Adding a Touch ID protected item

If you want to store the Touch ID protected Keychain item, specify accessibility and authenticationPolicy attributes.

UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:@"com.example.github-token"];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
    [keychain setAccessibility:UICKeyChainStoreAccessibilityWhenPasscodeSetThisDeviceOnly
          authenticationPolicy:UICKeyChainStoreAuthenticationPolicyUserPresence];

    keychain[@"kishikawakatsumi"] = @"01234567-89ab-cdef-0123-456789abcdef"
});

Updating a Touch ID protected item

The same way as when adding.

Do not run in the main thread if there is a possibility that the item you are trying to add already exists, and protected. Because updating protected items requires authentication.

Additionally, you want to show custom authentication prompt message when updating, specify an authenticationPrompt attribute. If the item not protected, the authenticationPrompt parameter just be ignored.

UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:@"com.example.github-token"];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
    [keychain setAccessibility:UICKeyChainStoreAccessibilityWhenPasscodeSetThisDeviceOnly
          authenticationPolicy:UICKeyChainStoreAuthenticationPolicyUserPresence];
    keychain.authenticationPrompt = @"Authenticate to update your access token";

    keychain[@"kishikawakatsumi"] = @"01234567-89ab-cdef-0123-456789abcdef"
});

Obtaining a Touch ID protected item

The same way as when you get a normal item. It will be displayed automatically Touch ID or passcode authentication If the item you try to get is protected.
If you want to show custom authentication prompt message, specify an authenticationPrompt attribute. If the item not protected, the authenticationPrompt parameter just be ignored.

UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:@"com.example.github-token"];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
    [keychain setAccessibility:UICKeyChainStoreAccessibilityWhenPasscodeSetThisDeviceOnly
          authenticationPolicy:UICKeyChainStoreAuthenticationPolicyUserPresence];
    keychain.authenticationPrompt = @"Authenticate to update your access token";

    NSString *token = keychain[@"kishikawakatsumi"];
});

Removing a Touch ID protected item

The same way as when you remove a normal item. There is no way to show Touch ID or passcode authentication when removing Keychain items.

UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:@"com.example.github-token"];

keychain[@"kishikawakatsumi"] = nil;

Shared Web Credentials

Shared web credentials is a programming interface that enables native iOS apps to share credentials with their website counterparts. For example, a user may log in to a website in Safari, entering a user name and password, and save those credentials using the iCloud Keychain. Later, the user may run a native app from the same developer, and instead of the app requiring the user to reenter a user name and password, shared web credentials gives it access to the credentials that were entered earlier in Safari. The user can also create new accounts, update passwords, or delete her account from within the app. These changes are then saved and used by Safari.
https://developer.apple.com/library/ios/documentation/Security/Reference/SharedWebCredentialsRef/

UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithServer:[NSURL URLWithString:@"https://kishikawakatsumi.com"]
protocolType:UICKeyChainStoreProtocolTypeHTTPS];
NSString *username = @"[email protected]";
NSString *password = keychain[username];
if (password) {
    // If found password in the Keychain,
    // then log into the server
} else {
    // If not found password in the Keychain,
    // try to read from Shared Web Credentials
    [keychain sharedPasswordForAccount:username completion:^(NSString *password, NSError *error) {
        if (password) {
            // If found password in the Shared Web Credentials,
            // then log into the server
            // and save the password to the Keychain

            keychain[username] = password
        } else {
            // If not found password either in the Keychain also Shared Web Credentials,
            // prompt for username and password

            // Log into server

            // If the login is successful,
            // save the credentials to both the Keychain and the Shared Web Credentials.

            keychain[username] = password
            [keychain setSharedPassword:password forAccount:username completion:nil];
        }
    }];
}

Request all associated domain's credentials

[UICKeyChainStore requestSharedWebCredentialWithCompletion:^(NSArray *credentials, NSError *error) {

}];

Generate strong random password

Generate strong random password that is in the same format used by Safari autofill (xxx-xxx-xxx-xxx).

NSString *password = [UICKeyChainStore generatePassword];
NSLog(@"%@", password); // => Nhu-GKm-s3n-pMx

How to set up Shared Web Credentials

  1. Add a com.apple.developer.associated-domains entitlement to your app. This entitlement must include all the domains with which you want to share credentials.
  1. Add an apple-app-site-association file to your website. This file must include application identifiers for all the apps with which the site wants to share credentials, and it must be properly signed.
  1. When the app is installed, the system downloads and verifies the site association file for each of its associated domains. If the verification is successful, the app is associated with the domain.

More details:
https://developer.apple.com/library/ios/documentation/Security/Reference/SharedWebCredentialsRef/

Debugging

Display all stored items if print keychain object

UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithServer:[NSURL URLWithString:@"https://github.com"]
                                                          protocolType:UICKeyChainStoreProtocolTypeHTTPS];
NSLog(@"%@", keychain);
=>
(
{
    accessibility = ak;
    authenticationType = dflt;
    class = InternetPassword;
    key = kishikawakatsumi;
    protocol = htps;
    server = "github.com";
    synchronizable = 0;
    value = "01234567-89ab-cdef-0123-456789abcdef";
}    {
    accessibility = ck;
    authenticationType = dflt;
    class = InternetPassword;
    key = hirohamada;
    protocol = htps;
    server = "github.com";
    synchronizable = 1;
    value = "11111111-89ab-cdef-1111-456789abcdef";
}    {
    accessibility = ak;
    authenticationType = dflt;
    class = InternetPassword;
    key = honeylemon;
    protocol = htps;
    server = "github.com";
    synchronizable = 0;
    value = "22222222-89ab-cdef-2222-456789abcdef";
})

Obtaining all stored keys

UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithServer:[NSURL URLWithString:@"https://github.com"]
                                                          protocolType:UICKeyChainStoreProtocolTypeHTTPS];

NSArray *keys = keychain.allKeys;
for (NSString *key in keys) {
    NSLog(@"key: %@", key);
}
=>
key: kishikawakatsumi
key: hirohamada
key: honeylemon

Obtaining all stored items

UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithServer:[NSURL URLWithString:@"https://github.com"]
                                                          protocolType:UICKeyChainStoreProtocolTypeHTTPS];

NSArray *items = keychain.allItems;
for (NSString *item in items) {
    NSLog(@"item: %@", item);
}
=>

item: {
    accessibility = ak;
    authenticationType = dflt;
    class = InternetPassword;
    key = kishikawakatsumi;
    protocol = htps;
    server = "github.com";
    synchronizable = 0;
    value = "01234567-89ab-cdef-0123-456789abcdef";
}
item: {
    accessibility = ck;
    authenticationType = dflt;
    class = InternetPassword;
    key = hirohamada;
    protocol = htps;
    server = "github.com";
    synchronizable = 1;
    value = "11111111-89ab-cdef-1111-456789abcdef";
}
item: {
    accessibility = ak;
    authenticationType = dflt;
    class = InternetPassword;
    key = honeylemon;
    protocol = htps;
    server = "github.com";
    synchronizable = 0;
    value = "22222222-89ab-cdef-2222-456789abcdef";
}

Convenient class methods

Add items using default service name (=bundle identifer).

[UICKeyChainStore setString:@"01234567-89ab-cdef-0123-456789abcdef" forKey:@"kishikawakatsumi"];

Or specify the service name.

[UICKeyChainStore setString:@"01234567-89ab-cdef-0123-456789abcdef"
                     forKey:@"kishikawakatsumi"
                    service:@"com.example.github-token"];

Remove items.

[UICKeyChainStore removeItemForKey:@"kishikawakatsumi" service:@"com.example.github-token"];

To set nil value also works remove item for the key.

[UICKeyChainStore setString:nil forKey:@"kishikawakatsumi" service:@"com.example.github-token"];

Requirements

iOS 4.3 or later OS X 10.7 or later

Installation

Swift Package Manager

UICKeyChainStore is now available through Swift Package Manager.

Xcode

Select File > Swift Packages > Add Package Dependency...

Type https://github.com/kishikawakatsumi/UICKeyChainStore then check the target that appears.

CLI

Create Package.swift file and define the dependency like this

// swift-tools-version:5.0
import PackageDescription

let package = Package(
    name: "MyLibrary",
    products: [
        .library(name: "MyLibrary", targets: ["MyLibrary"]),
    ],
    dependencies: [
        .package(url: "https://github.com/kishikawakatsumi/UICKeyChainStore.git", from: "2.1.2"),
    ],
    targets: [
        .target(name: "MyLibrary", dependencies: ["UICKeyChainStore"]),
    ]
)

Then, type

$ swift build

CocoaPods

UICKeyChainStore is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'UICKeyChainStore'

For watchOS 2
use_frameworks!

target 'EampleApp' do
  pod 'UICKeyChainStore'
end

target 'EampleApp WatchKit Extension' do
  platform :watchos, '2.0'
  pod 'UICKeyChainStore'
end

Carthage

UICKeyChainStore is available through Carthage. To install it, simply add the following line to your Cartfile:

github "kishikawakatsumi/UICKeyChainStore"

To manually add to your project

  1. Add Security.framework to your target.
  2. Copy files in Lib (UICKeyChainStore.h and UICKeyChainStore.m) to your project.

Author

kishikawa katsumi, [email protected]

License

UICKeyChainStore is available under the MIT license. See the LICENSE file for more info.

More Repositories

1

KeychainAccess

Simple Swift wrapper for Keychain that works on iOS, watchOS, tvOS and macOS.
Swift
7,532
star
2

IBPCollectionViewCompositionalLayout

Backport of UICollectionViewCompositionalLayout to earlier iOS 12
Swift
1,467
star
3

PEPhotoCropEditor

Image cropping library for iOS.
Objective-C
1,087
star
4

SECoreTextView

SECoreTextView is multi style text view.
Objective-C
947
star
5

SourceKitForSafari

SourceKit for Safari is a Safari extension for GitHub, that enables Xcode features like go to definition, find references, or documentation on hover.
JavaScript
680
star
6

Kuery

A type-safe Core Data query API using Swift 4's Smart KeyPaths
Swift
621
star
7

ClassicMap

Google Map is back to iOS 6.
Objective-C
541
star
8

JavaScriptBridge

Write iOS apps in Javascript! JavaScriptBridge provides the way to write iOS apps with JavaScript. Powered by JavaScriptCore.framework.
Objective-C
523
star
9

UCZProgressView

UCZProgressView is a circular progress indicator for image loading.
Objective-C
481
star
10

swift-power-assert

Power Assert in Swift.
Swift
355
star
11

MapKit-Route-Directions

Extend MapKit to add route directions powered by Google Maps API.
Objective-C
350
star
12

ScreenRecorder

Capturing a screen as videos on iOS devices for user testing.
Objective-C
315
star
13

BookReader

Sample code for PDFKit on iOS 11, clone of iBooks.app built on top of PDFKit.
Swift
306
star
14

xcresulttool

A GitHub Action that generates a human-readable test report from the Xcode result bundle and shows it on GitHub Checks.
TypeScript
297
star
15

TextKitExamples

TextKit examples for try! Swift NYC 2016
Swift
294
star
16

AppStore-Clone-CollectionViewCompositionalLayouts

Sample project for implementing App Store.app UI with Collection View Compositional Layouts
Swift
280
star
17

swiftfmt

Format Swift code
Swift
215
star
18

SwiftPowerAssert

Power Assert in Swift. Provides descriptive assertion messages.
Swift
198
star
19

UltimateGuideToAnimations

Swift
184
star
20

JapaneseKeyboardKit

Sample implementation for iOS Custom Keyboard Extension with Mozc (Google Japanese Input)
Objective-C
148
star
21

RealmTypeSafeQuery

A type-safe Realm query extensions using Swift 4 Smart KeyPaths
Swift
131
star
22

swiftui-playground

SwiftUI Online Playground
JavaScript
119
star
23

xcjobs

Support the automation of release process of iOS/OSX apps with CI
Ruby
117
star
24

applelocalization-web

HTML
106
star
25

AutoLayoutManiacs

Swift
93
star
26

deliverbot

Go
81
star
27

WebTranslator

Safari web extension for DeepL translate.
CSS
79
star
28

FlipCardNavigationView

Objective-C
75
star
29

UUIDShortener

Convert UUID 32-character hex string into a Base32 short string and back.
Objective-C
70
star
30

BandwidthLimiter

Swift
69
star
31

YAMapKit

Yet Another MapKit.framework based on Google Maps Javascript API.
Objective-C
67
star
32

DescriptionBuilder

DescriptionBuilder (iPhone Utility Program) - Assists implementing description method.
Objective-C
67
star
33

Mozc-for-iOS

Mozc - Japanese Input Method for Chromium OS, Android, Windows, Mac and Linux
C
65
star
34

VoiceNavigation

UI Navigation by voice dictation on iOS 5.1
Objective-C
46
star
35

swift-ast-explorer-playground

Online playground for Swift AST Explorer
HTML
45
star
36

AUCapture

Swift
44
star
37

SymbolFontKit

Easy to use 'SymbolFont' as image in iOS 6.
Objective-C
38
star
38

TiledLayerView

CATiledLayer with UIScrollView Sample.
Objective-C
37
star
39

hatena-touch

Hatena touch / iPhone
Objective-C
36
star
40

CollectionUtils

Useful utilities for Objective-C collection classes.
Objective-C
36
star
41

ForceOrientationSample-iOS

Force view to enter landscape in iOS like YouTube app
Swift
36
star
42

ldr-touch

LDR touch / iPhone
Objective-C
35
star
43

swift-magic

A Swift wrapper for libmagic
Swift
33
star
44

SwiftAST

Experimental project for parsing an output that `swift -dump-ast` produces
Swift
28
star
45

CropImageSample

Objective-C
27
star
46

FTSKit

Full Text Search Library for iOS SDK.
C
27
star
47

PhotoFlipCardView

Flip card photo galally sample
Objective-C
26
star
48

VirtualCameraComposer-Example

Objective-C++
25
star
49

tv-listings

TV Listings / iPhone
Objective-C
23
star
50

SwiftSyntax

SwiftSyntax SwiftPM module
Swift
22
star
51

UIKeyInput-UITextInput-Sample

Objective-C
21
star
52

Doorlock

Swift
20
star
53

DownloadFont

Sample code for downloading additional font on iOS 6 or 7.
Objective-C
19
star
54

swift-compiler-discord-bot

JavaScript
19
star
55

WithCamera

Swift
16
star
56

KeyboardShortcuts

Sample program of handling keyboard shortcuts or any keyboard input events.
Objective-C
16
star
57

MacCatalystSlackApp

Swift
15
star
58

TiKeyChainStore

KeyChain module for Titanium Mobile iPhone
Objective-C
14
star
59

Realm-Hands-On

Swift
13
star
60

WWDCChecker-iPhone

WWDC 2012 Checker
Objective-C
13
star
61

applelocalization-data

Clojure
9
star
62

WWDCChecker-Mac

WWDC Site Update Checker With Push Notification Support (Via Parse.com)
Objective-C
9
star
63

iOSDC-2020-UICollectionViewCompositionalLayout

9
star
64

applelocalization-tools

Swift
8
star
65

ExplodeChristmas

Let's explode Christmas.
Objective-C
7
star
66

BuildNumber

Objective-C
7
star
67

bitrise-step-xcode-result-bundle-to-checks

A Bitrise Step that generates a human-readable test report from the Xcode result bundle and shows it on GitHub Checks.
JavaScript
7
star
68

attendancebot

Go
5
star
69

UICollectionViewCompositionalLayout-Workshop-Starter

Swift
5
star
70

LeapMotionSwipeLockScreen

Swipe gesture to lock the screen with Leap Motion.
Objective-C
5
star
71

GoogleAnalytics-for-WinJS

GoogleAnalytics for WinJS
JavaScript
4
star
72

TextViewLinks

Customize clickable links with UITextView.
Objective-C
4
star
73

TextViewCompatibility

Workaround for iOS 7 UITextView scrolling bugs.
Objective-C
4
star
74

webpdecoder

Swift package for libwebpdecoder
C
4
star
75

Realm-CoreData-Performance

Benchmark code for Realm and CoreData
Objective-C
4
star
76

swift-power-assert-playground

SwiftPowerAssert online live demo
HTML
4
star
77

TextChatTranslator

Swift
4
star
78

FittingLabel

Swift
3
star
79

coveralls-gcov

Upload coverage information generated by Gcov to coveralls.io.
Ruby
3
star
80

dotfiles

Shell
3
star
81

swift-online-playground-tutorial

HTML
3
star
82

downloadable-ios-apps

Objective-C
3
star
83

SwiftFiddleEditor

Swift
3
star
84

async-await-in-swift

HTML
2
star
85

xcresulttool-static

HTML
2
star
86

xcresulttool-example

Swift
2
star
87

swiftfmt-playground

Swiftfmt online playground
HTML
2
star
88

codespace-swift

Dockerfile
2
star
89

swift-package-libbsd

Simple wrapper around the C Library BSD for use with Swift Package Manager on Linux
Swift
2
star
90

make-check

Create GitHub Checks.
JavaScript
2
star
91

swift-developers-japan-discussion-archive

Swift Developers JapanのDiscordサーバーに投稿された過去の議論を閲覧・検索できるWebサービスのリポジトリです。
2
star
92

among-us-server-status

Swift
2
star
93

Tree

Swift
2
star
94

WorkaroundPreprocessInfoPlist

Swift
2
star
95

XcodeCloudMac

Swift
1
star
96

prime-number

Swift
1
star
97

XcodeCloud

Swift
1
star
98

NICOLA-Note

1
star
99

StringWidth

Swift
1
star
100

anime-today

Ruby
1
star