Compare commits

..

8 Commits

Author SHA1 Message Date
Matthew Palmer 80df919791 Merge pull request #108 from matthewpalmer/2.0.7
2.0.7
2016-02-14 18:24:59 +11:00
matthewpalmer 2f54712fda Bump podspec 2016-02-14 18:17:57 +11:00
matthewpalmer 78060ecc28 Add extra tests for new update method 2016-02-14 18:15:06 +11:00
Sergey Galezdinov e04d6291d4 Use SecItemUpdate function for updating the data. Added missing updateInSecureStore method to CreateableSecureStorable 2016-02-11 02:46:34 +03:00
Matthew Palmer c29ebcdba8 Merge pull request #102 from gilt/bitcode
full bitcode is needed for running Debug on an Apple TV device, even in Debug mode
2016-01-24 10:39:30 +11:00
Matthew Palmer ed56b9015c Merge pull request #101 from gilt/build_all_architectures
don't set ONLY_ACTIVE_ARCH to YES
2016-01-24 10:39:06 +11:00
Evan Maloney b5f7410d0e full bitcode is needed for running Debug on device
without this setting, it won't be possible to run a Debug build on the device; 'marker' only works in the sim
2016-01-22 14:24:00 -05:00
Evan Maloney e002690ccf don't set ONLY_ACTIVE_ARCH to YES
When embedding this project directly into another Xcode project in a target that:

• Is being built for a platform that has a simulator/device dichotomy (iOS, tvOS, watchOS), and
• Is inside a parent project building a Debug configuration

You will get one of two kinds of errors:

• Either the framework module itself is missing at the 'import' level, or
• Some or all of the framework's public symbols can't be found

The solution is to disable ONLY_ACTIVE_ARCH, which will ensure that both processor architectures are built and the symbols can be found.
2016-01-22 12:23:25 -05:00
4 changed files with 75 additions and 20 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "Locksmith"
s.version = "2.0.5"
s.version = "2.0.7"
s.summary = "Locksmith is a powerful, protocol-oriented library for working with the keychain in Swift."
s.description = <<-DESC
Locksmith is a powerful, protocol-oriented library for working with the iOS, Mac OS X, watchOS, and tvOS keychain in Swift. It provides extensive support for a lot of different keychain requests, and extensively uses Swift-native concepts.
+4 -1
View File
@@ -753,7 +753,6 @@
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = "";
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@@ -807,11 +806,13 @@
FBD0C94E1C1866BE00291F2A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BITCODE_GENERATION_MODE = bitcode;
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_BITCODE = YES;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = Source/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@@ -828,12 +829,14 @@
FBD0C94F1C1866BE00291F2A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BITCODE_GENERATION_MODE = bitcode;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_BITCODE = YES;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = Source/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+31 -8
View File
@@ -39,15 +39,14 @@ public struct Locksmith {
}
public static func updateData(data: [String: AnyObject], forUserAccount userAccount: String, inService service: String = LocksmithDefaultService) throws {
// Delete and then re-save
do {
try Locksmith.deleteDataForUserAccount(userAccount, inService: service)
} catch {
// Deletion is likely to fail if the piece of data doesn't exist yet.
// This doesn't matter--we only tell the user about errors on the save request.
struct UpdateRequest: GenericPasswordSecureStorable, CreateableSecureStorable {
let service: String
let account: String
let data: [String: AnyObject]
}
return try Locksmith.saveData(data, forUserAccount: userAccount, inService: service)
let request = UpdateRequest(service: service, account: userAccount, data: data)
try request.updateInSecureStore()
}
}
@@ -424,6 +423,7 @@ public protocol CreateableSecureStorable: SecureStorable {
var data: [String: AnyObject] { get }
var performCreateRequestClosure: PerformRequestClosureType { get }
func createInSecureStore() throws
func updateInSecureStore() throws
}
// MARK: - ReadableSecureStorable
@@ -509,6 +509,23 @@ public protocol DeleteableSecureStorable: SecureStorable {
// MARK: - Default property dictionaries
extension CreateableSecureStorable {
func updateInSecureStore(query: [String: AnyObject]) throws {
var attributesToUpdate = query
attributesToUpdate[String(kSecClass)] = nil
let status = SecItemUpdate(query, attributesToUpdate)
if let error = LocksmithError(fromStatusCode: Int(status)) {
throw error
}
if status != errSecSuccess {
throw LocksmithError.Undefined
}
}
}
public extension CreateableSecureStorable where Self : GenericPasswordSecureStorable {
var asCreateableSecureStoragePropertyDictionary: [String: AnyObject] {
var old = genericPasswordBaseStoragePropertyDictionary
@@ -521,6 +538,9 @@ public extension CreateableSecureStorable where Self : GenericPasswordSecureStor
func createInSecureStore() throws {
try performSecureStorageAction(performCreateRequestClosure, secureStoragePropertyDictionary: asCreateableSecureStoragePropertyDictionary)
}
func updateInSecureStore() throws {
try self.updateInSecureStore(self.asCreateableSecureStoragePropertyDictionary)
}
}
public extension CreateableSecureStorable where Self : InternetPasswordSecureStorable {
@@ -543,6 +563,9 @@ public extension CreateableSecureStorable where Self : InternetPasswordSecureSto
func createInSecureStore() throws {
try performSecureStorageAction(performCreateRequestClosure, secureStoragePropertyDictionary: asCreateableSecureStoragePropertyDictionary)
}
func updateInSecureStore() throws {
try self.updateInSecureStore(self.asCreateableSecureStoragePropertyDictionary)
}
}
public extension DeleteableSecureStorable {
+39 -10
View File
@@ -94,6 +94,24 @@ class LocksmithTests: XCTestCase {
createGenericPasswordWithData(data)
}
func testUpdateForGenericPassword() {
let data = ["some": "data"]
struct CreateGenericPassword: CreateableSecureStorable, GenericPasswordSecureStorable, ReadableSecureStorable {
var data: [String: AnyObject]
let account: String
let service: String
}
var create = CreateGenericPassword(data: data, account: userAccount, service: service)
try! create.createInSecureStore() // make sure it doesn't throw
create.data = ["other": "data"]
try! create.updateInSecureStore()
let read = create.readFromSecureStore()!.data as! [String: String]
XCTAssertEqual(read, ["other": "data"])
}
func testLoadForGenericPassword() {
let data = ["one": "two"]
createGenericPasswordWithData(data)
@@ -239,7 +257,7 @@ class LocksmithTests: XCTestCase {
func testInternetPasswordMetaAttributesAreCreatedAndReturned() {
struct CreateInternetPassword: CreateableSecureStorable, InternetPasswordSecureStorable {
let account: String
let data: [String: AnyObject]
var data: [String: AnyObject]
let server: String
let port: Int
let internetProtocol: LocksmithInternetProtocol
@@ -265,20 +283,31 @@ class LocksmithTests: XCTestCase {
let authenticationType: LocksmithInternetAuthenticationType
}
let c = CreateInternetPassword(account: userAccount, data: initialData, server: server, port: port, internetProtocol: internetProtocol, authenticationType: authenticationType, path: path, securityDomain: securityDomain)
var c = CreateInternetPassword(account: userAccount, data: initialData, server: server, port: port, internetProtocol: internetProtocol, authenticationType: authenticationType, path: path, securityDomain: securityDomain)
try! c.createInSecureStore()
func assertResultMetadataIsOk(result: InternetPasswordSecureStorableResultType?) {
XCTAssertEqual(result?.account, userAccount)
XCTAssertEqual(result?.server, server)
XCTAssertEqual(result?.port, port)
XCTAssertEqual(result?.internetProtocol, internetProtocol)
XCTAssertEqual(result?.authenticationType, authenticationType)
XCTAssertEqual(result?.securityDomain, securityDomain)
XCTAssertEqual(result?.path, path)
}
let r = ReadInternetPassword(account: userAccount, server: server, port: port, internetProtocol: internetProtocol, authenticationType: authenticationType)
let result = r.readFromSecureStore()
XCTAssertEqual(result?.account, userAccount)
XCTAssertEqual(result!.data as! [String: String], initialData)
XCTAssertEqual(result?.server, server)
XCTAssertEqual(result?.port, port)
XCTAssertEqual(result?.internetProtocol, internetProtocol)
XCTAssertEqual(result?.authenticationType, authenticationType)
XCTAssertEqual(result?.securityDomain, securityDomain)
XCTAssertEqual(result?.path, path)
assertResultMetadataIsOk(result)
// Assert that metadata is maintained after an update
c.data = ["other internet": "junk"]
try! c.updateInSecureStore()
let result2 = r.readFromSecureStore()
XCTAssertEqual(result2!.data as! [String: String], ["other internet": "junk"])
assertResultMetadataIsOk(result2)
}
func assertStringPairsMatchInDictionary(dictionary: NSDictionary, pairs: [(key: CFString, expectedOutput: String)]) {