├── .gitignore ├── LICENSE ├── Readme.markdown ├── SAMKeychain.podspec ├── SAMKeychain.xcodeproj ├── project.pbxproj └── xcshareddata │ └── xcschemes │ ├── SAMKeychain-iOS.xcscheme │ ├── SAMKeychain-macOS.xcscheme │ ├── SAMKeychain-tvOS.xcscheme │ └── SAMKeychain-watchOS.xcscheme ├── Sources ├── SAMKeychain.h ├── SAMKeychain.m ├── SAMKeychainQuery.h └── SAMKeychainQuery.m ├── Support ├── Info.plist ├── SAMKeychain.bundle │ └── en.lproj │ │ └── SAMKeychain.strings └── Tests-Info.plist └── Tests └── KeychainTests.swift /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.mode1v3 3 | *.pbxuser 4 | *.perspectivev3 5 | *.xcworkspace 6 | xcuserdata 7 | Documentation 8 | DerivedData 9 | build 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010-2016 Sam Soffes, http://soff.es 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Readme.markdown: -------------------------------------------------------------------------------- 1 | # SAMKeychain 2 | 3 | [![Version](https://img.shields.io/github/release/soffes/SAMKeychain.svg)](https://github.com/soffes/SAMKeychain/releases) 4 | [![CocoaPods](https://img.shields.io/cocoapods/v/SAMKeychain.svg)](https://cocoapods.org/pods/SAMKeychain) 5 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 6 | 7 | SAMKeychain is a simple wrapper for accessing accounts, getting passwords, setting passwords, and deleting passwords using the system Keychain on Mac OS X and iOS. 8 | 9 | ## Adding to Your Project 10 | 11 | Simply add the following to your Podfile if you're using CocoaPods: 12 | 13 | ``` ruby 14 | pod 'SAMKeychain' 15 | ``` 16 | 17 | or Cartfile if you're using Carthage: 18 | 19 | ``` 20 | github "soffes/SAMKeychain" 21 | ``` 22 | 23 | To manually add to your project: 24 | 25 | 1. Add `Security.framework` to your target 26 | 2. Add `SAMKeychain.h`, `SAMKeychain.m`, `SAMKeychainQuery.h`, and `SAMKeychainQuery.m` to your project. 27 | 28 | SAMKeychain requires ARC. 29 | 30 | Note: Currently SAMKeychain does not support Mac OS 10.6. 31 | 32 | ## Working with the Keychain 33 | 34 | SAMKeychain has the following class methods for working with the system keychain: 35 | 36 | ```objective-c 37 | + (NSArray *)allAccounts; 38 | + (NSArray *)accountsForService:(NSString *)serviceName; 39 | + (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account; 40 | + (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account; 41 | + (void)setAccessibilityType:(CFTypeRef)accessibilityType; 42 | + (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account; 43 | ``` 44 | 45 | Easy as that. (See [SAMKeychain.h](https://github.com/soffes/samkeychain/blob/master/Sources/SAMKeychain.h) and [SAMKeychainQuery.h](https://github.com/soffes/samkeychain/blob/master/Sources/SAMKeychainQuery.h) for all of the methods.) 46 | 47 | 48 | ## Documentation 49 | 50 | ### Use prepared documentation 51 | 52 | Read the [online documentation](http://cocoadocs.org/docsets/SAMKeychain). 53 | 54 | ## Debugging 55 | 56 | If your saving to the keychain fails, use the NSError object to handle it. You can invoke `[error code]` to get the numeric error code. A few values are defined in SAMKeychain.h, and the rest in SecBase.h. 57 | 58 | ```objective-c 59 | NSError *error = nil; 60 | SAMKeychainQuery *query = [[SAMKeychainQuery alloc] init]; 61 | query.service = @"MyService"; 62 | query.account = @"soffes"; 63 | [query fetch:&error]; 64 | 65 | if ([error code] == errSecItemNotFound) { 66 | NSLog(@"Password not found"); 67 | } else if (error != nil) { 68 | NSLog(@"Some other error occurred: %@", [error localizedDescription]); 69 | } 70 | ``` 71 | 72 | Obviously, you should do something more sophisticated. You can just call `[error localizedDescription]` if all you need is the error message. 73 | 74 | ## Disclaimer 75 | 76 | Working with the keychain is pretty sucky. You should really check for errors and failures. This library doesn't make it any more stable, it just wraps up all of the annoying C APIs. 77 | 78 | You also really should not use the default but set the `accessibilityType`. 79 | `kSecAttrAccessibleWhenUnlocked` should work for most applications. See 80 | [Apple Documentation](https://developer.apple.com/library/ios/DOCUMENTATION/Security/Reference/keychainservices/Reference/reference.html#//apple_ref/doc/constant_group/Keychain_Item_Accessibility_Constants) 81 | for other options. 82 | 83 | ## Thanks 84 | 85 | This was originally inspired by EMKeychain and SDKeychain (both of which are now gone). Thanks to the authors. SAMKeychain has since switched to a simpler implementation that was abstracted from [SSToolkit](https://github.com/soffes/sstoolkit). 86 | 87 | A huge thanks to [Caleb Davenport](https://github.com/calebd) for leading the way on version 1.0 of SAMKeychain. 88 | -------------------------------------------------------------------------------- /SAMKeychain.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'SAMKeychain' 3 | spec.version = '1.5.3' 4 | spec.description = 'Simple Cocoa wrapper for the keychain that works on OS X, iOS, tvOS, and watchOS.' 5 | spec.summary = 'Simple Cocoa wrapper for the keychain.' 6 | spec.homepage = 'https://github.com/soffes/samkeychain' 7 | spec.author = { 'Sam Soffes' => 'sam@soff.es' } 8 | spec.source = { :git => 'https://github.com/soffes/samkeychain.git', :tag => "v#{spec.version}" } 9 | spec.license = { :type => 'MIT', :file => 'LICENSE' } 10 | 11 | spec.source_files = 'Sources/*.{h,m}' 12 | spec.resources = 'Support/SAMKeychain.bundle' 13 | 14 | spec.frameworks = 'Security', 'Foundation' 15 | 16 | spec.osx.deployment_target = '10.8' 17 | spec.ios.deployment_target = '5.0' 18 | spec.tvos.deployment_target = '9.0' 19 | spec.watchos.deployment_target = '2.0' 20 | end 21 | -------------------------------------------------------------------------------- /SAMKeychain.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 02AB79B61CA69B4700E52F3D /* SAMKeychain.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 02AB79B51CA69B4700E52F3D /* SAMKeychain.bundle */; }; 11 | 02AB79B71CA69B4700E52F3D /* SAMKeychain.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 02AB79B51CA69B4700E52F3D /* SAMKeychain.bundle */; }; 12 | 02AB79B81CA69B4700E52F3D /* SAMKeychain.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 02AB79B51CA69B4700E52F3D /* SAMKeychain.bundle */; }; 13 | 02AB79B91CA69B4700E52F3D /* SAMKeychain.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 02AB79B51CA69B4700E52F3D /* SAMKeychain.bundle */; }; 14 | 21632D821C92599100C40D7D /* SAMKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 21632D7C1C92599100C40D7D /* SAMKeychain.h */; settings = {ATTRIBUTES = (Public, ); }; }; 15 | 21632D831C92599100C40D7D /* SAMKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 21632D7D1C92599100C40D7D /* SAMKeychain.m */; }; 16 | 21632D841C92599100C40D7D /* SAMKeychainQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = 21632D7E1C92599100C40D7D /* SAMKeychainQuery.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17 | 21632D851C92599100C40D7D /* SAMKeychainQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = 21632D7F1C92599100C40D7D /* SAMKeychainQuery.m */; }; 18 | 21632D8F1C9259C100C40D7D /* SAMKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 21632D7C1C92599100C40D7D /* SAMKeychain.h */; settings = {ATTRIBUTES = (Public, ); }; }; 19 | 21632D901C9259C100C40D7D /* SAMKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 21632D7D1C92599100C40D7D /* SAMKeychain.m */; }; 20 | 21632D911C9259C100C40D7D /* SAMKeychainQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = 21632D7E1C92599100C40D7D /* SAMKeychainQuery.h */; settings = {ATTRIBUTES = (Public, ); }; }; 21 | 21632D921C9259C100C40D7D /* SAMKeychainQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = 21632D7F1C92599100C40D7D /* SAMKeychainQuery.m */; }; 22 | 21632DA21C925A3C00C40D7D /* SAMKeychain.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21632D981C925A3C00C40D7D /* SAMKeychain.framework */; }; 23 | 21632DB11C925A6000C40D7D /* SAMKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 21632D7C1C92599100C40D7D /* SAMKeychain.h */; settings = {ATTRIBUTES = (Public, ); }; }; 24 | 21632DB21C925A6000C40D7D /* SAMKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 21632D7D1C92599100C40D7D /* SAMKeychain.m */; }; 25 | 21632DB31C925A6000C40D7D /* SAMKeychainQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = 21632D7E1C92599100C40D7D /* SAMKeychainQuery.h */; settings = {ATTRIBUTES = (Public, ); }; }; 26 | 21632DB41C925A6000C40D7D /* SAMKeychainQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = 21632D7F1C92599100C40D7D /* SAMKeychainQuery.m */; }; 27 | 21632DC51C925B3700C40D7D /* SAMKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 21632D7C1C92599100C40D7D /* SAMKeychain.h */; settings = {ATTRIBUTES = (Public, ); }; }; 28 | 21632DC61C925B3700C40D7D /* SAMKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 21632D7D1C92599100C40D7D /* SAMKeychain.m */; }; 29 | 21632DC71C925B3700C40D7D /* SAMKeychainQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = 21632D7E1C92599100C40D7D /* SAMKeychainQuery.h */; settings = {ATTRIBUTES = (Public, ); }; }; 30 | 21632DC81C925B3700C40D7D /* SAMKeychainQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = 21632D7F1C92599100C40D7D /* SAMKeychainQuery.m */; }; 31 | 21632DD31C9282BD00C40D7D /* KeychainTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21632DD21C9282BD00C40D7D /* KeychainTests.swift */; }; 32 | 21632DD41C9282BD00C40D7D /* KeychainTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21632DD21C9282BD00C40D7D /* KeychainTests.swift */; }; 33 | 21632DD51C9282BD00C40D7D /* KeychainTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21632DD21C9282BD00C40D7D /* KeychainTests.swift */; }; 34 | E8A6665B1A844D3A00287CA3 /* SAMKeychain.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E8A666341A844CC400287CA3 /* SAMKeychain.framework */; }; 35 | E8A6667A1A844E4100287CA3 /* SAMKeychain.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E8A6666F1A844E4100287CA3 /* SAMKeychain.framework */; }; 36 | /* End PBXBuildFile section */ 37 | 38 | /* Begin PBXContainerItemProxy section */ 39 | 852915A11D4670A700871559 /* PBXContainerItemProxy */ = { 40 | isa = PBXContainerItemProxy; 41 | containerPortal = 21CC429F17DB874300201DDC /* Project object */; 42 | proxyType = 1; 43 | remoteGlobalIDString = E8A666331A844CC400287CA3; 44 | remoteInfo = "SAMKeychain-iOS"; 45 | }; 46 | 852915A31D4670C500871559 /* PBXContainerItemProxy */ = { 47 | isa = PBXContainerItemProxy; 48 | containerPortal = 21CC429F17DB874300201DDC /* Project object */; 49 | proxyType = 1; 50 | remoteGlobalIDString = E8A6666E1A844E4100287CA3; 51 | remoteInfo = "SAMKeychain-OSX"; 52 | }; 53 | 852915A51D4670E400871559 /* PBXContainerItemProxy */ = { 54 | isa = PBXContainerItemProxy; 55 | containerPortal = 21CC429F17DB874300201DDC /* Project object */; 56 | proxyType = 1; 57 | remoteGlobalIDString = 21632D971C925A3C00C40D7D; 58 | remoteInfo = "SAMKeychain-tvOS"; 59 | }; 60 | /* End PBXContainerItemProxy section */ 61 | 62 | /* Begin PBXFileReference section */ 63 | 02AB79B51CA69B4700E52F3D /* SAMKeychain.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = SAMKeychain.bundle; sourceTree = ""; }; 64 | 21632D7C1C92599100C40D7D /* SAMKeychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAMKeychain.h; sourceTree = ""; }; 65 | 21632D7D1C92599100C40D7D /* SAMKeychain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SAMKeychain.m; sourceTree = ""; }; 66 | 21632D7E1C92599100C40D7D /* SAMKeychainQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAMKeychainQuery.h; sourceTree = ""; }; 67 | 21632D7F1C92599100C40D7D /* SAMKeychainQuery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SAMKeychainQuery.m; sourceTree = ""; }; 68 | 21632D891C9259B400C40D7D /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 69 | 21632D8A1C9259B400C40D7D /* Tests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Tests-Info.plist"; sourceTree = ""; }; 70 | 21632D981C925A3C00C40D7D /* SAMKeychain.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SAMKeychain.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 71 | 21632DA11C925A3C00C40D7D /* SAMKeychainTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SAMKeychainTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 72 | 21632DBC1C925B1F00C40D7D /* SAMKeychain.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SAMKeychain.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 73 | 21632DD21C9282BD00C40D7D /* KeychainTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeychainTests.swift; sourceTree = ""; }; 74 | 21B85B1E18EC9391009D2B98 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; 75 | 21B85B2518EC9455009D2B98 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; }; 76 | 21B85B2818EC9455009D2B98 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 77 | 21B85B2918EC9455009D2B98 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 78 | 21B85B2A18EC9455009D2B98 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 79 | 21B85B6E18EC963A009D2B98 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; }; 80 | 21CC42AA17DB874300201DDC /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 81 | 21CC42AC17DB874300201DDC /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 82 | 21CC42AE17DB874300201DDC /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 83 | 21CC42C317DB874300201DDC /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 84 | 21CC42F917DB87C300201DDC /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 85 | E8A666341A844CC400287CA3 /* SAMKeychain.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SAMKeychain.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 86 | E8A666551A844D3A00287CA3 /* SAMKeychainTests-iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SAMKeychainTests-iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 87 | E8A6666F1A844E4100287CA3 /* SAMKeychain.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SAMKeychain.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 88 | E8A666791A844E4100287CA3 /* SAMKeychainTests-macOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SAMKeychainTests-macOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 89 | /* End PBXFileReference section */ 90 | 91 | /* Begin PBXFrameworksBuildPhase section */ 92 | 21632D941C925A3C00C40D7D /* Frameworks */ = { 93 | isa = PBXFrameworksBuildPhase; 94 | buildActionMask = 2147483647; 95 | files = ( 96 | ); 97 | runOnlyForDeploymentPostprocessing = 0; 98 | }; 99 | 21632D9E1C925A3C00C40D7D /* Frameworks */ = { 100 | isa = PBXFrameworksBuildPhase; 101 | buildActionMask = 2147483647; 102 | files = ( 103 | 21632DA21C925A3C00C40D7D /* SAMKeychain.framework in Frameworks */, 104 | ); 105 | runOnlyForDeploymentPostprocessing = 0; 106 | }; 107 | 21632DB81C925B1F00C40D7D /* Frameworks */ = { 108 | isa = PBXFrameworksBuildPhase; 109 | buildActionMask = 2147483647; 110 | files = ( 111 | ); 112 | runOnlyForDeploymentPostprocessing = 0; 113 | }; 114 | E8A666301A844CC400287CA3 /* Frameworks */ = { 115 | isa = PBXFrameworksBuildPhase; 116 | buildActionMask = 2147483647; 117 | files = ( 118 | ); 119 | runOnlyForDeploymentPostprocessing = 0; 120 | }; 121 | E8A666521A844D3A00287CA3 /* Frameworks */ = { 122 | isa = PBXFrameworksBuildPhase; 123 | buildActionMask = 2147483647; 124 | files = ( 125 | E8A6665B1A844D3A00287CA3 /* SAMKeychain.framework in Frameworks */, 126 | ); 127 | runOnlyForDeploymentPostprocessing = 0; 128 | }; 129 | E8A6666B1A844E4100287CA3 /* Frameworks */ = { 130 | isa = PBXFrameworksBuildPhase; 131 | buildActionMask = 2147483647; 132 | files = ( 133 | ); 134 | runOnlyForDeploymentPostprocessing = 0; 135 | }; 136 | E8A666761A844E4100287CA3 /* Frameworks */ = { 137 | isa = PBXFrameworksBuildPhase; 138 | buildActionMask = 2147483647; 139 | files = ( 140 | E8A6667A1A844E4100287CA3 /* SAMKeychain.framework in Frameworks */, 141 | ); 142 | runOnlyForDeploymentPostprocessing = 0; 143 | }; 144 | /* End PBXFrameworksBuildPhase section */ 145 | 146 | /* Begin PBXGroup section */ 147 | 21632D781C92599100C40D7D /* Sources */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | 21632D7C1C92599100C40D7D /* SAMKeychain.h */, 151 | 21632D7D1C92599100C40D7D /* SAMKeychain.m */, 152 | 21632D7E1C92599100C40D7D /* SAMKeychainQuery.h */, 153 | 21632D7F1C92599100C40D7D /* SAMKeychainQuery.m */, 154 | ); 155 | path = Sources; 156 | sourceTree = ""; 157 | }; 158 | 21632D861C9259B400C40D7D /* Support */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | 02AB79B51CA69B4700E52F3D /* SAMKeychain.bundle */, 162 | 21632D891C9259B400C40D7D /* Info.plist */, 163 | 21632D8A1C9259B400C40D7D /* Tests-Info.plist */, 164 | ); 165 | path = Support; 166 | sourceTree = ""; 167 | }; 168 | 21B85B2718EC9455009D2B98 /* Other Frameworks */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | 21B85B2818EC9455009D2B98 /* AppKit.framework */, 172 | 21B85B2918EC9455009D2B98 /* CoreData.framework */, 173 | 21B85B2A18EC9455009D2B98 /* Foundation.framework */, 174 | ); 175 | name = "Other Frameworks"; 176 | sourceTree = ""; 177 | }; 178 | 21CC429E17DB874300201DDC = { 179 | isa = PBXGroup; 180 | children = ( 181 | 21632D781C92599100C40D7D /* Sources */, 182 | 21CC42D917DB877900201DDC /* Tests */, 183 | 21632D861C9259B400C40D7D /* Support */, 184 | 21CC42A917DB874300201DDC /* Frameworks */, 185 | 21CC42A817DB874300201DDC /* Products */, 186 | ); 187 | sourceTree = ""; 188 | usesTabs = 1; 189 | }; 190 | 21CC42A817DB874300201DDC /* Products */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | E8A666341A844CC400287CA3 /* SAMKeychain.framework */, 194 | E8A666551A844D3A00287CA3 /* SAMKeychainTests-iOS.xctest */, 195 | E8A6666F1A844E4100287CA3 /* SAMKeychain.framework */, 196 | E8A666791A844E4100287CA3 /* SAMKeychainTests-macOS.xctest */, 197 | 21632D981C925A3C00C40D7D /* SAMKeychain.framework */, 198 | 21632DA11C925A3C00C40D7D /* SAMKeychainTests.xctest */, 199 | 21632DBC1C925B1F00C40D7D /* SAMKeychain.framework */, 200 | ); 201 | name = Products; 202 | sourceTree = ""; 203 | }; 204 | 21CC42A917DB874300201DDC /* Frameworks */ = { 205 | isa = PBXGroup; 206 | children = ( 207 | 21B85B6E18EC963A009D2B98 /* Cocoa.framework */, 208 | 21B85B1E18EC9391009D2B98 /* Security.framework */, 209 | 21CC42F917DB87C300201DDC /* Security.framework */, 210 | 21CC42AA17DB874300201DDC /* Foundation.framework */, 211 | 21CC42AC17DB874300201DDC /* CoreGraphics.framework */, 212 | 21CC42AE17DB874300201DDC /* UIKit.framework */, 213 | 21CC42C317DB874300201DDC /* XCTest.framework */, 214 | 21B85B2518EC9455009D2B98 /* Cocoa.framework */, 215 | 21B85B2718EC9455009D2B98 /* Other Frameworks */, 216 | ); 217 | name = Frameworks; 218 | sourceTree = ""; 219 | }; 220 | 21CC42D917DB877900201DDC /* Tests */ = { 221 | isa = PBXGroup; 222 | children = ( 223 | 21632DD21C9282BD00C40D7D /* KeychainTests.swift */, 224 | ); 225 | path = Tests; 226 | sourceTree = ""; 227 | }; 228 | /* End PBXGroup section */ 229 | 230 | /* Begin PBXHeadersBuildPhase section */ 231 | 21632D951C925A3C00C40D7D /* Headers */ = { 232 | isa = PBXHeadersBuildPhase; 233 | buildActionMask = 2147483647; 234 | files = ( 235 | 21632DB11C925A6000C40D7D /* SAMKeychain.h in Headers */, 236 | 21632DB31C925A6000C40D7D /* SAMKeychainQuery.h in Headers */, 237 | ); 238 | runOnlyForDeploymentPostprocessing = 0; 239 | }; 240 | 21632DB91C925B1F00C40D7D /* Headers */ = { 241 | isa = PBXHeadersBuildPhase; 242 | buildActionMask = 2147483647; 243 | files = ( 244 | 21632DC51C925B3700C40D7D /* SAMKeychain.h in Headers */, 245 | 21632DC71C925B3700C40D7D /* SAMKeychainQuery.h in Headers */, 246 | ); 247 | runOnlyForDeploymentPostprocessing = 0; 248 | }; 249 | E8A666311A844CC400287CA3 /* Headers */ = { 250 | isa = PBXHeadersBuildPhase; 251 | buildActionMask = 2147483647; 252 | files = ( 253 | 21632D821C92599100C40D7D /* SAMKeychain.h in Headers */, 254 | 21632D841C92599100C40D7D /* SAMKeychainQuery.h in Headers */, 255 | ); 256 | runOnlyForDeploymentPostprocessing = 0; 257 | }; 258 | E8A6666C1A844E4100287CA3 /* Headers */ = { 259 | isa = PBXHeadersBuildPhase; 260 | buildActionMask = 2147483647; 261 | files = ( 262 | 21632D8F1C9259C100C40D7D /* SAMKeychain.h in Headers */, 263 | 21632D911C9259C100C40D7D /* SAMKeychainQuery.h in Headers */, 264 | ); 265 | runOnlyForDeploymentPostprocessing = 0; 266 | }; 267 | /* End PBXHeadersBuildPhase section */ 268 | 269 | /* Begin PBXNativeTarget section */ 270 | 21632D971C925A3C00C40D7D /* SAMKeychain-tvOS */ = { 271 | isa = PBXNativeTarget; 272 | buildConfigurationList = 21632DA91C925A3C00C40D7D /* Build configuration list for PBXNativeTarget "SAMKeychain-tvOS" */; 273 | buildPhases = ( 274 | 21632D931C925A3C00C40D7D /* Sources */, 275 | 21632D941C925A3C00C40D7D /* Frameworks */, 276 | 21632D951C925A3C00C40D7D /* Headers */, 277 | 21632D961C925A3C00C40D7D /* Resources */, 278 | ); 279 | buildRules = ( 280 | ); 281 | dependencies = ( 282 | ); 283 | name = "SAMKeychain-tvOS"; 284 | productName = SSKeychain; 285 | productReference = 21632D981C925A3C00C40D7D /* SAMKeychain.framework */; 286 | productType = "com.apple.product-type.framework"; 287 | }; 288 | 21632DA01C925A3C00C40D7D /* SAMKeychainTests-tvOS */ = { 289 | isa = PBXNativeTarget; 290 | buildConfigurationList = 21632DAD1C925A3C00C40D7D /* Build configuration list for PBXNativeTarget "SAMKeychainTests-tvOS" */; 291 | buildPhases = ( 292 | 21632D9D1C925A3C00C40D7D /* Sources */, 293 | 21632D9E1C925A3C00C40D7D /* Frameworks */, 294 | 21632D9F1C925A3C00C40D7D /* Resources */, 295 | ); 296 | buildRules = ( 297 | ); 298 | dependencies = ( 299 | 852915A61D4670E400871559 /* PBXTargetDependency */, 300 | ); 301 | name = "SAMKeychainTests-tvOS"; 302 | productName = SSKeychainTests; 303 | productReference = 21632DA11C925A3C00C40D7D /* SAMKeychainTests.xctest */; 304 | productType = "com.apple.product-type.bundle.unit-test"; 305 | }; 306 | 21632DBB1C925B1F00C40D7D /* SAMKeychain-watchOS */ = { 307 | isa = PBXNativeTarget; 308 | buildConfigurationList = 21632DC11C925B1F00C40D7D /* Build configuration list for PBXNativeTarget "SAMKeychain-watchOS" */; 309 | buildPhases = ( 310 | 21632DB71C925B1F00C40D7D /* Sources */, 311 | 21632DB81C925B1F00C40D7D /* Frameworks */, 312 | 21632DB91C925B1F00C40D7D /* Headers */, 313 | 21632DBA1C925B1F00C40D7D /* Resources */, 314 | ); 315 | buildRules = ( 316 | ); 317 | dependencies = ( 318 | ); 319 | name = "SAMKeychain-watchOS"; 320 | productName = SSKeychain; 321 | productReference = 21632DBC1C925B1F00C40D7D /* SAMKeychain.framework */; 322 | productType = "com.apple.product-type.framework"; 323 | }; 324 | E8A666331A844CC400287CA3 /* SAMKeychain-iOS */ = { 325 | isa = PBXNativeTarget; 326 | buildConfigurationList = E8A666471A844CC400287CA3 /* Build configuration list for PBXNativeTarget "SAMKeychain-iOS" */; 327 | buildPhases = ( 328 | E8A6662F1A844CC400287CA3 /* Sources */, 329 | E8A666301A844CC400287CA3 /* Frameworks */, 330 | E8A666311A844CC400287CA3 /* Headers */, 331 | E8A666321A844CC400287CA3 /* Resources */, 332 | ); 333 | buildRules = ( 334 | ); 335 | dependencies = ( 336 | ); 337 | name = "SAMKeychain-iOS"; 338 | productName = "SSKeychain iOS"; 339 | productReference = E8A666341A844CC400287CA3 /* SAMKeychain.framework */; 340 | productType = "com.apple.product-type.framework"; 341 | }; 342 | E8A666541A844D3A00287CA3 /* SAMKeychainTests-iOS */ = { 343 | isa = PBXNativeTarget; 344 | buildConfigurationList = E8A6665E1A844D3A00287CA3 /* Build configuration list for PBXNativeTarget "SAMKeychainTests-iOS" */; 345 | buildPhases = ( 346 | E8A666511A844D3A00287CA3 /* Sources */, 347 | E8A666521A844D3A00287CA3 /* Frameworks */, 348 | ); 349 | buildRules = ( 350 | ); 351 | dependencies = ( 352 | 852915A21D4670A700871559 /* PBXTargetDependency */, 353 | ); 354 | name = "SAMKeychainTests-iOS"; 355 | productName = "SSKeychain iOS Tests"; 356 | productReference = E8A666551A844D3A00287CA3 /* SAMKeychainTests-iOS.xctest */; 357 | productType = "com.apple.product-type.bundle.unit-test"; 358 | }; 359 | E8A6666E1A844E4100287CA3 /* SAMKeychain-macOS */ = { 360 | isa = PBXNativeTarget; 361 | buildConfigurationList = E8A666821A844E4100287CA3 /* Build configuration list for PBXNativeTarget "SAMKeychain-macOS" */; 362 | buildPhases = ( 363 | E8A6666A1A844E4100287CA3 /* Sources */, 364 | E8A6666B1A844E4100287CA3 /* Frameworks */, 365 | E8A6666C1A844E4100287CA3 /* Headers */, 366 | E8A6666D1A844E4100287CA3 /* Resources */, 367 | ); 368 | buildRules = ( 369 | ); 370 | dependencies = ( 371 | ); 372 | name = "SAMKeychain-macOS"; 373 | productName = "SSKeychain Mac"; 374 | productReference = E8A6666F1A844E4100287CA3 /* SAMKeychain.framework */; 375 | productType = "com.apple.product-type.framework"; 376 | }; 377 | E8A666781A844E4100287CA3 /* SAMKeychainTests-macOS */ = { 378 | isa = PBXNativeTarget; 379 | buildConfigurationList = E8A666861A844E4100287CA3 /* Build configuration list for PBXNativeTarget "SAMKeychainTests-macOS" */; 380 | buildPhases = ( 381 | E8A666751A844E4100287CA3 /* Sources */, 382 | E8A666761A844E4100287CA3 /* Frameworks */, 383 | E8A666771A844E4100287CA3 /* Resources */, 384 | ); 385 | buildRules = ( 386 | ); 387 | dependencies = ( 388 | 852915A41D4670C500871559 /* PBXTargetDependency */, 389 | ); 390 | name = "SAMKeychainTests-macOS"; 391 | productName = "SSKeychain MacTests"; 392 | productReference = E8A666791A844E4100287CA3 /* SAMKeychainTests-macOS.xctest */; 393 | productType = "com.apple.product-type.bundle.unit-test"; 394 | }; 395 | /* End PBXNativeTarget section */ 396 | 397 | /* Begin PBXProject section */ 398 | 21CC429F17DB874300201DDC /* Project object */ = { 399 | isa = PBXProject; 400 | attributes = { 401 | CLASSPREFIX = SAM; 402 | LastSwiftUpdateCheck = 0730; 403 | LastUpgradeCheck = 1010; 404 | ORGANIZATIONNAME = "Sam Soffes"; 405 | TargetAttributes = { 406 | 21632D971C925A3C00C40D7D = { 407 | CreatedOnToolsVersion = 7.3; 408 | }; 409 | 21632DA01C925A3C00C40D7D = { 410 | CreatedOnToolsVersion = 7.3; 411 | }; 412 | 21632DBB1C925B1F00C40D7D = { 413 | CreatedOnToolsVersion = 7.3; 414 | }; 415 | E8A666331A844CC400287CA3 = { 416 | CreatedOnToolsVersion = 6.1.1; 417 | }; 418 | E8A666541A844D3A00287CA3 = { 419 | CreatedOnToolsVersion = 6.1.1; 420 | }; 421 | E8A6666E1A844E4100287CA3 = { 422 | CreatedOnToolsVersion = 6.1.1; 423 | }; 424 | E8A666781A844E4100287CA3 = { 425 | CreatedOnToolsVersion = 6.1.1; 426 | }; 427 | }; 428 | }; 429 | buildConfigurationList = 21CC42A217DB874300201DDC /* Build configuration list for PBXProject "SAMKeychain" */; 430 | compatibilityVersion = "Xcode 3.2"; 431 | developmentRegion = English; 432 | hasScannedForEncodings = 0; 433 | knownRegions = ( 434 | en, 435 | Base, 436 | ); 437 | mainGroup = 21CC429E17DB874300201DDC; 438 | productRefGroup = 21CC42A817DB874300201DDC /* Products */; 439 | projectDirPath = ""; 440 | projectRoot = ""; 441 | targets = ( 442 | E8A666331A844CC400287CA3 /* SAMKeychain-iOS */, 443 | E8A666541A844D3A00287CA3 /* SAMKeychainTests-iOS */, 444 | E8A6666E1A844E4100287CA3 /* SAMKeychain-macOS */, 445 | E8A666781A844E4100287CA3 /* SAMKeychainTests-macOS */, 446 | 21632D971C925A3C00C40D7D /* SAMKeychain-tvOS */, 447 | 21632DA01C925A3C00C40D7D /* SAMKeychainTests-tvOS */, 448 | 21632DBB1C925B1F00C40D7D /* SAMKeychain-watchOS */, 449 | ); 450 | }; 451 | /* End PBXProject section */ 452 | 453 | /* Begin PBXResourcesBuildPhase section */ 454 | 21632D961C925A3C00C40D7D /* Resources */ = { 455 | isa = PBXResourcesBuildPhase; 456 | buildActionMask = 2147483647; 457 | files = ( 458 | 02AB79B81CA69B4700E52F3D /* SAMKeychain.bundle in Resources */, 459 | ); 460 | runOnlyForDeploymentPostprocessing = 0; 461 | }; 462 | 21632D9F1C925A3C00C40D7D /* Resources */ = { 463 | isa = PBXResourcesBuildPhase; 464 | buildActionMask = 2147483647; 465 | files = ( 466 | ); 467 | runOnlyForDeploymentPostprocessing = 0; 468 | }; 469 | 21632DBA1C925B1F00C40D7D /* Resources */ = { 470 | isa = PBXResourcesBuildPhase; 471 | buildActionMask = 2147483647; 472 | files = ( 473 | 02AB79B91CA69B4700E52F3D /* SAMKeychain.bundle in Resources */, 474 | ); 475 | runOnlyForDeploymentPostprocessing = 0; 476 | }; 477 | E8A666321A844CC400287CA3 /* Resources */ = { 478 | isa = PBXResourcesBuildPhase; 479 | buildActionMask = 2147483647; 480 | files = ( 481 | 02AB79B61CA69B4700E52F3D /* SAMKeychain.bundle in Resources */, 482 | ); 483 | runOnlyForDeploymentPostprocessing = 0; 484 | }; 485 | E8A6666D1A844E4100287CA3 /* Resources */ = { 486 | isa = PBXResourcesBuildPhase; 487 | buildActionMask = 2147483647; 488 | files = ( 489 | 02AB79B71CA69B4700E52F3D /* SAMKeychain.bundle in Resources */, 490 | ); 491 | runOnlyForDeploymentPostprocessing = 0; 492 | }; 493 | E8A666771A844E4100287CA3 /* Resources */ = { 494 | isa = PBXResourcesBuildPhase; 495 | buildActionMask = 2147483647; 496 | files = ( 497 | ); 498 | runOnlyForDeploymentPostprocessing = 0; 499 | }; 500 | /* End PBXResourcesBuildPhase section */ 501 | 502 | /* Begin PBXSourcesBuildPhase section */ 503 | 21632D931C925A3C00C40D7D /* Sources */ = { 504 | isa = PBXSourcesBuildPhase; 505 | buildActionMask = 2147483647; 506 | files = ( 507 | 21632DB41C925A6000C40D7D /* SAMKeychainQuery.m in Sources */, 508 | 21632DB21C925A6000C40D7D /* SAMKeychain.m in Sources */, 509 | ); 510 | runOnlyForDeploymentPostprocessing = 0; 511 | }; 512 | 21632D9D1C925A3C00C40D7D /* Sources */ = { 513 | isa = PBXSourcesBuildPhase; 514 | buildActionMask = 2147483647; 515 | files = ( 516 | 21632DD51C9282BD00C40D7D /* KeychainTests.swift in Sources */, 517 | ); 518 | runOnlyForDeploymentPostprocessing = 0; 519 | }; 520 | 21632DB71C925B1F00C40D7D /* Sources */ = { 521 | isa = PBXSourcesBuildPhase; 522 | buildActionMask = 2147483647; 523 | files = ( 524 | 21632DC81C925B3700C40D7D /* SAMKeychainQuery.m in Sources */, 525 | 21632DC61C925B3700C40D7D /* SAMKeychain.m in Sources */, 526 | ); 527 | runOnlyForDeploymentPostprocessing = 0; 528 | }; 529 | E8A6662F1A844CC400287CA3 /* Sources */ = { 530 | isa = PBXSourcesBuildPhase; 531 | buildActionMask = 2147483647; 532 | files = ( 533 | 21632D851C92599100C40D7D /* SAMKeychainQuery.m in Sources */, 534 | 21632D831C92599100C40D7D /* SAMKeychain.m in Sources */, 535 | ); 536 | runOnlyForDeploymentPostprocessing = 0; 537 | }; 538 | E8A666511A844D3A00287CA3 /* Sources */ = { 539 | isa = PBXSourcesBuildPhase; 540 | buildActionMask = 2147483647; 541 | files = ( 542 | 21632DD31C9282BD00C40D7D /* KeychainTests.swift in Sources */, 543 | ); 544 | runOnlyForDeploymentPostprocessing = 0; 545 | }; 546 | E8A6666A1A844E4100287CA3 /* Sources */ = { 547 | isa = PBXSourcesBuildPhase; 548 | buildActionMask = 2147483647; 549 | files = ( 550 | 21632D921C9259C100C40D7D /* SAMKeychainQuery.m in Sources */, 551 | 21632D901C9259C100C40D7D /* SAMKeychain.m in Sources */, 552 | ); 553 | runOnlyForDeploymentPostprocessing = 0; 554 | }; 555 | E8A666751A844E4100287CA3 /* Sources */ = { 556 | isa = PBXSourcesBuildPhase; 557 | buildActionMask = 2147483647; 558 | files = ( 559 | 21632DD41C9282BD00C40D7D /* KeychainTests.swift in Sources */, 560 | ); 561 | runOnlyForDeploymentPostprocessing = 0; 562 | }; 563 | /* End PBXSourcesBuildPhase section */ 564 | 565 | /* Begin PBXTargetDependency section */ 566 | 852915A21D4670A700871559 /* PBXTargetDependency */ = { 567 | isa = PBXTargetDependency; 568 | target = E8A666331A844CC400287CA3 /* SAMKeychain-iOS */; 569 | targetProxy = 852915A11D4670A700871559 /* PBXContainerItemProxy */; 570 | }; 571 | 852915A41D4670C500871559 /* PBXTargetDependency */ = { 572 | isa = PBXTargetDependency; 573 | target = E8A6666E1A844E4100287CA3 /* SAMKeychain-macOS */; 574 | targetProxy = 852915A31D4670C500871559 /* PBXContainerItemProxy */; 575 | }; 576 | 852915A61D4670E400871559 /* PBXTargetDependency */ = { 577 | isa = PBXTargetDependency; 578 | target = 21632D971C925A3C00C40D7D /* SAMKeychain-tvOS */; 579 | targetProxy = 852915A51D4670E400871559 /* PBXContainerItemProxy */; 580 | }; 581 | /* End PBXTargetDependency section */ 582 | 583 | /* Begin XCBuildConfiguration section */ 584 | 215D7DE518ECA54500E7B508 /* Test */ = { 585 | isa = XCBuildConfiguration; 586 | buildSettings = { 587 | ALWAYS_SEARCH_USER_PATHS = NO; 588 | APPLICATION_EXTENSION_API_ONLY = YES; 589 | CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; 590 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 591 | CLANG_CXX_LIBRARY = "libc++"; 592 | CLANG_ENABLE_MODULES = YES; 593 | CLANG_ENABLE_OBJC_ARC = YES; 594 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 595 | CLANG_WARN_BOOL_CONVERSION = YES; 596 | CLANG_WARN_COMMA = YES; 597 | CLANG_WARN_CONSTANT_CONVERSION = YES; 598 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 599 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 600 | CLANG_WARN_EMPTY_BODY = YES; 601 | CLANG_WARN_ENUM_CONVERSION = YES; 602 | CLANG_WARN_INFINITE_RECURSION = YES; 603 | CLANG_WARN_INT_CONVERSION = YES; 604 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 605 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 606 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 607 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 608 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 609 | CLANG_WARN_STRICT_PROTOTYPES = YES; 610 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 611 | CLANG_WARN_UNREACHABLE_CODE = YES; 612 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 613 | COPY_PHASE_STRIP = NO; 614 | ENABLE_STRICT_OBJC_MSGSEND = YES; 615 | GCC_C_LANGUAGE_STANDARD = gnu99; 616 | GCC_DYNAMIC_NO_PIC = NO; 617 | GCC_NO_COMMON_BLOCKS = YES; 618 | GCC_OPTIMIZATION_LEVEL = 0; 619 | GCC_PREPROCESSOR_DEFINITIONS = ( 620 | "DEBUG=1", 621 | "$(inherited)", 622 | ); 623 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 624 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 625 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 626 | GCC_WARN_UNDECLARED_SELECTOR = YES; 627 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 628 | GCC_WARN_UNUSED_FUNCTION = YES; 629 | GCC_WARN_UNUSED_VARIABLE = YES; 630 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 631 | MACOSX_DEPLOYMENT_TARGET = 10.8; 632 | ONLY_ACTIVE_ARCH = YES; 633 | SDKROOT = iphoneos; 634 | TARGETED_DEVICE_FAMILY = "1,2"; 635 | TVOS_DEPLOYMENT_TARGET = 9.0; 636 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 637 | }; 638 | name = Test; 639 | }; 640 | 21632DAA1C925A3C00C40D7D /* Debug */ = { 641 | isa = XCBuildConfiguration; 642 | buildSettings = { 643 | CLANG_ANALYZER_NONNULL = YES; 644 | CLANG_WARN_UNREACHABLE_CODE = YES; 645 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 646 | CURRENT_PROJECT_VERSION = 1; 647 | DEBUG_INFORMATION_FORMAT = dwarf; 648 | DEFINES_MODULE = YES; 649 | DYLIB_COMPATIBILITY_VERSION = 1; 650 | DYLIB_CURRENT_VERSION = 1; 651 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 652 | ENABLE_STRICT_OBJC_MSGSEND = YES; 653 | GCC_NO_COMMON_BLOCKS = YES; 654 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 655 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 656 | INFOPLIST_FILE = Support/Info.plist; 657 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 658 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 659 | MTL_ENABLE_DEBUG_INFO = YES; 660 | PRODUCT_BUNDLE_IDENTIFIER = com.samsoffes.SAMKeychain; 661 | PRODUCT_NAME = SAMKeychain; 662 | SDKROOT = appletvos; 663 | SKIP_INSTALL = YES; 664 | TARGETED_DEVICE_FAMILY = 3; 665 | VERSIONING_SYSTEM = "apple-generic"; 666 | VERSION_INFO_PREFIX = ""; 667 | }; 668 | name = Debug; 669 | }; 670 | 21632DAB1C925A3C00C40D7D /* Test */ = { 671 | isa = XCBuildConfiguration; 672 | buildSettings = { 673 | CLANG_ANALYZER_NONNULL = YES; 674 | CLANG_WARN_UNREACHABLE_CODE = YES; 675 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 676 | COPY_PHASE_STRIP = NO; 677 | CURRENT_PROJECT_VERSION = 1; 678 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 679 | DEFINES_MODULE = YES; 680 | DYLIB_COMPATIBILITY_VERSION = 1; 681 | DYLIB_CURRENT_VERSION = 1; 682 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 683 | ENABLE_STRICT_OBJC_MSGSEND = YES; 684 | GCC_NO_COMMON_BLOCKS = YES; 685 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 686 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 687 | INFOPLIST_FILE = Support/Info.plist; 688 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 689 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 690 | MTL_ENABLE_DEBUG_INFO = NO; 691 | PRODUCT_BUNDLE_IDENTIFIER = com.samsoffes.SAMKeychain; 692 | PRODUCT_NAME = SAMKeychain; 693 | SDKROOT = appletvos; 694 | SKIP_INSTALL = YES; 695 | TARGETED_DEVICE_FAMILY = 3; 696 | VERSIONING_SYSTEM = "apple-generic"; 697 | VERSION_INFO_PREFIX = ""; 698 | }; 699 | name = Test; 700 | }; 701 | 21632DAC1C925A3C00C40D7D /* Release */ = { 702 | isa = XCBuildConfiguration; 703 | buildSettings = { 704 | CLANG_ANALYZER_NONNULL = YES; 705 | CLANG_WARN_UNREACHABLE_CODE = YES; 706 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 707 | COPY_PHASE_STRIP = NO; 708 | CURRENT_PROJECT_VERSION = 1; 709 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 710 | DEFINES_MODULE = YES; 711 | DYLIB_COMPATIBILITY_VERSION = 1; 712 | DYLIB_CURRENT_VERSION = 1; 713 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 714 | ENABLE_STRICT_OBJC_MSGSEND = YES; 715 | GCC_NO_COMMON_BLOCKS = YES; 716 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 717 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 718 | INFOPLIST_FILE = Support/Info.plist; 719 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 720 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 721 | MTL_ENABLE_DEBUG_INFO = NO; 722 | PRODUCT_BUNDLE_IDENTIFIER = com.samsoffes.SAMKeychain; 723 | PRODUCT_NAME = SAMKeychain; 724 | SDKROOT = appletvos; 725 | SKIP_INSTALL = YES; 726 | TARGETED_DEVICE_FAMILY = 3; 727 | VERSIONING_SYSTEM = "apple-generic"; 728 | VERSION_INFO_PREFIX = ""; 729 | }; 730 | name = Release; 731 | }; 732 | 21632DAE1C925A3C00C40D7D /* Debug */ = { 733 | isa = XCBuildConfiguration; 734 | buildSettings = { 735 | APPLICATION_EXTENSION_API_ONLY = NO; 736 | CLANG_ANALYZER_NONNULL = YES; 737 | CLANG_ENABLE_MODULES = YES; 738 | CLANG_WARN_UNREACHABLE_CODE = YES; 739 | DEBUG_INFORMATION_FORMAT = dwarf; 740 | ENABLE_STRICT_OBJC_MSGSEND = YES; 741 | GCC_NO_COMMON_BLOCKS = YES; 742 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 743 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 744 | INFOPLIST_FILE = "Support/Tests-Info.plist"; 745 | MTL_ENABLE_DEBUG_INFO = YES; 746 | PRODUCT_BUNDLE_IDENTIFIER = com.samsoffes.SAMKeychainTests; 747 | PRODUCT_NAME = SAMKeychainTests; 748 | SDKROOT = appletvos; 749 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 750 | SWIFT_VERSION = 3.0; 751 | TVOS_DEPLOYMENT_TARGET = 9.2; 752 | }; 753 | name = Debug; 754 | }; 755 | 21632DAF1C925A3C00C40D7D /* Test */ = { 756 | isa = XCBuildConfiguration; 757 | buildSettings = { 758 | APPLICATION_EXTENSION_API_ONLY = NO; 759 | CLANG_ANALYZER_NONNULL = YES; 760 | CLANG_ENABLE_MODULES = YES; 761 | CLANG_WARN_UNREACHABLE_CODE = YES; 762 | COPY_PHASE_STRIP = NO; 763 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 764 | ENABLE_STRICT_OBJC_MSGSEND = YES; 765 | GCC_NO_COMMON_BLOCKS = YES; 766 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 767 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 768 | INFOPLIST_FILE = "Support/Tests-Info.plist"; 769 | MTL_ENABLE_DEBUG_INFO = NO; 770 | PRODUCT_BUNDLE_IDENTIFIER = com.samsoffes.SAMKeychainTests; 771 | PRODUCT_NAME = SAMKeychainTests; 772 | SDKROOT = appletvos; 773 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 774 | SWIFT_VERSION = 3.0; 775 | TVOS_DEPLOYMENT_TARGET = 9.2; 776 | }; 777 | name = Test; 778 | }; 779 | 21632DB01C925A3C00C40D7D /* Release */ = { 780 | isa = XCBuildConfiguration; 781 | buildSettings = { 782 | APPLICATION_EXTENSION_API_ONLY = NO; 783 | CLANG_ANALYZER_NONNULL = YES; 784 | CLANG_ENABLE_MODULES = YES; 785 | CLANG_WARN_UNREACHABLE_CODE = YES; 786 | COPY_PHASE_STRIP = NO; 787 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 788 | ENABLE_STRICT_OBJC_MSGSEND = YES; 789 | GCC_NO_COMMON_BLOCKS = YES; 790 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 791 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 792 | INFOPLIST_FILE = "Support/Tests-Info.plist"; 793 | MTL_ENABLE_DEBUG_INFO = NO; 794 | PRODUCT_BUNDLE_IDENTIFIER = com.samsoffes.SAMKeychainTests; 795 | PRODUCT_NAME = SAMKeychainTests; 796 | SDKROOT = appletvos; 797 | SWIFT_VERSION = 3.0; 798 | TVOS_DEPLOYMENT_TARGET = 9.2; 799 | }; 800 | name = Release; 801 | }; 802 | 21632DC21C925B1F00C40D7D /* Debug */ = { 803 | isa = XCBuildConfiguration; 804 | buildSettings = { 805 | CLANG_ANALYZER_NONNULL = YES; 806 | CLANG_WARN_UNREACHABLE_CODE = YES; 807 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 808 | CURRENT_PROJECT_VERSION = 1; 809 | DEBUG_INFORMATION_FORMAT = dwarf; 810 | DEFINES_MODULE = YES; 811 | DYLIB_COMPATIBILITY_VERSION = 1; 812 | DYLIB_CURRENT_VERSION = 1; 813 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 814 | ENABLE_STRICT_OBJC_MSGSEND = YES; 815 | GCC_NO_COMMON_BLOCKS = YES; 816 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 817 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 818 | INFOPLIST_FILE = Support/Info.plist; 819 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 820 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 821 | MTL_ENABLE_DEBUG_INFO = YES; 822 | PRODUCT_BUNDLE_IDENTIFIER = com.samsoffes.SAMKeychain; 823 | PRODUCT_NAME = SAMKeychain; 824 | SDKROOT = watchos; 825 | SKIP_INSTALL = YES; 826 | TARGETED_DEVICE_FAMILY = 4; 827 | VERSIONING_SYSTEM = "apple-generic"; 828 | VERSION_INFO_PREFIX = ""; 829 | }; 830 | name = Debug; 831 | }; 832 | 21632DC31C925B1F00C40D7D /* Test */ = { 833 | isa = XCBuildConfiguration; 834 | buildSettings = { 835 | CLANG_ANALYZER_NONNULL = YES; 836 | CLANG_WARN_UNREACHABLE_CODE = YES; 837 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 838 | COPY_PHASE_STRIP = NO; 839 | CURRENT_PROJECT_VERSION = 1; 840 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 841 | DEFINES_MODULE = YES; 842 | DYLIB_COMPATIBILITY_VERSION = 1; 843 | DYLIB_CURRENT_VERSION = 1; 844 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 845 | ENABLE_STRICT_OBJC_MSGSEND = YES; 846 | GCC_NO_COMMON_BLOCKS = YES; 847 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 848 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 849 | INFOPLIST_FILE = Support/Info.plist; 850 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 851 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 852 | MTL_ENABLE_DEBUG_INFO = NO; 853 | PRODUCT_BUNDLE_IDENTIFIER = com.samsoffes.SAMKeychain; 854 | PRODUCT_NAME = SAMKeychain; 855 | SDKROOT = watchos; 856 | SKIP_INSTALL = YES; 857 | TARGETED_DEVICE_FAMILY = 4; 858 | VERSIONING_SYSTEM = "apple-generic"; 859 | VERSION_INFO_PREFIX = ""; 860 | }; 861 | name = Test; 862 | }; 863 | 21632DC41C925B1F00C40D7D /* Release */ = { 864 | isa = XCBuildConfiguration; 865 | buildSettings = { 866 | CLANG_ANALYZER_NONNULL = YES; 867 | CLANG_WARN_UNREACHABLE_CODE = YES; 868 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 869 | COPY_PHASE_STRIP = NO; 870 | CURRENT_PROJECT_VERSION = 1; 871 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 872 | DEFINES_MODULE = YES; 873 | DYLIB_COMPATIBILITY_VERSION = 1; 874 | DYLIB_CURRENT_VERSION = 1; 875 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 876 | ENABLE_STRICT_OBJC_MSGSEND = YES; 877 | GCC_NO_COMMON_BLOCKS = YES; 878 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 879 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 880 | INFOPLIST_FILE = Support/Info.plist; 881 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 882 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 883 | MTL_ENABLE_DEBUG_INFO = NO; 884 | PRODUCT_BUNDLE_IDENTIFIER = com.samsoffes.SAMKeychain; 885 | PRODUCT_NAME = SAMKeychain; 886 | SDKROOT = watchos; 887 | SKIP_INSTALL = YES; 888 | TARGETED_DEVICE_FAMILY = 4; 889 | VERSIONING_SYSTEM = "apple-generic"; 890 | VERSION_INFO_PREFIX = ""; 891 | }; 892 | name = Release; 893 | }; 894 | 21CC42D117DB874300201DDC /* Debug */ = { 895 | isa = XCBuildConfiguration; 896 | buildSettings = { 897 | ALWAYS_SEARCH_USER_PATHS = NO; 898 | APPLICATION_EXTENSION_API_ONLY = YES; 899 | CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; 900 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 901 | CLANG_CXX_LIBRARY = "libc++"; 902 | CLANG_ENABLE_MODULES = YES; 903 | CLANG_ENABLE_OBJC_ARC = YES; 904 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 905 | CLANG_WARN_BOOL_CONVERSION = YES; 906 | CLANG_WARN_COMMA = YES; 907 | CLANG_WARN_CONSTANT_CONVERSION = YES; 908 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 909 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 910 | CLANG_WARN_EMPTY_BODY = YES; 911 | CLANG_WARN_ENUM_CONVERSION = YES; 912 | CLANG_WARN_INFINITE_RECURSION = YES; 913 | CLANG_WARN_INT_CONVERSION = YES; 914 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 915 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 916 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 917 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 918 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 919 | CLANG_WARN_STRICT_PROTOTYPES = YES; 920 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 921 | CLANG_WARN_UNREACHABLE_CODE = YES; 922 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 923 | COPY_PHASE_STRIP = NO; 924 | ENABLE_STRICT_OBJC_MSGSEND = YES; 925 | ENABLE_TESTABILITY = YES; 926 | GCC_C_LANGUAGE_STANDARD = gnu99; 927 | GCC_DYNAMIC_NO_PIC = NO; 928 | GCC_NO_COMMON_BLOCKS = YES; 929 | GCC_OPTIMIZATION_LEVEL = 0; 930 | GCC_PREPROCESSOR_DEFINITIONS = ( 931 | "DEBUG=1", 932 | "$(inherited)", 933 | ); 934 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 935 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 936 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 937 | GCC_WARN_UNDECLARED_SELECTOR = YES; 938 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 939 | GCC_WARN_UNUSED_FUNCTION = YES; 940 | GCC_WARN_UNUSED_VARIABLE = YES; 941 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 942 | MACOSX_DEPLOYMENT_TARGET = 10.8; 943 | ONLY_ACTIVE_ARCH = YES; 944 | SDKROOT = iphoneos; 945 | TARGETED_DEVICE_FAMILY = "1,2"; 946 | TVOS_DEPLOYMENT_TARGET = 9.0; 947 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 948 | }; 949 | name = Debug; 950 | }; 951 | 21CC42D217DB874300201DDC /* Release */ = { 952 | isa = XCBuildConfiguration; 953 | buildSettings = { 954 | ALWAYS_SEARCH_USER_PATHS = NO; 955 | APPLICATION_EXTENSION_API_ONLY = YES; 956 | CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; 957 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 958 | CLANG_CXX_LIBRARY = "libc++"; 959 | CLANG_ENABLE_MODULES = YES; 960 | CLANG_ENABLE_OBJC_ARC = YES; 961 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 962 | CLANG_WARN_BOOL_CONVERSION = YES; 963 | CLANG_WARN_COMMA = YES; 964 | CLANG_WARN_CONSTANT_CONVERSION = YES; 965 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 966 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 967 | CLANG_WARN_EMPTY_BODY = YES; 968 | CLANG_WARN_ENUM_CONVERSION = YES; 969 | CLANG_WARN_INFINITE_RECURSION = YES; 970 | CLANG_WARN_INT_CONVERSION = YES; 971 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 972 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 973 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 974 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 975 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 976 | CLANG_WARN_STRICT_PROTOTYPES = YES; 977 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 978 | CLANG_WARN_UNREACHABLE_CODE = YES; 979 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 980 | COPY_PHASE_STRIP = YES; 981 | ENABLE_NS_ASSERTIONS = NO; 982 | ENABLE_STRICT_OBJC_MSGSEND = YES; 983 | GCC_C_LANGUAGE_STANDARD = gnu99; 984 | GCC_NO_COMMON_BLOCKS = YES; 985 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 986 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 987 | GCC_WARN_UNDECLARED_SELECTOR = YES; 988 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 989 | GCC_WARN_UNUSED_FUNCTION = YES; 990 | GCC_WARN_UNUSED_VARIABLE = YES; 991 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 992 | MACOSX_DEPLOYMENT_TARGET = 10.8; 993 | SDKROOT = iphoneos; 994 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 995 | TARGETED_DEVICE_FAMILY = "1,2"; 996 | TVOS_DEPLOYMENT_TARGET = 9.0; 997 | VALIDATE_PRODUCT = YES; 998 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 999 | }; 1000 | name = Release; 1001 | }; 1002 | E8A666481A844CC400287CA3 /* Debug */ = { 1003 | isa = XCBuildConfiguration; 1004 | buildSettings = { 1005 | CLANG_WARN_UNREACHABLE_CODE = YES; 1006 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 1007 | CURRENT_PROJECT_VERSION = 1; 1008 | DEFINES_MODULE = YES; 1009 | DYLIB_COMPATIBILITY_VERSION = 1; 1010 | DYLIB_CURRENT_VERSION = 1; 1011 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1012 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1013 | GCC_PREPROCESSOR_DEFINITIONS = ( 1014 | "DEBUG=1", 1015 | "$(inherited)", 1016 | ); 1017 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1018 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1019 | INFOPLIST_FILE = "$(SRCROOT)/Support/Info.plist"; 1020 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1021 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1022 | MTL_ENABLE_DEBUG_INFO = YES; 1023 | PRODUCT_BUNDLE_IDENTIFIER = "com.samsoffes.$(PRODUCT_NAME:rfc1034identifier)"; 1024 | PRODUCT_NAME = SAMKeychain; 1025 | SKIP_INSTALL = YES; 1026 | VERSIONING_SYSTEM = "apple-generic"; 1027 | VERSION_INFO_PREFIX = ""; 1028 | }; 1029 | name = Debug; 1030 | }; 1031 | E8A666491A844CC400287CA3 /* Test */ = { 1032 | isa = XCBuildConfiguration; 1033 | buildSettings = { 1034 | CLANG_WARN_UNREACHABLE_CODE = YES; 1035 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 1036 | CURRENT_PROJECT_VERSION = 1; 1037 | DEFINES_MODULE = YES; 1038 | DYLIB_COMPATIBILITY_VERSION = 1; 1039 | DYLIB_CURRENT_VERSION = 1; 1040 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1041 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1042 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1043 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1044 | INFOPLIST_FILE = "$(SRCROOT)/Support/Info.plist"; 1045 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1046 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1047 | MTL_ENABLE_DEBUG_INFO = NO; 1048 | PRODUCT_BUNDLE_IDENTIFIER = "com.samsoffes.$(PRODUCT_NAME:rfc1034identifier)"; 1049 | PRODUCT_NAME = SAMKeychain; 1050 | SKIP_INSTALL = YES; 1051 | VERSIONING_SYSTEM = "apple-generic"; 1052 | VERSION_INFO_PREFIX = ""; 1053 | }; 1054 | name = Test; 1055 | }; 1056 | E8A6664A1A844CC400287CA3 /* Release */ = { 1057 | isa = XCBuildConfiguration; 1058 | buildSettings = { 1059 | CLANG_WARN_UNREACHABLE_CODE = YES; 1060 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 1061 | CURRENT_PROJECT_VERSION = 1; 1062 | DEFINES_MODULE = YES; 1063 | DYLIB_COMPATIBILITY_VERSION = 1; 1064 | DYLIB_CURRENT_VERSION = 1; 1065 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1066 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1067 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1068 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1069 | INFOPLIST_FILE = "$(SRCROOT)/Support/Info.plist"; 1070 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1071 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1072 | MTL_ENABLE_DEBUG_INFO = NO; 1073 | PRODUCT_BUNDLE_IDENTIFIER = "com.samsoffes.$(PRODUCT_NAME:rfc1034identifier)"; 1074 | PRODUCT_NAME = SAMKeychain; 1075 | SKIP_INSTALL = YES; 1076 | VERSIONING_SYSTEM = "apple-generic"; 1077 | VERSION_INFO_PREFIX = ""; 1078 | }; 1079 | name = Release; 1080 | }; 1081 | E8A6665F1A844D3A00287CA3 /* Debug */ = { 1082 | isa = XCBuildConfiguration; 1083 | buildSettings = { 1084 | APPLICATION_EXTENSION_API_ONLY = NO; 1085 | CLANG_ENABLE_MODULES = YES; 1086 | CLANG_WARN_UNREACHABLE_CODE = YES; 1087 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1088 | FRAMEWORK_SEARCH_PATHS = ( 1089 | "$(SDKROOT)/Developer/Library/Frameworks", 1090 | "$(inherited)", 1091 | ); 1092 | GCC_PREPROCESSOR_DEFINITIONS = ( 1093 | "DEBUG=1", 1094 | "$(inherited)", 1095 | ); 1096 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1097 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1098 | INFOPLIST_FILE = "Support/Tests-Info.plist"; 1099 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 1100 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1101 | MTL_ENABLE_DEBUG_INFO = YES; 1102 | PRODUCT_BUNDLE_IDENTIFIER = "com.samsoffes.$(PRODUCT_NAME:rfc1034identifier)"; 1103 | PRODUCT_NAME = "$(TARGET_NAME)"; 1104 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 1105 | SWIFT_VERSION = 3.0; 1106 | }; 1107 | name = Debug; 1108 | }; 1109 | E8A666601A844D3A00287CA3 /* Test */ = { 1110 | isa = XCBuildConfiguration; 1111 | buildSettings = { 1112 | APPLICATION_EXTENSION_API_ONLY = NO; 1113 | CLANG_ENABLE_MODULES = YES; 1114 | CLANG_WARN_UNREACHABLE_CODE = YES; 1115 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1116 | FRAMEWORK_SEARCH_PATHS = ( 1117 | "$(SDKROOT)/Developer/Library/Frameworks", 1118 | "$(inherited)", 1119 | ); 1120 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1121 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1122 | INFOPLIST_FILE = "Support/Tests-Info.plist"; 1123 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 1124 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1125 | MTL_ENABLE_DEBUG_INFO = NO; 1126 | PRODUCT_BUNDLE_IDENTIFIER = "com.samsoffes.$(PRODUCT_NAME:rfc1034identifier)"; 1127 | PRODUCT_NAME = "$(TARGET_NAME)"; 1128 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 1129 | SWIFT_VERSION = 3.0; 1130 | }; 1131 | name = Test; 1132 | }; 1133 | E8A666611A844D3A00287CA3 /* Release */ = { 1134 | isa = XCBuildConfiguration; 1135 | buildSettings = { 1136 | APPLICATION_EXTENSION_API_ONLY = NO; 1137 | CLANG_ENABLE_MODULES = YES; 1138 | CLANG_WARN_UNREACHABLE_CODE = YES; 1139 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1140 | FRAMEWORK_SEARCH_PATHS = ( 1141 | "$(SDKROOT)/Developer/Library/Frameworks", 1142 | "$(inherited)", 1143 | ); 1144 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1145 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1146 | INFOPLIST_FILE = "Support/Tests-Info.plist"; 1147 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 1148 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1149 | MTL_ENABLE_DEBUG_INFO = NO; 1150 | PRODUCT_BUNDLE_IDENTIFIER = "com.samsoffes.$(PRODUCT_NAME:rfc1034identifier)"; 1151 | PRODUCT_NAME = "$(TARGET_NAME)"; 1152 | SWIFT_VERSION = 3.0; 1153 | }; 1154 | name = Release; 1155 | }; 1156 | E8A666831A844E4100287CA3 /* Debug */ = { 1157 | isa = XCBuildConfiguration; 1158 | buildSettings = { 1159 | CLANG_WARN_UNREACHABLE_CODE = YES; 1160 | COMBINE_HIDPI_IMAGES = YES; 1161 | CURRENT_PROJECT_VERSION = 1; 1162 | DEFINES_MODULE = YES; 1163 | DYLIB_COMPATIBILITY_VERSION = 1; 1164 | DYLIB_CURRENT_VERSION = 1; 1165 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1166 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1167 | FRAMEWORK_VERSION = A; 1168 | GCC_PREPROCESSOR_DEFINITIONS = ( 1169 | "DEBUG=1", 1170 | "$(inherited)", 1171 | ); 1172 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1173 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1174 | INFOPLIST_FILE = "$(SRCROOT)/Support/Info.plist"; 1175 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1176 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 1177 | MTL_ENABLE_DEBUG_INFO = YES; 1178 | PRODUCT_BUNDLE_IDENTIFIER = "com.samsoffes.$(PRODUCT_NAME:rfc1034identifier)"; 1179 | PRODUCT_NAME = SAMKeychain; 1180 | SDKROOT = macosx; 1181 | SKIP_INSTALL = YES; 1182 | VERSIONING_SYSTEM = "apple-generic"; 1183 | VERSION_INFO_PREFIX = ""; 1184 | }; 1185 | name = Debug; 1186 | }; 1187 | E8A666841A844E4100287CA3 /* Test */ = { 1188 | isa = XCBuildConfiguration; 1189 | buildSettings = { 1190 | CLANG_WARN_UNREACHABLE_CODE = YES; 1191 | COMBINE_HIDPI_IMAGES = YES; 1192 | CURRENT_PROJECT_VERSION = 1; 1193 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1194 | DEFINES_MODULE = YES; 1195 | DYLIB_COMPATIBILITY_VERSION = 1; 1196 | DYLIB_CURRENT_VERSION = 1; 1197 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1198 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1199 | FRAMEWORK_VERSION = A; 1200 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1201 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1202 | INFOPLIST_FILE = "$(SRCROOT)/Support/Info.plist"; 1203 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1204 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 1205 | MTL_ENABLE_DEBUG_INFO = NO; 1206 | PRODUCT_BUNDLE_IDENTIFIER = "com.samsoffes.$(PRODUCT_NAME:rfc1034identifier)"; 1207 | PRODUCT_NAME = SAMKeychain; 1208 | SDKROOT = macosx; 1209 | SKIP_INSTALL = YES; 1210 | VERSIONING_SYSTEM = "apple-generic"; 1211 | VERSION_INFO_PREFIX = ""; 1212 | }; 1213 | name = Test; 1214 | }; 1215 | E8A666851A844E4100287CA3 /* Release */ = { 1216 | isa = XCBuildConfiguration; 1217 | buildSettings = { 1218 | CLANG_WARN_UNREACHABLE_CODE = YES; 1219 | COMBINE_HIDPI_IMAGES = YES; 1220 | CURRENT_PROJECT_VERSION = 1; 1221 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1222 | DEFINES_MODULE = YES; 1223 | DYLIB_COMPATIBILITY_VERSION = 1; 1224 | DYLIB_CURRENT_VERSION = 1; 1225 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1226 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1227 | FRAMEWORK_VERSION = A; 1228 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1229 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1230 | INFOPLIST_FILE = "$(SRCROOT)/Support/Info.plist"; 1231 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1232 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 1233 | MTL_ENABLE_DEBUG_INFO = NO; 1234 | PRODUCT_BUNDLE_IDENTIFIER = "com.samsoffes.$(PRODUCT_NAME:rfc1034identifier)"; 1235 | PRODUCT_NAME = SAMKeychain; 1236 | SDKROOT = macosx; 1237 | SKIP_INSTALL = YES; 1238 | VERSIONING_SYSTEM = "apple-generic"; 1239 | VERSION_INFO_PREFIX = ""; 1240 | }; 1241 | name = Release; 1242 | }; 1243 | E8A666871A844E4100287CA3 /* Debug */ = { 1244 | isa = XCBuildConfiguration; 1245 | buildSettings = { 1246 | APPLICATION_EXTENSION_API_ONLY = NO; 1247 | CLANG_ENABLE_MODULES = YES; 1248 | CLANG_WARN_UNREACHABLE_CODE = YES; 1249 | COMBINE_HIDPI_IMAGES = YES; 1250 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1251 | FRAMEWORK_SEARCH_PATHS = ( 1252 | "$(DEVELOPER_FRAMEWORKS_DIR)", 1253 | "$(inherited)", 1254 | ); 1255 | GCC_PREPROCESSOR_DEFINITIONS = ( 1256 | "DEBUG=1", 1257 | "$(inherited)", 1258 | ); 1259 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1260 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1261 | INFOPLIST_FILE = "Support/Tests-Info.plist"; 1262 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 1263 | MACOSX_DEPLOYMENT_TARGET = 10.10; 1264 | MTL_ENABLE_DEBUG_INFO = YES; 1265 | PRODUCT_BUNDLE_IDENTIFIER = "com.samsoffes.$(PRODUCT_NAME:rfc1034identifier)"; 1266 | PRODUCT_NAME = "$(TARGET_NAME)"; 1267 | SDKROOT = macosx; 1268 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 1269 | SWIFT_VERSION = 3.0; 1270 | }; 1271 | name = Debug; 1272 | }; 1273 | E8A666881A844E4100287CA3 /* Test */ = { 1274 | isa = XCBuildConfiguration; 1275 | buildSettings = { 1276 | APPLICATION_EXTENSION_API_ONLY = NO; 1277 | CLANG_ENABLE_MODULES = YES; 1278 | CLANG_WARN_UNREACHABLE_CODE = YES; 1279 | COMBINE_HIDPI_IMAGES = YES; 1280 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1281 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1282 | FRAMEWORK_SEARCH_PATHS = ( 1283 | "$(DEVELOPER_FRAMEWORKS_DIR)", 1284 | "$(inherited)", 1285 | ); 1286 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1287 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1288 | INFOPLIST_FILE = "Support/Tests-Info.plist"; 1289 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 1290 | MACOSX_DEPLOYMENT_TARGET = 10.10; 1291 | MTL_ENABLE_DEBUG_INFO = NO; 1292 | PRODUCT_BUNDLE_IDENTIFIER = "com.samsoffes.$(PRODUCT_NAME:rfc1034identifier)"; 1293 | PRODUCT_NAME = "$(TARGET_NAME)"; 1294 | SDKROOT = macosx; 1295 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 1296 | SWIFT_VERSION = 3.0; 1297 | }; 1298 | name = Test; 1299 | }; 1300 | E8A666891A844E4100287CA3 /* Release */ = { 1301 | isa = XCBuildConfiguration; 1302 | buildSettings = { 1303 | APPLICATION_EXTENSION_API_ONLY = NO; 1304 | CLANG_ENABLE_MODULES = YES; 1305 | CLANG_WARN_UNREACHABLE_CODE = YES; 1306 | COMBINE_HIDPI_IMAGES = YES; 1307 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1308 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1309 | FRAMEWORK_SEARCH_PATHS = ( 1310 | "$(DEVELOPER_FRAMEWORKS_DIR)", 1311 | "$(inherited)", 1312 | ); 1313 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1314 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1315 | INFOPLIST_FILE = "Support/Tests-Info.plist"; 1316 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 1317 | MACOSX_DEPLOYMENT_TARGET = 10.10; 1318 | MTL_ENABLE_DEBUG_INFO = NO; 1319 | PRODUCT_BUNDLE_IDENTIFIER = "com.samsoffes.$(PRODUCT_NAME:rfc1034identifier)"; 1320 | PRODUCT_NAME = "$(TARGET_NAME)"; 1321 | SDKROOT = macosx; 1322 | SWIFT_VERSION = 3.0; 1323 | }; 1324 | name = Release; 1325 | }; 1326 | /* End XCBuildConfiguration section */ 1327 | 1328 | /* Begin XCConfigurationList section */ 1329 | 21632DA91C925A3C00C40D7D /* Build configuration list for PBXNativeTarget "SAMKeychain-tvOS" */ = { 1330 | isa = XCConfigurationList; 1331 | buildConfigurations = ( 1332 | 21632DAA1C925A3C00C40D7D /* Debug */, 1333 | 21632DAB1C925A3C00C40D7D /* Test */, 1334 | 21632DAC1C925A3C00C40D7D /* Release */, 1335 | ); 1336 | defaultConfigurationIsVisible = 0; 1337 | defaultConfigurationName = Release; 1338 | }; 1339 | 21632DAD1C925A3C00C40D7D /* Build configuration list for PBXNativeTarget "SAMKeychainTests-tvOS" */ = { 1340 | isa = XCConfigurationList; 1341 | buildConfigurations = ( 1342 | 21632DAE1C925A3C00C40D7D /* Debug */, 1343 | 21632DAF1C925A3C00C40D7D /* Test */, 1344 | 21632DB01C925A3C00C40D7D /* Release */, 1345 | ); 1346 | defaultConfigurationIsVisible = 0; 1347 | defaultConfigurationName = Release; 1348 | }; 1349 | 21632DC11C925B1F00C40D7D /* Build configuration list for PBXNativeTarget "SAMKeychain-watchOS" */ = { 1350 | isa = XCConfigurationList; 1351 | buildConfigurations = ( 1352 | 21632DC21C925B1F00C40D7D /* Debug */, 1353 | 21632DC31C925B1F00C40D7D /* Test */, 1354 | 21632DC41C925B1F00C40D7D /* Release */, 1355 | ); 1356 | defaultConfigurationIsVisible = 0; 1357 | defaultConfigurationName = Release; 1358 | }; 1359 | 21CC42A217DB874300201DDC /* Build configuration list for PBXProject "SAMKeychain" */ = { 1360 | isa = XCConfigurationList; 1361 | buildConfigurations = ( 1362 | 21CC42D117DB874300201DDC /* Debug */, 1363 | 215D7DE518ECA54500E7B508 /* Test */, 1364 | 21CC42D217DB874300201DDC /* Release */, 1365 | ); 1366 | defaultConfigurationIsVisible = 0; 1367 | defaultConfigurationName = Release; 1368 | }; 1369 | E8A666471A844CC400287CA3 /* Build configuration list for PBXNativeTarget "SAMKeychain-iOS" */ = { 1370 | isa = XCConfigurationList; 1371 | buildConfigurations = ( 1372 | E8A666481A844CC400287CA3 /* Debug */, 1373 | E8A666491A844CC400287CA3 /* Test */, 1374 | E8A6664A1A844CC400287CA3 /* Release */, 1375 | ); 1376 | defaultConfigurationIsVisible = 0; 1377 | defaultConfigurationName = Release; 1378 | }; 1379 | E8A6665E1A844D3A00287CA3 /* Build configuration list for PBXNativeTarget "SAMKeychainTests-iOS" */ = { 1380 | isa = XCConfigurationList; 1381 | buildConfigurations = ( 1382 | E8A6665F1A844D3A00287CA3 /* Debug */, 1383 | E8A666601A844D3A00287CA3 /* Test */, 1384 | E8A666611A844D3A00287CA3 /* Release */, 1385 | ); 1386 | defaultConfigurationIsVisible = 0; 1387 | defaultConfigurationName = Release; 1388 | }; 1389 | E8A666821A844E4100287CA3 /* Build configuration list for PBXNativeTarget "SAMKeychain-macOS" */ = { 1390 | isa = XCConfigurationList; 1391 | buildConfigurations = ( 1392 | E8A666831A844E4100287CA3 /* Debug */, 1393 | E8A666841A844E4100287CA3 /* Test */, 1394 | E8A666851A844E4100287CA3 /* Release */, 1395 | ); 1396 | defaultConfigurationIsVisible = 0; 1397 | defaultConfigurationName = Release; 1398 | }; 1399 | E8A666861A844E4100287CA3 /* Build configuration list for PBXNativeTarget "SAMKeychainTests-macOS" */ = { 1400 | isa = XCConfigurationList; 1401 | buildConfigurations = ( 1402 | E8A666871A844E4100287CA3 /* Debug */, 1403 | E8A666881A844E4100287CA3 /* Test */, 1404 | E8A666891A844E4100287CA3 /* Release */, 1405 | ); 1406 | defaultConfigurationIsVisible = 0; 1407 | defaultConfigurationName = Release; 1408 | }; 1409 | /* End XCConfigurationList section */ 1410 | }; 1411 | rootObject = 21CC429F17DB874300201DDC /* Project object */; 1412 | } 1413 | -------------------------------------------------------------------------------- /SAMKeychain.xcodeproj/xcshareddata/xcschemes/SAMKeychain-iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /SAMKeychain.xcodeproj/xcshareddata/xcschemes/SAMKeychain-macOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /SAMKeychain.xcodeproj/xcshareddata/xcschemes/SAMKeychain-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /SAMKeychain.xcodeproj/xcshareddata/xcschemes/SAMKeychain-watchOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Sources/SAMKeychain.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAMKeychain.h 3 | // SAMKeychain 4 | // 5 | // Created by Sam Soffes on 5/19/10. 6 | // Copyright (c) 2010-2014 Sam Soffes. All rights reserved. 7 | // 8 | 9 | #if __has_feature(modules) 10 | @import Foundation; 11 | #else 12 | #import 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | /** 18 | Error code specific to SAMKeychain that can be returned in NSError objects. 19 | For codes returned by the operating system, refer to SecBase.h for your 20 | platform. 21 | */ 22 | typedef NS_ENUM(OSStatus, SAMKeychainErrorCode) { 23 | /** Some of the arguments were invalid. */ 24 | SAMKeychainErrorBadArguments = -1001, 25 | }; 26 | 27 | /** SAMKeychain error domain */ 28 | extern NSString *const kSAMKeychainErrorDomain; 29 | 30 | /** Account name. */ 31 | extern NSString *const kSAMKeychainAccountKey; 32 | 33 | /** 34 | Time the item was created. 35 | 36 | The value will be a string. 37 | */ 38 | extern NSString *const kSAMKeychainCreatedAtKey; 39 | 40 | /** Item class. */ 41 | extern NSString *const kSAMKeychainClassKey; 42 | 43 | /** Item description. */ 44 | extern NSString *const kSAMKeychainDescriptionKey; 45 | 46 | /** Item label. */ 47 | extern NSString *const kSAMKeychainLabelKey; 48 | 49 | /** Time the item was last modified. 50 | 51 | The value will be a string. 52 | */ 53 | extern NSString *const kSAMKeychainLastModifiedKey; 54 | 55 | /** Where the item was created. */ 56 | extern NSString *const kSAMKeychainWhereKey; 57 | 58 | /** 59 | Simple wrapper for accessing accounts, getting passwords, setting passwords, and deleting passwords using the system 60 | Keychain on Mac OS X and iOS. 61 | 62 | This was originally inspired by EMKeychain and SDKeychain (both of which are now gone). Thanks to the authors. 63 | SAMKeychain has since switched to a simpler implementation that was abstracted from [SSToolkit](http://sstoolk.it). 64 | */ 65 | @interface SAMKeychain : NSObject 66 | 67 | #pragma mark - Classic methods 68 | 69 | /** 70 | Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't have a 71 | password for the given parameters. 72 | 73 | @param serviceName The service for which to return the corresponding password. 74 | 75 | @param account The account for which to return the corresponding password. 76 | 77 | @return Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't 78 | have a password for the given parameters. 79 | */ 80 | + (nullable NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account; 81 | + (nullable NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error __attribute__((swift_error(none))); 82 | 83 | /** 84 | Returns a nsdata containing the password for a given account and service, or `nil` if the Keychain doesn't have a 85 | password for the given parameters. 86 | 87 | @param serviceName The service for which to return the corresponding password. 88 | 89 | @param account The account for which to return the corresponding password. 90 | 91 | @return Returns a nsdata containing the password for a given account and service, or `nil` if the Keychain doesn't 92 | have a password for the given parameters. 93 | */ 94 | + (nullable NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account; 95 | + (nullable NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error __attribute__((swift_error(none))); 96 | 97 | 98 | /** 99 | Deletes a password from the Keychain. 100 | 101 | @param serviceName The service for which to delete the corresponding password. 102 | 103 | @param account The account for which to delete the corresponding password. 104 | 105 | @return Returns `YES` on success, or `NO` on failure. 106 | */ 107 | + (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account; 108 | + (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error __attribute__((swift_error(none))); 109 | 110 | 111 | /** 112 | Sets a password in the Keychain. 113 | 114 | @param password The password to store in the Keychain. 115 | 116 | @param serviceName The service for which to set the corresponding password. 117 | 118 | @param account The account for which to set the corresponding password. 119 | 120 | @return Returns `YES` on success, or `NO` on failure. 121 | */ 122 | + (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account; 123 | + (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error __attribute__((swift_error(none))); 124 | 125 | /** 126 | Sets a password in the Keychain. 127 | 128 | @param password The password to store in the Keychain. 129 | 130 | @param serviceName The service for which to set the corresponding password. 131 | 132 | @param account The account for which to set the corresponding password. 133 | 134 | @return Returns `YES` on success, or `NO` on failure. 135 | */ 136 | + (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account; 137 | + (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error __attribute__((swift_error(none))); 138 | 139 | /** 140 | Returns an array containing the Keychain's accounts, or `nil` if the Keychain has no accounts. 141 | 142 | See the `NSString` constants declared in SAMKeychain.h for a list of keys that can be used when accessing the 143 | dictionaries returned by this method. 144 | 145 | @return An array of dictionaries containing the Keychain's accounts, or `nil` if the Keychain doesn't have any 146 | accounts. The order of the objects in the array isn't defined. 147 | */ 148 | + (nullable NSArray *> *)allAccounts; 149 | + (nullable NSArray *> *)allAccounts:(NSError *__autoreleasing *)error __attribute__((swift_error(none))); 150 | 151 | 152 | /** 153 | Returns an array containing the Keychain's accounts for a given service, or `nil` if the Keychain doesn't have any 154 | accounts for the given service. 155 | 156 | See the `NSString` constants declared in SAMKeychain.h for a list of keys that can be used when accessing the 157 | dictionaries returned by this method. 158 | 159 | @param serviceName The service for which to return the corresponding accounts. 160 | 161 | @return An array of dictionaries containing the Keychain's accounts for a given `serviceName`, or `nil` if the Keychain 162 | doesn't have any accounts for the given `serviceName`. The order of the objects in the array isn't defined. 163 | */ 164 | + (nullable NSArray *> *)accountsForService:(nullable NSString *)serviceName; 165 | + (nullable NSArray *> *)accountsForService:(nullable NSString *)serviceName error:(NSError *__autoreleasing *)error __attribute__((swift_error(none))); 166 | 167 | 168 | #pragma mark - Configuration 169 | 170 | #if __IPHONE_4_0 && TARGET_OS_IPHONE 171 | /** 172 | Returns the accessibility type for all future passwords saved to the Keychain. 173 | 174 | @return Returns the accessibility type. 175 | 176 | The return value will be `NULL` or one of the "Keychain Item Accessibility 177 | Constants" used for determining when a keychain item should be readable. 178 | 179 | @see setAccessibilityType 180 | */ 181 | + (CFTypeRef)accessibilityType; 182 | 183 | /** 184 | Sets the accessibility type for all future passwords saved to the Keychain. 185 | 186 | @param accessibilityType One of the "Keychain Item Accessibility Constants" 187 | used for determining when a keychain item should be readable. 188 | 189 | If the value is `NULL` (the default), the Keychain default will be used which 190 | is highly insecure. You really should use at least `kSecAttrAccessibleAfterFirstUnlock` 191 | for background applications or `kSecAttrAccessibleWhenUnlocked` for all 192 | other applications. 193 | 194 | @see accessibilityType 195 | */ 196 | + (void)setAccessibilityType:(CFTypeRef)accessibilityType; 197 | #endif 198 | 199 | @end 200 | 201 | NS_ASSUME_NONNULL_END 202 | 203 | #import 204 | -------------------------------------------------------------------------------- /Sources/SAMKeychain.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAMKeychain.m 3 | // SAMKeychain 4 | // 5 | // Created by Sam Soffes on 5/19/10. 6 | // Copyright (c) 2010-2014 Sam Soffes. All rights reserved. 7 | // 8 | 9 | #import "SAMKeychain.h" 10 | #import "SAMKeychainQuery.h" 11 | 12 | NSString *const kSAMKeychainErrorDomain = @"com.samsoffes.samkeychain"; 13 | NSString *const kSAMKeychainAccountKey = @"acct"; 14 | NSString *const kSAMKeychainCreatedAtKey = @"cdat"; 15 | NSString *const kSAMKeychainClassKey = @"labl"; 16 | NSString *const kSAMKeychainDescriptionKey = @"desc"; 17 | NSString *const kSAMKeychainLabelKey = @"labl"; 18 | NSString *const kSAMKeychainLastModifiedKey = @"mdat"; 19 | NSString *const kSAMKeychainWhereKey = @"svce"; 20 | 21 | #if __IPHONE_4_0 && TARGET_OS_IPHONE 22 | static CFTypeRef SAMKeychainAccessibilityType = NULL; 23 | #endif 24 | 25 | @implementation SAMKeychain 26 | 27 | + (nullable NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account { 28 | return [self passwordForService:serviceName account:account error:nil]; 29 | } 30 | 31 | 32 | + (nullable NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account error:(NSError *__autoreleasing *)error { 33 | SAMKeychainQuery *query = [[SAMKeychainQuery alloc] init]; 34 | query.service = serviceName; 35 | query.account = account; 36 | [query fetch:error]; 37 | return query.password; 38 | } 39 | 40 | + (nullable NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account { 41 | return [self passwordDataForService:serviceName account:account error:nil]; 42 | } 43 | 44 | + (nullable NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error { 45 | SAMKeychainQuery *query = [[SAMKeychainQuery alloc] init]; 46 | query.service = serviceName; 47 | query.account = account; 48 | [query fetch:error]; 49 | 50 | return query.passwordData; 51 | } 52 | 53 | 54 | + (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account { 55 | return [self deletePasswordForService:serviceName account:account error:nil]; 56 | } 57 | 58 | 59 | + (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account error:(NSError *__autoreleasing *)error { 60 | SAMKeychainQuery *query = [[SAMKeychainQuery alloc] init]; 61 | query.service = serviceName; 62 | query.account = account; 63 | return [query deleteItem:error]; 64 | } 65 | 66 | 67 | + (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account { 68 | return [self setPassword:password forService:serviceName account:account error:nil]; 69 | } 70 | 71 | 72 | + (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError *__autoreleasing *)error { 73 | SAMKeychainQuery *query = [[SAMKeychainQuery alloc] init]; 74 | query.service = serviceName; 75 | query.account = account; 76 | query.password = password; 77 | return [query save:error]; 78 | } 79 | 80 | + (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account { 81 | return [self setPasswordData:password forService:serviceName account:account error:nil]; 82 | } 83 | 84 | 85 | + (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error { 86 | SAMKeychainQuery *query = [[SAMKeychainQuery alloc] init]; 87 | query.service = serviceName; 88 | query.account = account; 89 | query.passwordData = password; 90 | return [query save:error]; 91 | } 92 | 93 | + (nullable NSArray *)allAccounts { 94 | return [self allAccounts:nil]; 95 | } 96 | 97 | 98 | + (nullable NSArray *)allAccounts:(NSError *__autoreleasing *)error { 99 | return [self accountsForService:nil error:error]; 100 | } 101 | 102 | 103 | + (nullable NSArray *)accountsForService:(nullable NSString *)serviceName { 104 | return [self accountsForService:serviceName error:nil]; 105 | } 106 | 107 | 108 | + (nullable NSArray *)accountsForService:(nullable NSString *)serviceName error:(NSError *__autoreleasing *)error { 109 | SAMKeychainQuery *query = [[SAMKeychainQuery alloc] init]; 110 | query.service = serviceName; 111 | return [query fetchAll:error]; 112 | } 113 | 114 | 115 | #if __IPHONE_4_0 && TARGET_OS_IPHONE 116 | + (CFTypeRef)accessibilityType { 117 | return SAMKeychainAccessibilityType; 118 | } 119 | 120 | 121 | + (void)setAccessibilityType:(CFTypeRef)accessibilityType { 122 | CFRetain(accessibilityType); 123 | if (SAMKeychainAccessibilityType) { 124 | CFRelease(SAMKeychainAccessibilityType); 125 | } 126 | SAMKeychainAccessibilityType = accessibilityType; 127 | } 128 | #endif 129 | 130 | @end 131 | -------------------------------------------------------------------------------- /Sources/SAMKeychainQuery.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAMKeychainQuery.h 3 | // SAMKeychain 4 | // 5 | // Created by Caleb Davenport on 3/19/13. 6 | // Copyright (c) 2013-2014 Sam Soffes. All rights reserved. 7 | // 8 | 9 | #if __has_feature(modules) 10 | @import Foundation; 11 | @import Security; 12 | #else 13 | #import 14 | #import 15 | #endif 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | #if __IPHONE_7_0 || __MAC_10_9 20 | // Keychain synchronization available at compile time 21 | #define SAMKEYCHAIN_SYNCHRONIZATION_AVAILABLE 1 22 | #endif 23 | 24 | #if __IPHONE_3_0 || __MAC_10_9 25 | // Keychain access group available at compile time 26 | #define SAMKEYCHAIN_ACCESS_GROUP_AVAILABLE 1 27 | #endif 28 | 29 | #ifdef SAMKEYCHAIN_SYNCHRONIZATION_AVAILABLE 30 | typedef NS_ENUM(NSUInteger, SAMKeychainQuerySynchronizationMode) { 31 | SAMKeychainQuerySynchronizationModeAny, 32 | SAMKeychainQuerySynchronizationModeNo, 33 | SAMKeychainQuerySynchronizationModeYes 34 | }; 35 | #endif 36 | 37 | /** 38 | Simple interface for querying or modifying keychain items. 39 | */ 40 | @interface SAMKeychainQuery : NSObject 41 | 42 | /** kSecAttrAccount */ 43 | @property (nonatomic, copy, nullable) NSString *account; 44 | 45 | /** kSecAttrService */ 46 | @property (nonatomic, copy, nullable) NSString *service; 47 | 48 | /** kSecAttrLabel */ 49 | @property (nonatomic, copy, nullable) NSString *label; 50 | 51 | #ifdef SAMKEYCHAIN_ACCESS_GROUP_AVAILABLE 52 | /** kSecAttrAccessGroup (only used on iOS) */ 53 | @property (nonatomic, copy, nullable) NSString *accessGroup; 54 | #endif 55 | 56 | #ifdef SAMKEYCHAIN_SYNCHRONIZATION_AVAILABLE 57 | /** kSecAttrSynchronizable */ 58 | @property (nonatomic) SAMKeychainQuerySynchronizationMode synchronizationMode; 59 | #endif 60 | 61 | /** Root storage for password information */ 62 | @property (nonatomic, copy, nullable) NSData *passwordData; 63 | 64 | /** 65 | This property automatically transitions between an object and the value of 66 | `passwordData` using NSKeyedArchiver and NSKeyedUnarchiver. 67 | */ 68 | @property (nonatomic, copy, nullable) id passwordObject; 69 | 70 | /** 71 | Convenience accessor for setting and getting a password string. Passes through 72 | to `passwordData` using UTF-8 string encoding. 73 | */ 74 | @property (nonatomic, copy, nullable) NSString *password; 75 | 76 | 77 | ///------------------------ 78 | /// @name Saving & Deleting 79 | ///------------------------ 80 | 81 | /** 82 | Save the receiver's attributes as a keychain item. Existing items with the 83 | given account, service, and access group will first be deleted. 84 | 85 | @param error Populated should an error occur. 86 | 87 | @return `YES` if saving was successful, `NO` otherwise. 88 | */ 89 | - (BOOL)save:(NSError **)error; 90 | 91 | /** 92 | Delete keychain items that match the given account, service, and access group. 93 | 94 | @param error Populated should an error occur. 95 | 96 | @return `YES` if saving was successful, `NO` otherwise. 97 | */ 98 | - (BOOL)deleteItem:(NSError **)error; 99 | 100 | 101 | ///--------------- 102 | /// @name Fetching 103 | ///--------------- 104 | 105 | /** 106 | Fetch all keychain items that match the given account, service, and access 107 | group. The values of `password` and `passwordData` are ignored when fetching. 108 | 109 | @param error Populated should an error occur. 110 | 111 | @return An array of dictionaries that represent all matching keychain items or 112 | `nil` should an error occur. 113 | The order of the items is not determined. 114 | */ 115 | - (nullable NSArray *> *)fetchAll:(NSError **)error; 116 | 117 | /** 118 | Fetch the keychain item that matches the given account, service, and access 119 | group. The `password` and `passwordData` properties will be populated unless 120 | an error occurs. The values of `password` and `passwordData` are ignored when 121 | fetching. 122 | 123 | @param error Populated should an error occur. 124 | 125 | @return `YES` if fetching was successful, `NO` otherwise. 126 | */ 127 | - (BOOL)fetch:(NSError **)error; 128 | 129 | 130 | ///----------------------------- 131 | /// @name Synchronization Status 132 | ///----------------------------- 133 | 134 | #ifdef SAMKEYCHAIN_SYNCHRONIZATION_AVAILABLE 135 | /** 136 | Returns a boolean indicating if keychain synchronization is available on the device at runtime. The #define 137 | SAMKEYCHAIN_SYNCHRONIZATION_AVAILABLE is only for compile time. If you are checking for the presence of synchronization, 138 | you should use this method. 139 | 140 | @return A value indicating if keychain synchronization is available 141 | */ 142 | + (BOOL)isSynchronizationAvailable; 143 | #endif 144 | 145 | @end 146 | 147 | NS_ASSUME_NONNULL_END 148 | -------------------------------------------------------------------------------- /Sources/SAMKeychainQuery.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAMKeychainQuery.m 3 | // SAMKeychain 4 | // 5 | // Created by Caleb Davenport on 3/19/13. 6 | // Copyright (c) 2013-2014 Sam Soffes. All rights reserved. 7 | // 8 | 9 | #import "SAMKeychainQuery.h" 10 | #import "SAMKeychain.h" 11 | 12 | @implementation SAMKeychainQuery 13 | 14 | @synthesize account = _account; 15 | @synthesize service = _service; 16 | @synthesize label = _label; 17 | @synthesize passwordData = _passwordData; 18 | 19 | #ifdef SAMKEYCHAIN_ACCESS_GROUP_AVAILABLE 20 | @synthesize accessGroup = _accessGroup; 21 | #endif 22 | 23 | #ifdef SAMKEYCHAIN_SYNCHRONIZATION_AVAILABLE 24 | @synthesize synchronizationMode = _synchronizationMode; 25 | #endif 26 | 27 | #pragma mark - Public 28 | 29 | - (BOOL)save:(NSError *__autoreleasing *)error { 30 | OSStatus status = SAMKeychainErrorBadArguments; 31 | if (!self.service || !self.account || !self.passwordData) { 32 | if (error) { 33 | *error = [[self class] errorWithCode:status]; 34 | } 35 | return NO; 36 | } 37 | NSMutableDictionary *query = nil; 38 | NSMutableDictionary * searchQuery = [self query]; 39 | status = SecItemCopyMatching((__bridge CFDictionaryRef)searchQuery, nil); 40 | if (status == errSecSuccess) {//item already exists, update it! 41 | query = [[NSMutableDictionary alloc]init]; 42 | [query setObject:self.passwordData forKey:(__bridge id)kSecValueData]; 43 | #if __IPHONE_4_0 && TARGET_OS_IPHONE 44 | CFTypeRef accessibilityType = [SAMKeychain accessibilityType]; 45 | if (accessibilityType) { 46 | [query setObject:(__bridge id)accessibilityType forKey:(__bridge id)kSecAttrAccessible]; 47 | } 48 | #endif 49 | status = SecItemUpdate((__bridge CFDictionaryRef)(searchQuery), (__bridge CFDictionaryRef)(query)); 50 | }else if(status == errSecItemNotFound){//item not found, create it! 51 | query = [self query]; 52 | if (self.label) { 53 | [query setObject:self.label forKey:(__bridge id)kSecAttrLabel]; 54 | } 55 | [query setObject:self.passwordData forKey:(__bridge id)kSecValueData]; 56 | #if __IPHONE_4_0 && TARGET_OS_IPHONE 57 | CFTypeRef accessibilityType = [SAMKeychain accessibilityType]; 58 | if (accessibilityType) { 59 | [query setObject:(__bridge id)accessibilityType forKey:(__bridge id)kSecAttrAccessible]; 60 | } 61 | #endif 62 | status = SecItemAdd((__bridge CFDictionaryRef)query, NULL); 63 | } 64 | if (status != errSecSuccess && error != NULL) { 65 | *error = [[self class] errorWithCode:status]; 66 | } 67 | return (status == errSecSuccess);} 68 | 69 | 70 | - (BOOL)deleteItem:(NSError *__autoreleasing *)error { 71 | OSStatus status = SAMKeychainErrorBadArguments; 72 | if (!self.service || !self.account) { 73 | if (error) { 74 | *error = [[self class] errorWithCode:status]; 75 | } 76 | return NO; 77 | } 78 | 79 | NSMutableDictionary *query = [self query]; 80 | #if TARGET_OS_IPHONE 81 | status = SecItemDelete((__bridge CFDictionaryRef)query); 82 | #else 83 | // On Mac OS, SecItemDelete will not delete a key created in a different 84 | // app, nor in a different version of the same app. 85 | // 86 | // To replicate the issue, save a password, change to the code and 87 | // rebuild the app, and then attempt to delete that password. 88 | // 89 | // This was true in OS X 10.6 and probably later versions as well. 90 | // 91 | // Work around it by using SecItemCopyMatching and SecKeychainItemDelete. 92 | CFTypeRef result = NULL; 93 | [query setObject:@YES forKey:(__bridge id)kSecReturnRef]; 94 | status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); 95 | if (status == errSecSuccess) { 96 | status = SecKeychainItemDelete((SecKeychainItemRef)result); 97 | CFRelease(result); 98 | } 99 | #endif 100 | 101 | if (status != errSecSuccess && error != NULL) { 102 | *error = [[self class] errorWithCode:status]; 103 | } 104 | 105 | return (status == errSecSuccess); 106 | } 107 | 108 | 109 | - (nullable NSArray *)fetchAll:(NSError *__autoreleasing *)error { 110 | NSMutableDictionary *query = [self query]; 111 | [query setObject:@YES forKey:(__bridge id)kSecReturnAttributes]; 112 | [query setObject:(__bridge id)kSecMatchLimitAll forKey:(__bridge id)kSecMatchLimit]; 113 | #if __IPHONE_4_0 && TARGET_OS_IPHONE 114 | CFTypeRef accessibilityType = [SAMKeychain accessibilityType]; 115 | if (accessibilityType) { 116 | [query setObject:(__bridge id)accessibilityType forKey:(__bridge id)kSecAttrAccessible]; 117 | } 118 | #endif 119 | 120 | CFTypeRef result = NULL; 121 | OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); 122 | if (status != errSecSuccess && error != NULL) { 123 | *error = [[self class] errorWithCode:status]; 124 | return nil; 125 | } 126 | 127 | return (__bridge_transfer NSArray *)result; 128 | } 129 | 130 | 131 | - (BOOL)fetch:(NSError *__autoreleasing *)error { 132 | OSStatus status = SAMKeychainErrorBadArguments; 133 | if (!self.service || !self.account) { 134 | if (error) { 135 | *error = [[self class] errorWithCode:status]; 136 | } 137 | return NO; 138 | } 139 | 140 | CFTypeRef result = NULL; 141 | NSMutableDictionary *query = [self query]; 142 | [query setObject:@YES forKey:(__bridge id)kSecReturnData]; 143 | [query setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit]; 144 | status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); 145 | 146 | if (status != errSecSuccess) { 147 | if (error) { 148 | *error = [[self class] errorWithCode:status]; 149 | } 150 | return NO; 151 | } 152 | 153 | self.passwordData = (__bridge_transfer NSData *)result; 154 | return YES; 155 | } 156 | 157 | 158 | #pragma mark - Accessors 159 | 160 | - (void)setPasswordObject:(id)object { 161 | self.passwordData = [NSKeyedArchiver archivedDataWithRootObject:object]; 162 | } 163 | 164 | 165 | - (id)passwordObject { 166 | if ([self.passwordData length]) { 167 | return [NSKeyedUnarchiver unarchiveObjectWithData:self.passwordData]; 168 | } 169 | return nil; 170 | } 171 | 172 | 173 | - (void)setPassword:(NSString *)password { 174 | self.passwordData = [password dataUsingEncoding:NSUTF8StringEncoding]; 175 | } 176 | 177 | 178 | - (NSString *)password { 179 | if ([self.passwordData length]) { 180 | return [[NSString alloc] initWithData:self.passwordData encoding:NSUTF8StringEncoding]; 181 | } 182 | return nil; 183 | } 184 | 185 | 186 | #pragma mark - Synchronization Status 187 | 188 | #ifdef SAMKEYCHAIN_SYNCHRONIZATION_AVAILABLE 189 | + (BOOL)isSynchronizationAvailable { 190 | #if TARGET_OS_IPHONE 191 | // Apple suggested way to check for 7.0 at runtime 192 | // https://developer.apple.com/library/ios/documentation/userexperience/conceptual/transitionguide/SupportingEarlieriOS.html 193 | return floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1; 194 | #else 195 | return floor(NSFoundationVersionNumber) > NSFoundationVersionNumber10_8_4; 196 | #endif 197 | } 198 | #endif 199 | 200 | 201 | #pragma mark - Private 202 | 203 | - (NSMutableDictionary *)query { 204 | NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:3]; 205 | [dictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; 206 | 207 | if (self.service) { 208 | [dictionary setObject:self.service forKey:(__bridge id)kSecAttrService]; 209 | } 210 | 211 | if (self.account) { 212 | [dictionary setObject:self.account forKey:(__bridge id)kSecAttrAccount]; 213 | } 214 | 215 | #ifdef SAMKEYCHAIN_ACCESS_GROUP_AVAILABLE 216 | #if !TARGET_IPHONE_SIMULATOR 217 | if (self.accessGroup) { 218 | [dictionary setObject:self.accessGroup forKey:(__bridge id)kSecAttrAccessGroup]; 219 | } 220 | #endif 221 | #endif 222 | 223 | #ifdef SAMKEYCHAIN_SYNCHRONIZATION_AVAILABLE 224 | if ([[self class] isSynchronizationAvailable]) { 225 | id value; 226 | 227 | switch (self.synchronizationMode) { 228 | case SAMKeychainQuerySynchronizationModeNo: { 229 | value = @NO; 230 | break; 231 | } 232 | case SAMKeychainQuerySynchronizationModeYes: { 233 | value = @YES; 234 | break; 235 | } 236 | case SAMKeychainQuerySynchronizationModeAny: { 237 | value = (__bridge id)(kSecAttrSynchronizableAny); 238 | break; 239 | } 240 | } 241 | 242 | [dictionary setObject:value forKey:(__bridge id)(kSecAttrSynchronizable)]; 243 | } 244 | #endif 245 | 246 | return dictionary; 247 | } 248 | 249 | 250 | + (NSError *)errorWithCode:(OSStatus) code { 251 | static dispatch_once_t onceToken; 252 | static NSBundle *resourcesBundle = nil; 253 | dispatch_once(&onceToken, ^{ 254 | NSURL *url = [[NSBundle bundleForClass:[SAMKeychainQuery class]] URLForResource:@"SAMKeychain" withExtension:@"bundle"]; 255 | resourcesBundle = [NSBundle bundleWithURL:url]; 256 | }); 257 | 258 | NSString *message = nil; 259 | switch (code) { 260 | case errSecSuccess: return nil; 261 | case SAMKeychainErrorBadArguments: message = NSLocalizedStringFromTableInBundle(@"SAMKeychainErrorBadArguments", @"SAMKeychain", resourcesBundle, nil); break; 262 | 263 | #if TARGET_OS_IPHONE 264 | case errSecUnimplemented: { 265 | message = NSLocalizedStringFromTableInBundle(@"errSecUnimplemented", @"SAMKeychain", resourcesBundle, nil); 266 | break; 267 | } 268 | case errSecParam: { 269 | message = NSLocalizedStringFromTableInBundle(@"errSecParam", @"SAMKeychain", resourcesBundle, nil); 270 | break; 271 | } 272 | case errSecAllocate: { 273 | message = NSLocalizedStringFromTableInBundle(@"errSecAllocate", @"SAMKeychain", resourcesBundle, nil); 274 | break; 275 | } 276 | case errSecNotAvailable: { 277 | message = NSLocalizedStringFromTableInBundle(@"errSecNotAvailable", @"SAMKeychain", resourcesBundle, nil); 278 | break; 279 | } 280 | case errSecDuplicateItem: { 281 | message = NSLocalizedStringFromTableInBundle(@"errSecDuplicateItem", @"SAMKeychain", resourcesBundle, nil); 282 | break; 283 | } 284 | case errSecItemNotFound: { 285 | message = NSLocalizedStringFromTableInBundle(@"errSecItemNotFound", @"SAMKeychain", resourcesBundle, nil); 286 | break; 287 | } 288 | case errSecInteractionNotAllowed: { 289 | message = NSLocalizedStringFromTableInBundle(@"errSecInteractionNotAllowed", @"SAMKeychain", resourcesBundle, nil); 290 | break; 291 | } 292 | case errSecDecode: { 293 | message = NSLocalizedStringFromTableInBundle(@"errSecDecode", @"SAMKeychain", resourcesBundle, nil); 294 | break; 295 | } 296 | case errSecAuthFailed: { 297 | message = NSLocalizedStringFromTableInBundle(@"errSecAuthFailed", @"SAMKeychain", resourcesBundle, nil); 298 | break; 299 | } 300 | default: { 301 | message = NSLocalizedStringFromTableInBundle(@"errSecDefault", @"SAMKeychain", resourcesBundle, nil); 302 | } 303 | #else 304 | default: 305 | message = (__bridge_transfer NSString *)SecCopyErrorMessageString(code, NULL); 306 | #endif 307 | } 308 | 309 | NSDictionary *userInfo = nil; 310 | if (message) { 311 | userInfo = @{ NSLocalizedDescriptionKey : message }; 312 | } 313 | return [NSError errorWithDomain:kSAMKeychainErrorDomain code:code userInfo:userInfo]; 314 | } 315 | 316 | @end 317 | -------------------------------------------------------------------------------- /Support/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.5.3 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Support/SAMKeychain.bundle/en.lproj/SAMKeychain.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soffes/SAMKeychain/d3d64f8c5fa14bf2adb2d51a18ee8b6639232ca5/Support/SAMKeychain.bundle/en.lproj/SAMKeychain.strings -------------------------------------------------------------------------------- /Support/Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Tests/KeychainTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeychainTests.swift 3 | // SAMKeychain 4 | // 5 | // Created by Sam Soffes on 3/10/16. 6 | // Copyright © 2010-2016 Sam Soffes. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import SAMKeychain 11 | 12 | class KeychainTests: XCTestCase { 13 | 14 | // MARK: - Properties 15 | 16 | let testService = "SSToolkitTestService" 17 | let testAccount = "SSToolkitTestAccount" 18 | let testPassword = "SSToolkitTestPassword" 19 | let testLabel = "SSToolkitLabel" 20 | 21 | 22 | // MARK: - XCTestCase 23 | 24 | override func tearDown() { 25 | SAMKeychain.deletePasswordForService(testService, account: testAccount) 26 | super.tearDown() 27 | } 28 | 29 | 30 | // MARK: - Tests 31 | 32 | func testNewItem() { 33 | // New item 34 | let newQuery = SAMKeychainQuery() 35 | newQuery.password = testPassword 36 | newQuery.service = testService 37 | newQuery.account = testAccount 38 | newQuery.label = testLabel 39 | try! newQuery.save() 40 | 41 | // Look up 42 | let lookupQuery = SAMKeychainQuery() 43 | lookupQuery.service = testService 44 | lookupQuery.account = testAccount 45 | try! lookupQuery.fetch() 46 | 47 | XCTAssertEqual(newQuery.password, lookupQuery.password) 48 | 49 | // Search for all accounts 50 | let allQuery = SAMKeychainQuery() 51 | var accounts = try! allQuery.fetchAll() 52 | XCTAssertTrue(self.accounts(accounts, containsAccountWithName: testAccount), "Matching account was not returned") 53 | 54 | // Check accounts for service 55 | allQuery.service = testService 56 | accounts = try! allQuery.fetchAll() 57 | XCTAssertTrue(self.accounts(accounts, containsAccountWithName: testAccount), "Matching account was not returned") 58 | 59 | // Delete 60 | let deleteQuery = SAMKeychainQuery() 61 | deleteQuery.service = testService 62 | deleteQuery.account = testAccount 63 | try! deleteQuery.deleteItem() 64 | } 65 | 66 | func testPasswordObject() { 67 | let newQuery = SAMKeychainQuery() 68 | newQuery.service = testService 69 | newQuery.account = testAccount 70 | 71 | let dictionary: [String: NSObject] = [ 72 | "number": 42, 73 | "string": "Hello World" 74 | ] 75 | 76 | newQuery.passwordObject = dictionary 77 | try! newQuery.save() 78 | 79 | let lookupQuery = SAMKeychainQuery() 80 | lookupQuery.service = testService 81 | lookupQuery.account = testAccount 82 | try! lookupQuery.fetch() 83 | 84 | let readDictionary = lookupQuery.passwordObject as! [String: NSObject] 85 | XCTAssertEqual(dictionary, readDictionary) 86 | } 87 | 88 | func testCreateWithMissingInformation() { 89 | var query = SAMKeychainQuery() 90 | query.service = testService 91 | query.account = testAccount 92 | XCTAssertThrowsError(try query.save()) 93 | 94 | query = SAMKeychainQuery() 95 | query.account = testAccount 96 | query.password = testPassword 97 | XCTAssertThrowsError(try query.save()) 98 | 99 | query = SAMKeychainQuery() 100 | query.service = testService 101 | query.password = testPassword 102 | XCTAssertThrowsError(try query.save()) 103 | } 104 | 105 | func testDeleteWithMissingInformation() { 106 | var query = SAMKeychainQuery() 107 | query.account = testAccount 108 | XCTAssertThrowsError(try query.deleteItem()) 109 | 110 | query = SAMKeychainQuery() 111 | query.service = testService 112 | XCTAssertThrowsError(try query.deleteItem()) 113 | 114 | query = SAMKeychainQuery() 115 | query.account = testAccount 116 | XCTAssertThrowsError(try query.deleteItem()) 117 | } 118 | 119 | func testFetchWithMissingInformation() { 120 | var query = SAMKeychainQuery() 121 | query.account = testAccount 122 | XCTAssertThrowsError(try query.fetch()) 123 | 124 | query = SAMKeychainQuery() 125 | query.service = testService 126 | XCTAssertThrowsError(try query.fetch()) 127 | } 128 | 129 | func testSynchronizable() { 130 | let createQuery = SAMKeychainQuery() 131 | createQuery.service = testService 132 | createQuery.account = testAccount 133 | createQuery.password = testPassword 134 | createQuery.synchronizationMode = .Yes 135 | try! createQuery.save() 136 | 137 | let noFetchQuery = SAMKeychainQuery() 138 | noFetchQuery.service = testService 139 | noFetchQuery.account = testAccount 140 | noFetchQuery.synchronizationMode = .No 141 | XCTAssertThrowsError(try noFetchQuery.fetch()) 142 | XCTAssertNotEqual(createQuery.password, noFetchQuery.password) 143 | 144 | let anyFetchQuery = SAMKeychainQuery() 145 | anyFetchQuery.service = testService 146 | anyFetchQuery.account = testAccount 147 | anyFetchQuery.synchronizationMode = .Any 148 | try! anyFetchQuery.fetch() 149 | XCTAssertEqual(createQuery.password, anyFetchQuery.password) 150 | } 151 | 152 | func testConvenienceMethods() { 153 | // Create a new item 154 | SAMKeychain.setPassword(testPassword, forService: testService, account: testAccount) 155 | 156 | // Check password 157 | XCTAssertEqual(testPassword, SAMKeychain.passwordForService(testService, account: testAccount)) 158 | 159 | // Check all accounts 160 | XCTAssertTrue(accounts(SAMKeychain.allAccounts(), containsAccountWithName: testAccount)) 161 | 162 | // Check account 163 | XCTAssertTrue(accounts(SAMKeychain.accountsForService(testService), containsAccountWithName: testAccount)) 164 | 165 | #if !os(OSX) 166 | SAMKeychain.setAccessibilityType(kSecAttrAccessibleWhenUnlockedThisDeviceOnly) 167 | XCTAssertEqual(String(kSecAttrAccessibleWhenUnlockedThisDeviceOnly), String(SAMKeychain.accessibilityType().takeRetainedValue())) 168 | #endif 169 | } 170 | 171 | func testUpdateAccessibilityType() { 172 | SAMKeychain.setAccessibilityType(kSecAttrAccessibleWhenUnlockedThisDeviceOnly) 173 | 174 | // Create a new item 175 | SAMKeychain.setPassword(testPassword, forService: testService, account: testAccount) 176 | 177 | // Check all accounts 178 | XCTAssertTrue(accounts(SAMKeychain.allAccounts(), containsAccountWithName: testAccount)) 179 | 180 | // Check account 181 | XCTAssertTrue(accounts(SAMKeychain.accountsForService(testService), containsAccountWithName: testAccount)) 182 | 183 | SAMKeychain.setAccessibilityType(kSecAttrAccessibleAlwaysThisDeviceOnly) 184 | SAMKeychain.setPassword(testPassword, forService: testService, account: testAccount) 185 | 186 | // Check all accounts 187 | XCTAssertTrue(accounts(SAMKeychain.allAccounts(), containsAccountWithName: testAccount)) 188 | 189 | // Check account 190 | XCTAssertTrue(accounts(SAMKeychain.accountsForService(testService), containsAccountWithName: testAccount)) 191 | } 192 | 193 | 194 | // MARK: - Private 195 | 196 | private func accounts(accounts: [[String: AnyObject]], containsAccountWithName name: String) -> Bool { 197 | for account in accounts { 198 | if let acct = account["acct"] as? String where acct == name { 199 | return true 200 | } 201 | } 202 | 203 | return false 204 | } 205 | } 206 | --------------------------------------------------------------------------------