Browse files

Version 0.1.3

* Added ARC support
* Added ARC tests
  • Loading branch information...
1 parent 0b0dbf2 commit ca7ebbc40e9b14e3328f9694a32ad40470d1fb04 @soffes soffes committed May 8, 2012
Showing with 190 additions and 13 deletions.
  1. +6 −1 Changelog.markdown
  2. +3 −1 Readme.markdown
  3. +55 −11 SSKeychain.m
  4. +104 −0 Tests/SSKeychain.xcodeproj/project.pbxproj
  5. +22 −0 Tests/SSKeychainTestsARC-Info.plist
View
7 Changelog.markdown
@@ -1,10 +1,15 @@
# SSKeychain Changelog
+### Version 0.1.3
+
+[Released October 18, 2011](https://github.com/samsoffes/sskeychain/tree/0.1.2)
+
+* Added ARC support
+
### Version 0.1.2
[Released October 18, 2011](https://github.com/samsoffes/sskeychain/tree/0.1.2)
-* Added VERSION file
* Added documentation
* Added string constants for keys in returned dictionaries
* Renamed `SSKeychainErrorDomain` to `kSSKeychainErrorDomain`
View
4 Readme.markdown
@@ -1,6 +1,6 @@
# SSKeychain
-SSKeychain is a simple wrapper for accessing accounts, getting passwords, setting passwords, and deleting passwords using the system Keychain on Mac OS X and iOS.
+SSKeychain is a simple wrapper for accessing accounts, getting passwords, setting passwords, and deleting passwords using the system Keychain on Mac OS X and iOS. SSKeychain works in ARC and non-ARC projects.
This was originally inspired by EMKeychain and SDKeychain (both of which are now gone). Thanks to the authors. SSKeychain has since switched to a simpler implementation that was abstracted from [SSToolkit](http://sstoolk.it).
@@ -9,6 +9,8 @@ This was originally inspired by EMKeychain and SDKeychain (both of which are now
1. Add `Security.framework` to your target
2. Add `SSKeychain.h` and `SSKeychain.m` to your project.
+You don't need to do anything regarding ARC. SSKeychain will detect if you're not using ARC and add the required memory management code.
+
Note: Currently SSKeychain does not support Mac OS 10.6.
## Working with the keychain
View
66 SSKeychain.m
@@ -47,15 +47,26 @@ + (NSArray *)accountsForService:(NSString *)service {
+ (NSArray *)accountsForService:(NSString *)service error:(NSError **)error {
OSStatus status = SSKeychainErrorBadArguments;
- CFArrayRef result = NULL;
NSMutableDictionary *query = [self _queryForService:service account:nil];
[query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes];
[query setObject:(id)kSecMatchLimitAll forKey:(id)kSecMatchLimit];
- status = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&result);
+
+ CFTypeRef result = NULL;
+#if __has_feature(objc_arc)
+ status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);
+#else
+ status = SecItemCopyMatching((CFDictionaryRef)query, &result);
+#endif
if (status != noErr && error != NULL) {
*error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil];
+ return nil;
}
+
+#if __has_feature(objc_arc)
+ return (__bridge_transfer NSArray *)result;
+#else
return [(NSArray *)result autorelease];
+#endif
}
@@ -68,7 +79,15 @@ + (NSString *)passwordForService:(NSString *)service account:(NSString *)account
+ (NSString *)passwordForService:(NSString *)service account:(NSString *)account error:(NSError **)error {
NSData *data = [self passwordDataForService:service account:account error:error];
- return ([data length]) ? [[[NSString alloc] initWithData:(NSData *)data encoding:NSUTF8StringEncoding] autorelease] : nil;
+ if (data.length > 0) {
+ NSString *string = [[NSString alloc] initWithData:(NSData *)data encoding:NSUTF8StringEncoding];
+#if !__has_feature(objc_arc)
+ [string autorelease];
+#endif
+ return string;
+ }
+
+ return nil;
}
@@ -79,19 +98,36 @@ + (NSData *)passwordDataForService:(NSString *)service account:(NSString *)accou
+ (NSData *)passwordDataForService:(NSString *)service account:(NSString *)account error:(NSError **)error {
OSStatus status = SSKeychainErrorBadArguments;
- NSData *result = nil;
- if (service && account) {
- NSMutableDictionary *query = [self _queryForService:service account:account];
- [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
- [query setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
- status = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&result);
+ if (!service || !account) {
+ if (error) {
+ *error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil];
+ }
+ return nil;
}
+
+ NSMutableDictionary *query = [self _queryForService:service account:account];
+ [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
+ [query setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
+ CFTypeRef result = NULL;
+#if __has_feature(objc_arc)
+ status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);
+#else
+ status = SecItemCopyMatching((CFDictionaryRef)query, &result);
+#endif
+
if (status != noErr && error != NULL) {
*error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil];
+ return nil;
}
- return [result autorelease];
+
+#if __has_feature(objc_arc)
+ return (__bridge_transfer NSData *)result;
+#else
+ return [(NSData *)result autorelease];
+#endif
}
+
#pragma mark - Deleting Passwords
+ (BOOL)deletePasswordForService:(NSString *)service account:(NSString *)account {
@@ -103,7 +139,11 @@ + (BOOL)deletePasswordForService:(NSString *)service account:(NSString *)account
OSStatus status = SSKeychainErrorBadArguments;
if (service && account) {
NSMutableDictionary *query = [self _queryForService:service account:account];
+#if __has_feature(objc_arc)
+ status = SecItemDelete((__bridge CFDictionaryRef)query);
+#else
status = SecItemDelete((CFDictionaryRef)query);
+#endif
}
if (status != noErr && error != NULL) {
*error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil];
@@ -144,7 +184,11 @@ + (BOOL)setPasswordData:(NSData *)password forService:(NSString *)service accoun
}
#endif
- status = SecItemAdd((CFDictionaryRef)query, NULL);
+#if __has_feature(objc_arc)
+ status = SecItemAdd((__bridge CFDictionaryRef)query, NULL);
+#else
+ status = SecItemAdd((CFDictionaryRef)query, NULL);
+#endif
}
if (status != noErr && error != NULL) {
*error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil];
View
104 Tests/SSKeychain.xcodeproj/project.pbxproj
@@ -7,6 +7,11 @@
objects = {
/* Begin PBXBuildFile section */
+ B2059B5D1559058C003D2FAC /* SSKeychainTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B2A5FACE143AC25C000F6011 /* SSKeychainTests.m */; };
+ B2059B5E1559058C003D2FAC /* SSKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = B25737E1143AC2EC003FACED /* SSKeychain.m */; };
+ B2059B601559058C003D2FAC /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B25737E4143AC308003FACED /* Security.framework */; };
+ B2059B611559058C003D2FAC /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2A5FAB1143AC134000F6011 /* SenTestingKit.framework */; };
+ B2059B621559058C003D2FAC /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2A5FA93143AC133000F6011 /* Cocoa.framework */; };
B25737E2143AC2EC003FACED /* SSKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = B25737E1143AC2EC003FACED /* SSKeychain.m */; };
B25737E5143AC308003FACED /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B25737E4143AC308003FACED /* Security.framework */; };
B2A5FAB2143AC134000F6011 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2A5FAB1143AC134000F6011 /* SenTestingKit.framework */; };
@@ -15,6 +20,8 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
+ B2059B681559058C003D2FAC /* SSKeychainTestsARC.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SSKeychainTestsARC.octest; sourceTree = BUILT_PRODUCTS_DIR; };
+ B2059B691559058C003D2FAC /* SSKeychainTestsARC-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "SSKeychainTestsARC-Info.plist"; path = "/Users/samsoffes/Code/sskeychain/Tests/SSKeychainTestsARC-Info.plist"; sourceTree = "<absolute>"; };
B25737E0143AC2EC003FACED /* SSKeychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SSKeychain.h; path = ../SSKeychain.h; sourceTree = "<group>"; };
B25737E1143AC2EC003FACED /* SSKeychain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SSKeychain.m; path = ../SSKeychain.m; sourceTree = "<group>"; };
B25737E4143AC308003FACED /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
@@ -29,6 +36,16 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
+ B2059B5F1559058C003D2FAC /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B2059B601559058C003D2FAC /* Security.framework in Frameworks */,
+ B2059B611559058C003D2FAC /* SenTestingKit.framework in Frameworks */,
+ B2059B621559058C003D2FAC /* Cocoa.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
B2A5FAAC143AC134000F6011 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -65,6 +82,7 @@
isa = PBXGroup;
children = (
B2A5FAB0143AC134000F6011 /* SSKeychainTests.octest */,
+ B2059B681559058C003D2FAC /* SSKeychainTestsARC.octest */,
);
name = Products;
sourceTree = "<group>";
@@ -95,13 +113,32 @@
children = (
B2A5FACE143AC25C000F6011 /* SSKeychainTests.m */,
B2A5FACC143AC25C000F6011 /* SSKeychainTests-Info.plist */,
+ B2059B691559058C003D2FAC /* SSKeychainTestsARC-Info.plist */,
);
path = SSKeychainTests;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
+ B2059B5B1559058C003D2FAC /* SSKeychainTestsARC */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = B2059B651559058C003D2FAC /* Build configuration list for PBXNativeTarget "SSKeychainTestsARC" */;
+ buildPhases = (
+ B2059B5C1559058C003D2FAC /* Sources */,
+ B2059B5F1559058C003D2FAC /* Frameworks */,
+ B2059B631559058C003D2FAC /* Resources */,
+ B2059B641559058C003D2FAC /* ShellScript */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = SSKeychainTestsARC;
+ productName = SSKeychainTests;
+ productReference = B2059B681559058C003D2FAC /* SSKeychainTestsARC.octest */;
+ productType = "com.apple.product-type.bundle";
+ };
B2A5FAAF143AC134000F6011 /* SSKeychainTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = B2A5FAC4143AC134000F6011 /* Build configuration list for PBXNativeTarget "SSKeychainTests" */;
@@ -142,11 +179,19 @@
projectRoot = "";
targets = (
B2A5FAAF143AC134000F6011 /* SSKeychainTests */,
+ B2059B5B1559058C003D2FAC /* SSKeychainTestsARC */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
+ B2059B631559058C003D2FAC /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
B2A5FAAD143AC134000F6011 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -157,6 +202,19 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
+ B2059B641559058C003D2FAC /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
+ };
B2A5FAAE143AC134000F6011 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -173,6 +231,15 @@
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
+ B2059B5C1559058C003D2FAC /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ B2059B5D1559058C003D2FAC /* SSKeychainTests.m in Sources */,
+ B2059B5E1559058C003D2FAC /* SSKeychain.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
B2A5FAAB143AC134000F6011 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -185,6 +252,32 @@
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
+ B2059B661559058C003D2FAC /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks";
+ INFOPLIST_FILE = "SSKeychainTestsARC-Info.plist";
+ PRODUCT_NAME = SSKeychainTestsARC;
+ RUN_CLANG_STATIC_ANALYZER = YES;
+ TEST_HOST = "$(BUNDLE_LOADER)";
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Debug;
+ };
+ B2059B671559058C003D2FAC /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks";
+ INFOPLIST_FILE = "SSKeychainTestsARC-Info.plist";
+ PRODUCT_NAME = SSKeychainTestsARC;
+ RUN_CLANG_STATIC_ANALYZER = YES;
+ TEST_HOST = "$(BUNDLE_LOADER)";
+ WRAPPER_EXTENSION = octest;
+ };
+ name = Release;
+ };
B2A5FABF143AC134000F6011 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -236,6 +329,7 @@
FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks";
INFOPLIST_FILE = "SSKeychainTests-Info.plist";
PRODUCT_NAME = "$(TARGET_NAME)";
+ RUN_CLANG_STATIC_ANALYZER = YES;
TEST_HOST = "$(BUNDLE_LOADER)";
WRAPPER_EXTENSION = octest;
};
@@ -247,6 +341,7 @@
FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks";
INFOPLIST_FILE = "SSKeychainTests-Info.plist";
PRODUCT_NAME = "$(TARGET_NAME)";
+ RUN_CLANG_STATIC_ANALYZER = YES;
TEST_HOST = "$(BUNDLE_LOADER)";
WRAPPER_EXTENSION = octest;
};
@@ -255,6 +350,15 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
+ B2059B651559058C003D2FAC /* Build configuration list for PBXNativeTarget "SSKeychainTestsARC" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ B2059B661559058C003D2FAC /* Debug */,
+ B2059B671559058C003D2FAC /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
B2A5FA89143AC133000F6011 /* Build configuration list for PBXProject "SSKeychain" */ = {
isa = XCConfigurationList;
buildConfigurations = (
View
22 Tests/SSKeychainTestsARC-Info.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.samsoffes.${PRODUCT_NAME:rfc1034identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+</dict>
+</plist>

0 comments on commit ca7ebbc

Please sign in to comment.