Compare commits

..

39 Commits

Author SHA1 Message Date
matthewpalmer 49b08bf8fa Bump to version 4.0 in ancillary files 2017-09-30 21:02:25 -04:00
matthewpalmer a664da8f3e Bump version for Swift 4 2017-09-30 21:01:18 -04:00
matthewpalmer fab50b777e Attempt fix at #181 2017-09-30 20:58:16 -04:00
Evan Maloney d2c3db9ca8 set APPLICATION_EXTENSION_API_ONLY for unit tests
unit tests don't need APPLICATION_EXTENSION_API_ONLY set to yes; in fact, doing so causes this compiler warning in Xcode 9:

ld: warning: linking against a dylib which is not safe for use in application extensions: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator/libswiftXCTest.dylib
2017-09-20 17:17:04 +01:00
Evan Maloney ffc5ade402 Swift 4 updates 2017-09-20 17:11:13 +01:00
Evan Maloney aa0707a3b0 update build settings per suggestions from Xcode 9 2017-09-20 16:42:55 +01:00
Evan Maloney f4c59ec551 fix redundant conformance constraint warnings
these occur under Xcode 9
2017-09-20 16:37:55 +01:00
Matthew Palmer 65e4d5ad62 Merge pull request #166 from diejmon/master
Add SPM support
2016-12-28 14:25:47 +11:00
Alexander Belyavskiy 66c2cce0c9 Add SPM support 2016-12-26 11:43:15 +03:00
Matthew Palmer bcb1a269d6 Merge pull request #160 from Fuxxel/fix/readme
README has setup section (Keychain Sharing)
2016-11-09 19:30:34 +11:00
Marvin e35ae01309 Added setup section in README.md 2016-11-08 18:49:50 +01:00
matthewpalmer b80a90c104 Add swift version file 2016-09-17 15:26:53 +10:00
matthewpalmer ee3b4e3584 Bump swift migration version 2016-09-17 13:42:44 +10:00
matthewpalmer 861c054729 Update podspec for Swift 3 2016-09-17 13:37:12 +10:00
matthewpalmer 3a97bd9e80 Merge branch 'swift-3.0'
* swift-3.0:
  Update .travis.yml
  [Travis] disable pod linting for watchOS 2 configuration
  Set Test Host deployment target to 8.0
  Update project for Xcode 8 GM
  Enums with lowercase
  Adapted naming of enums according to swift 3 rules.
  Updates for Xcode beta 4
  Update for Xcode beta 2
  Updated for Swift 3.0
2016-09-17 13:33:13 +10:00
Matthew Palmer 1039eedb31 Merge pull request #142 from fedetrim/swift-3.0
Swift 3.0 and Xcode 8 GM support
2016-09-14 19:37:19 +10:00
Federico Trimboli 23c4eff1bf Update .travis.yml 2016-09-10 11:40:53 -03:00
Federico Trimboli 096285a39f [Travis] disable pod linting for watchOS 2 configuration 2016-09-10 10:31:51 -03:00
Federico Trimboli 27e8863baa Set Test Host deployment target to 8.0 2016-09-10 10:15:16 -03:00
Federico Trimboli 06fbc41df5 Update project for Xcode 8 GM 2016-09-10 09:52:19 -03:00
Pascal Freiburghaus 818938df81 Enums with lowercase 2016-08-25 22:45:59 +02:00
Pascal Freiburghaus ca96ace5d0 Adapted naming of enums according to swift 3 rules. 2016-08-25 13:55:28 +02:00
Matthew Palmer 9613c8fd22 Update README.md 2016-08-19 13:28:08 +10:00
matthewpalmer f2269ef8d1 Update rocket link 2016-08-13 11:58:01 +10:00
matthewpalmer 4d00c74922 Add padding symbols 2016-08-13 11:56:33 +10:00
matthewpalmer 1e8fcc8c2c Add spacing over heading for rocket section 2016-08-13 11:53:55 +10:00
matthewpalmer 9e1e912788 Update rocket link position and style 2016-08-13 11:53:13 +10:00
matthewpalmer c6838a31f2 Add link to Rocket to README 2016-08-13 11:44:55 +10:00
Matthew Palmer 70369178ec Merge pull request #133 from warren-gavin/swift-3.0
Updates for Xcode beta 4
2016-08-06 14:36:53 +10:00
Warren Gavin 6e15b6ee42 Updates for Xcode beta 4 2016-08-02 12:31:18 +02:00
Matthew Palmer 5055c8997e Merge pull request #131 from edwellbrook/swift-3.0
Update for Xcode beta 2
2016-08-01 05:44:30 +10:00
Ed Wellbrook 8744bef07c Update for Xcode beta 2 2016-07-10 23:59:56 +01:00
Matthew Palmer cdd1b2893a Merge pull request #127 from Podfactor/app-extension-safe
Fix warning when linking against Locksmith from an app extension
2016-07-09 06:38:03 +10:00
matthewpalmer 67ded45500 Merge branch 'jenseickmeyer-swift-3.0' into swift-3.0
* jenseickmeyer-swift-3.0:
  Updated for Swift 3.0
2016-07-09 06:36:50 +10:00
Jens Eickmeyer dd159e10a7 Updated for Swift 3.0
Basic adjustments for supporting Swift 3.0. All tests are running.
2016-06-25 07:03:13 +02:00
Tom Brow 7b9237c39e build with APPLICATION_EXTENSION_API_ONLY = YES 2016-05-31 17:25:45 -05:00
Matthew Palmer 1b278e59a5 Merge pull request #118 from jakemarsh/master
Carthage doesn't allow single quotes. Change README to doubles.
2016-04-09 13:25:19 +10:00
Jake Marsh 1359edf840 Update README.md
Carthage doesn't allow single quotes. Change to doubles.
2016-04-06 19:24:58 -07:00
matthewpalmer 6b32c7ec68 Fix regression in update method to fix #110 2016-02-16 20:23:02 +11:00
36 changed files with 1138 additions and 297 deletions
+1
View File
@@ -33,3 +33,4 @@ DerivedData
.idea/
# Pods - for those of you who use CocoaPods
Pods
/.build
+1
View File
@@ -0,0 +1 @@
3.0
+19 -13
View File
@@ -1,23 +1,29 @@
# Taken from https://github.com/Alamofire/AlamofireImage
language: objective-c
osx_image: xcode7
osx_image: xcode8
env:
global:
- LC_CTYPE=en_US.UTF-8
- LANG=en_US.UTF-8
matrix:
- DESTINATION="OS=2.0,name=Apple Watch - 42mm" SCHEME="Locksmith watchOS" SDK=watchsimulator2.0 RUN_TESTS="NO" BUILD_EXAMPLE="NO" POD_LINT="YES"
- DESTINATION="arch=x86_64" SCHEME="Locksmith OS X" SDK=macosx10.11 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
- DESTINATION="OS=3.0,name=Apple Watch - 42mm" SCHEME="Locksmith watchOS" SDK=watchsimulator3.0 RUN_TESTS="NO" BUILD_EXAMPLE="NO" POD_LINT="YES"
- DESTINATION="OS=2.0,name=Apple Watch - 42mm" SCHEME="Locksmith watchOS" SDK=watchsimulator3.0 RUN_TESTS="NO" BUILD_EXAMPLE="NO" POD_LINT="NO"
- DESTINATION="arch=x86_64" SCHEME="Locksmith OS X" SDK=macosx10.12 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
# "build_example" should be YES but travis was giving me grief
- DESTINATION="OS=9.0,name=iPad 2" SCHEME="Locksmith iOS" SDK=iphonesimulator9.0 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
- DESTINATION="OS=9.0,name=iPhone 6" SCHEME="Locksmith iOS" SDK=iphonesimulator9.0 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
- DESTINATION="OS=9.0,name=iPhone 6 Plus" SCHEME="Locksmith iOS" SDK=iphonesimulator9.0 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
- DESTINATION="OS=10.0,name=iPad Air 2" SCHEME="Locksmith iOS" SDK=iphonesimulator10.0 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
- DESTINATION="OS=10.0,name=iPhone 7" SCHEME="Locksmith iOS" SDK=iphonesimulator10.0 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
- DESTINATION="OS=10.0,name=iPhone 7 Plus" SCHEME="Locksmith iOS" SDK=iphonesimulator10.0 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
- DESTINATION="OS=8.1,name=iPad 2" SCHEME="Locksmith iOS" SDK=iphonesimulator9.0 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
- DESTINATION="OS=8.2,name=iPhone 4S" SCHEME="Locksmith iOS" SDK=iphonesimulator9.0 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
- DESTINATION="OS=8.3,name=iPhone 5" SCHEME="Locksmith iOS" SDK=iphonesimulator9.0 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
- DESTINATION="OS=8.4,name=iPhone 5S" SCHEME="Locksmith iOS" SDK=iphonesimulator9.0 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
- DESTINATION="OS=9.0,name=iPad 2" SCHEME="Locksmith iOS" SDK=iphonesimulator10.0 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
- DESTINATION="OS=9.0,name=iPhone 6" SCHEME="Locksmith iOS" SDK=iphonesimulator10.0 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
- DESTINATION="OS=9.0,name=iPhone 6 Plus" SCHEME="Locksmith iOS" SDK=iphonesimulator10.0 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
- DESTINATION="OS=8.1,name=iPad 2" SCHEME="Locksmith iOS" SDK=iphonesimulator10.0 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
- DESTINATION="OS=8.2,name=iPhone 4S" SCHEME="Locksmith iOS" SDK=iphonesimulator10.0 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
- DESTINATION="OS=8.3,name=iPhone 5" SCHEME="Locksmith iOS" SDK=iphonesimulator10.0 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
- DESTINATION="OS=8.4,name=iPhone 5S" SCHEME="Locksmith iOS" SDK=iphonesimulator10.0 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
before_install:
- gem install cocoapods --no-rdoc --no-ri --no-document --quiet
- gem install xcpretty --no-rdoc --no-ri --no-document --quiet
@@ -46,11 +52,11 @@ script:
fi
# Build example in Debug and Release
- if [ $BUILD_EXAMPLE == "YES" ]; then
- if [ $BUILD_EXAMPLE == "YES" ]; then
xcodebuild -workspace Locksmith.xcworkspace -scheme "Locksmith iOS Example" -sdk "$SDK" -destination "$DESTINATION"
-configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty -c;
fi
- if [ $BUILD_EXAMPLE == "YES" ]; then
- if [ $BUILD_EXAMPLE == "YES" ]; then
xcodebuild -workspace Locksmith.xcworkspace -scheme "Locksmith iOS Example" -sdk "$SDK" -destination "$DESTINATION"
-configuration Release ONLY_ACTIVE_ARCH=NO build | xcpretty -c;
fi
@@ -58,4 +64,4 @@ script:
# Run pod lib lint quick if specified
- if [ $POD_LINT == "YES" ]; then
pod lib lint --quick;
fi
fi
@@ -17,9 +17,9 @@ class InterfaceController: WKInterfaceController, WCSessionDelegate {
super.willActivate()
if (WCSession.isSupported()) {
let session = WCSession.defaultSession()
let session = WCSession.default()
session.delegate = self
session.activateSession()
session.activate()
}
struct TwitterAccount: ReadableSecureStorable, CreateableSecureStorable, DeleteableSecureStorable, GenericPasswordSecureStorable {
@@ -30,7 +30,7 @@ class InterfaceController: WKInterfaceController, WCSessionDelegate {
var account: String { return username }
var data: [String: AnyObject] {
var data: [String: Any] {
return ["password": password]
}
}
@@ -48,4 +48,8 @@ class InterfaceController: WKInterfaceController, WCSessionDelegate {
// DeleteableSecureStorable lets us delete the account from the keychain
try! account.deleteFromSecureStore()
}
@available(watchOSApplicationExtension 2.2, *)
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
}
}
@@ -98,6 +98,12 @@
379DD1E5C8CDE5ABD6E50A38 /* Pods-watch.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-watch.release.xcconfig"; path = "Pods/Target Support Files/Pods-watch/Pods-watch.release.xcconfig"; sourceTree = "<group>"; };
74E67F961D2CBE4F8D171223 /* Pods-watch.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-watch.debug.xcconfig"; path = "Pods/Target Support Files/Pods-watch/Pods-watch.debug.xcconfig"; sourceTree = "<group>"; };
8D5C601685F38F2EA6AA2CA0 /* Pods-app.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app.release.xcconfig"; path = "Pods/Target Support Files/Pods-app/Pods-app.release.xcconfig"; sourceTree = "<group>"; };
E3DD3B201D84354F00A59312 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
E3DD3B221D84354F00A59312 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
E3DD3B251D84354F00A59312 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
E3DD3B271D84354F00A59312 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
E3DD3B2A1D84354F00A59312 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
E3DD3B2C1D84354F00A59312 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
FFB6EBF2507E751B53E55514 /* Pods-app.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-app.debug.xcconfig"; path = "Pods/Target Support Files/Pods-app/Pods-app.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -148,6 +154,7 @@
0E13A9A21BA3EE8700A06FF9 /* Locksmith iOS Example */,
056F2A701BA42E3C00B24B65 /* Locksmith */,
056F2A7F1BA42E3C00B24B65 /* Locksmith Extension */,
E3DD3B1F1D84354F00A59312 /* Test Host */,
0E13A9A11BA3EE8700A06FF9 /* Products */,
74B88A8534E794C2027D6B3D /* Pods */,
D1E3110F9ED1A0EE737E7A37 /* Frameworks */,
@@ -199,6 +206,19 @@
name = Frameworks;
sourceTree = "<group>";
};
E3DD3B1F1D84354F00A59312 /* Test Host */ = {
isa = PBXGroup;
children = (
E3DD3B201D84354F00A59312 /* AppDelegate.swift */,
E3DD3B221D84354F00A59312 /* ViewController.swift */,
E3DD3B241D84354F00A59312 /* Main.storyboard */,
E3DD3B271D84354F00A59312 /* Assets.xcassets */,
E3DD3B291D84354F00A59312 /* LaunchScreen.storyboard */,
E3DD3B2C1D84354F00A59312 /* Info.plist */,
);
path = "Test Host";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -262,7 +282,8 @@
0E13A9981BA3EE8600A06FF9 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0700;
LastSwiftUpdateCheck = 0800;
LastUpgradeCheck = 0900;
ORGANIZATIONNAME = "Matthew Palmer";
TargetAttributes = {
056F2A6E1BA42E3C00B24B65 = {
@@ -385,14 +406,30 @@
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
E3DD3B241D84354F00A59312 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
E3DD3B251D84354F00A59312 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
E3DD3B291D84354F00A59312 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
E3DD3B2A1D84354F00A59312 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
056F2A8A1BA42E3C00B24B65 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
IBSC_MODULE = Locksmith_Extension;
INFOPLIST_FILE = Locksmith/Info.plist;
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-iOS-Example.watchkitapp";
@@ -407,8 +444,8 @@
056F2A8B1BA42E3C00B24B65 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
IBSC_MODULE = Locksmith_Extension;
INFOPLIST_FILE = Locksmith/Info.plist;
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-iOS-Example.watchkitapp";
@@ -430,6 +467,7 @@
PRODUCT_NAME = "${TARGET_NAME}";
SDKROOT = watchos;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 2.0;
};
@@ -445,6 +483,8 @@
PRODUCT_NAME = "${TARGET_NAME}";
SDKROOT = watchos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 2.0;
};
@@ -458,13 +498,21 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -503,13 +551,21 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -528,6 +584,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
@@ -543,6 +600,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-iOS-Example";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
@@ -556,6 +614,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-iOS-Example";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
};
name = Release;
};
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0720"
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
@@ -45,6 +46,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
@@ -12,8 +12,8 @@ import Locksmith
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
struct TwitterAccount: ReadableSecureStorable, CreateableSecureStorable, DeleteableSecureStorable, GenericPasswordSecureStorable {
let username: String
let password: String
@@ -22,7 +22,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var account: String { return username }
var data: [String: AnyObject] {
var data: [String: Any] {
return ["password": password]
}
}
@@ -0,0 +1,46 @@
//
// AppDelegate.swift
// Test Host
//
// Created by Federico Trimboli on 9/10/16.
// Copyright © 2016 Matthew Palmer. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
@@ -0,0 +1,68 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11134" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11106"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11134" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11106"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
@@ -0,0 +1,45 @@
<?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>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
@@ -0,0 +1,25 @@
//
// ViewController.swift
// Test Host
//
// Created by Federico Trimboli on 9/10/16.
// Copyright © 2016 Matthew Palmer. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "Locksmith"
s.version = "2.0.7"
s.version = "4.0.0"
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.
+227 -3
View File
@@ -35,6 +35,11 @@
DF6BD4B91BB0524500A3EB64 /* Locksmith.h in Headers */ = {isa = PBXBuildFile; fileRef = DF6BD4B61BB051ED00A3EB64 /* Locksmith.h */; settings = {ATTRIBUTES = (Public, ); }; };
DF6BD4BC1BB054CB00A3EB64 /* Locksmith.h in Headers */ = {isa = PBXBuildFile; fileRef = DF6BD4B61BB051ED00A3EB64 /* Locksmith.h */; settings = {ATTRIBUTES = (Public, ); }; };
DF6BD4BD1BB054D400A3EB64 /* Locksmith.h in Headers */ = {isa = PBXBuildFile; fileRef = DF6BD4B61BB051ED00A3EB64 /* Locksmith.h */; settings = {ATTRIBUTES = (Public, ); }; };
E3DD3B371D84356600A59312 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3DD3B361D84356500A59312 /* AppDelegate.swift */; };
E3DD3B391D84356600A59312 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3DD3B381D84356600A59312 /* ViewController.swift */; };
E3DD3B3C1D84356600A59312 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E3DD3B3A1D84356600A59312 /* Main.storyboard */; };
E3DD3B3E1D84356600A59312 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E3DD3B3D1D84356600A59312 /* Assets.xcassets */; };
E3DD3B411D84356600A59312 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E3DD3B3F1D84356600A59312 /* LaunchScreen.storyboard */; };
FBD0C9511C18693200291F2A /* Dictionary_Initializers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C401BA38539004191AF /* Dictionary_Initializers.swift */; };
FBD0C9521C18693900291F2A /* Locksmith.h in Headers */ = {isa = PBXBuildFile; fileRef = DF6BD4B61BB051ED00A3EB64 /* Locksmith.h */; settings = {ATTRIBUTES = (Public, ); }; };
FBD0C9531C18694100291F2A /* Locksmith.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C421BA38539004191AF /* Locksmith.swift */; };
@@ -60,6 +65,13 @@
remoteGlobalIDString = 0EC25C741BA385F6004191AF;
remoteInfo = "Locksmith OS X";
};
E3DD3B471D84360300A59312 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = BFFB19C71A4870A300CCFFC3 /* Project object */;
proxyType = 1;
remoteGlobalIDString = E3DD3B331D84356500A59312;
remoteInfo = "Test Host";
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
@@ -70,7 +82,7 @@
0EC25C451BA38539004191AF /* LocksmithInternetAuthenticationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocksmithInternetAuthenticationType.swift; sourceTree = "<group>"; };
0EC25C461BA38539004191AF /* LocksmithInternetProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocksmithInternetProtocol.swift; sourceTree = "<group>"; };
0EC25C471BA38539004191AF /* LocksmithSecurityClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocksmithSecurityClass.swift; sourceTree = "<group>"; };
0EC25C491BA38539004191AF /* LocksmithTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocksmithTests.swift; sourceTree = "<group>"; };
0EC25C491BA38539004191AF /* LocksmithTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LocksmithTests.swift; path = LocksmithTests/LocksmithTests.swift; sourceTree = "<group>"; };
0EC25C591BA385AA004191AF /* Locksmith.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Locksmith.framework; sourceTree = BUILT_PRODUCTS_DIR; };
0EC25C621BA385AB004191AF /* Locksmith iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Locksmith iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
0EC25C751BA385F6004191AF /* Locksmith.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Locksmith.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -79,6 +91,14 @@
0EC25C9E1BA389CB004191AF /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
0EC25CA71BA39C9F004191AF /* Locksmith.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Locksmith.framework; sourceTree = BUILT_PRODUCTS_DIR; };
DF6BD4B61BB051ED00A3EB64 /* Locksmith.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Locksmith.h; sourceTree = "<group>"; };
E3DD3B341D84356500A59312 /* Test Host.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Test Host.app"; sourceTree = BUILT_PRODUCTS_DIR; };
E3DD3B361D84356500A59312 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
E3DD3B381D84356600A59312 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
E3DD3B3B1D84356600A59312 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
E3DD3B3D1D84356600A59312 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
E3DD3B401D84356600A59312 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
E3DD3B421D84356600A59312 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
E3DD3B461D84358100A59312 /* Test Host.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Test Host.entitlements"; sourceTree = "<group>"; };
FBD0C9491C1866BE00291F2A /* Locksmith.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Locksmith.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
@@ -120,6 +140,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
E3DD3B311D84356500A59312 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
FBD0C9451C1866BE00291F2A /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -176,6 +203,7 @@
children = (
0EC25C481BA38539004191AF /* Source */,
0EC25C4A1BA38539004191AF /* Tests */,
E3DD3B351D84356500A59312 /* Test Host */,
BFFB19D11A4870A300CCFFC3 /* Products */,
);
sourceTree = "<group>";
@@ -189,10 +217,25 @@
0EC25C7E1BA385F6004191AF /* Locksmith OS X Tests.xctest */,
0EC25CA71BA39C9F004191AF /* Locksmith.framework */,
FBD0C9491C1866BE00291F2A /* Locksmith.framework */,
E3DD3B341D84356500A59312 /* Test Host.app */,
);
name = Products;
sourceTree = "<group>";
};
E3DD3B351D84356500A59312 /* Test Host */ = {
isa = PBXGroup;
children = (
E3DD3B461D84358100A59312 /* Test Host.entitlements */,
E3DD3B361D84356500A59312 /* AppDelegate.swift */,
E3DD3B381D84356600A59312 /* ViewController.swift */,
E3DD3B3A1D84356600A59312 /* Main.storyboard */,
E3DD3B3D1D84356600A59312 /* Assets.xcassets */,
E3DD3B3F1D84356600A59312 /* LaunchScreen.storyboard */,
E3DD3B421D84356600A59312 /* Info.plist */,
);
path = "Test Host";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@@ -261,6 +304,7 @@
);
dependencies = (
0EC25C651BA385AB004191AF /* PBXTargetDependency */,
E3DD3B481D84360300A59312 /* PBXTargetDependency */,
);
name = "Locksmith iOS Tests";
productName = "Locksmith iOSTests";
@@ -321,6 +365,23 @@
productReference = 0EC25CA71BA39C9F004191AF /* Locksmith.framework */;
productType = "com.apple.product-type.framework";
};
E3DD3B331D84356500A59312 /* Test Host */ = {
isa = PBXNativeTarget;
buildConfigurationList = E3DD3B451D84356600A59312 /* Build configuration list for PBXNativeTarget "Test Host" */;
buildPhases = (
E3DD3B301D84356500A59312 /* Sources */,
E3DD3B311D84356500A59312 /* Frameworks */,
E3DD3B321D84356500A59312 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "Test Host";
productName = "Test Host";
productReference = E3DD3B341D84356500A59312 /* Test Host.app */;
productType = "com.apple.product-type.application";
};
FBD0C9481C1866BE00291F2A /* Locksmith tvOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = FBD0C9501C1866BE00291F2A /* Build configuration list for PBXNativeTarget "Locksmith tvOS" */;
@@ -345,15 +406,18 @@
BFFB19C71A4870A300CCFFC3 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0720;
LastSwiftUpdateCheck = 0800;
LastUpgradeCheck = 0900;
ORGANIZATIONNAME = "Mathew Palmer";
TargetAttributes = {
0EC25C581BA385AA004191AF = {
CreatedOnToolsVersion = 7.0;
LastSwiftMigration = 0900;
};
0EC25C611BA385AB004191AF = {
CreatedOnToolsVersion = 7.0;
LastSwiftMigration = 0900;
TestTargetID = E3DD3B331D84356500A59312;
};
0EC25C741BA385F6004191AF = {
CreatedOnToolsVersion = 7.0;
@@ -364,6 +428,16 @@
0EC25CA61BA39C9F004191AF = {
CreatedOnToolsVersion = 7.0;
};
E3DD3B331D84356500A59312 = {
CreatedOnToolsVersion = 8.0;
LastSwiftMigration = 0900;
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.Keychain = {
enabled = 1;
};
};
};
FBD0C9481C1866BE00291F2A = {
CreatedOnToolsVersion = 7.2;
};
@@ -375,6 +449,7 @@
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = BFFB19C61A4870A300CCFFC3;
productRefGroup = BFFB19D11A4870A300CCFFC3 /* Products */;
@@ -387,6 +462,7 @@
0EC25C7D1BA385F6004191AF /* Locksmith OS X Tests */,
0EC25CA61BA39C9F004191AF /* Locksmith watchOS */,
FBD0C9481C1866BE00291F2A /* Locksmith tvOS */,
E3DD3B331D84356500A59312 /* Test Host */,
);
};
/* End PBXProject section */
@@ -427,6 +503,16 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
E3DD3B321D84356500A59312 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E3DD3B411D84356600A59312 /* LaunchScreen.storyboard in Resources */,
E3DD3B3E1D84356600A59312 /* Assets.xcassets in Resources */,
E3DD3B3C1D84356600A59312 /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
FBD0C9471C1866BE00291F2A /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -495,6 +581,15 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
E3DD3B301D84356500A59312 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E3DD3B391D84356600A59312 /* ViewController.swift in Sources */,
E3DD3B371D84356600A59312 /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
FBD0C9441C1866BE00291F2A /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -522,12 +617,37 @@
target = 0EC25C741BA385F6004191AF /* Locksmith OS X */;
targetProxy = 0EC25C801BA385F6004191AF /* PBXContainerItemProxy */;
};
E3DD3B481D84360300A59312 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = E3DD3B331D84356500A59312 /* Test Host */;
targetProxy = E3DD3B471D84360300A59312 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
E3DD3B3A1D84356600A59312 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
E3DD3B3B1D84356600A59312 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
E3DD3B3F1D84356600A59312 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
E3DD3B401D84356600A59312 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
0EC25C6B1BA385AB004191AF /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -542,12 +662,14 @@
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-iOS";
PRODUCT_NAME = Locksmith;
SKIP_INSTALL = YES;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
0EC25C6C1BA385AB004191AF /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
@@ -562,12 +684,15 @@
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-iOS";
PRODUCT_NAME = Locksmith;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.0;
};
name = Release;
};
0EC25C6E1BA385AB004191AF /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_TESTABILITY = YES;
GCC_NO_COMMON_BLOCKS = YES;
@@ -576,12 +701,15 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-iOSTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Test Host.app/Test Host";
};
name = Debug;
};
0EC25C6F1BA385AB004191AF /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_NO_COMMON_BLOCKS = YES;
@@ -590,6 +718,9 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-iOSTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Test Host.app/Test Host";
};
name = Release;
};
@@ -613,6 +744,7 @@
PRODUCT_NAME = Locksmith;
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
};
name = Debug;
};
@@ -636,12 +768,15 @@
PRODUCT_NAME = Locksmith;
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
};
name = Release;
};
0EC25C8A1BA385F6004191AF /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
COMBINE_HIDPI_IMAGES = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_TESTABILITY = YES;
@@ -652,12 +787,14 @@
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-OS-XTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_VERSION = 3.0;
};
name = Debug;
};
0EC25C8B1BA385F6004191AF /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
@@ -668,12 +805,15 @@
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-OS-XTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
};
name = Release;
};
0EC25CAC1BA39CA0004191AF /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -687,6 +827,7 @@
PRODUCT_NAME = Locksmith;
SDKROOT = watchos;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 2.0;
};
@@ -695,6 +836,7 @@
0EC25CAD1BA39CA0004191AF /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
@@ -709,6 +851,8 @@
PRODUCT_NAME = Locksmith;
SDKROOT = watchos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 2.0;
};
@@ -718,17 +862,26 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -738,6 +891,7 @@
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
@@ -753,6 +907,7 @@
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";
@@ -766,17 +921,26 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -785,6 +949,7 @@
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
@@ -803,10 +968,56 @@
};
name = Release;
};
E3DD3B431D84356600A59312 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ANALYZER_NONNULL = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
CODE_SIGN_ENTITLEMENTS = "Test Host/Test Host.entitlements";
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "Test Host/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Test-Host";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
E3DD3B441D84356600A59312 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ANALYZER_NONNULL = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_SUSPICIOUS_MOVES = YES;
CODE_SIGN_ENTITLEMENTS = "Test Host/Test Host.entitlements";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "Test Host/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Test-Host";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.0;
};
name = Release;
};
FBD0C94E1C1866BE00291F2A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BITCODE_GENERATION_MODE = bitcode;
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -821,6 +1032,7 @@
PRODUCT_NAME = Locksmith;
SDKROOT = appletvos;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = 3;
TVOS_DEPLOYMENT_TARGET = 9.0;
};
@@ -830,6 +1042,7 @@
isa = XCBuildConfiguration;
buildSettings = {
BITCODE_GENERATION_MODE = bitcode;
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
@@ -845,6 +1058,8 @@
PRODUCT_NAME = Locksmith;
SDKROOT = appletvos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = 3;
TVOS_DEPLOYMENT_TARGET = 9.0;
};
@@ -907,6 +1122,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
E3DD3B451D84356600A59312 /* Build configuration list for PBXNativeTarget "Test Host" */ = {
isa = XCConfigurationList;
buildConfigurations = (
E3DD3B431D84356600A59312 /* Debug */,
E3DD3B441D84356600A59312 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
FBD0C9501C1866BE00291F2A /* Build configuration list for PBXNativeTarget "Locksmith tvOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0720"
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
@@ -55,6 +56,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0720"
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
@@ -55,6 +56,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0720"
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
@@ -36,6 +37,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0720"
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
@@ -36,6 +37,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
+5
View File
@@ -0,0 +1,5 @@
import PackageDescription
let package = Package(
name: "Locksmith"
)
+22 -5
View File
@@ -7,6 +7,14 @@ A powerful, protocol-oriented library for working with the keychain in Swift.
- [x] ⌚️ watchOS 2
- [x] 📺 tvOS
> &nbsp;
>
> 🚀 I make [Rocket](http://matthewpalmer.net/rocket?utm_source=locksmith&utm_medium=readme&utm_campaign=open_source), an app that gives you Slack-style emoji everywhere on your Mac.
>
> &nbsp;
## Details
How is Locksmith different to other keychain wrappers?
* Locksmiths API is both super-simple and deeply powerful
@@ -22,6 +30,8 @@ How is Locksmith different to other keychain wrappers?
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
[![Build Status](https://travis-ci.org/matthewpalmer/Locksmith.svg?branch=master)](https://travis-ci.org/matthewpalmer/Locksmith)
* Locksmith 4.0 and greater is Swift 4 compatible. See the `swift-3.1` branch for compatibility with older versions of Swift.
### CocoaPods
Locksmith is available through [CocoaPods](http://cocoapods.org).
@@ -32,10 +42,17 @@ Locksmith is available through [CocoaPods](http://cocoapods.org).
Locksmith is available through [Carthage](https://github.com/Carthage/Carthage).
github 'matthewpalmer/Locksmith'
github "matthewpalmer/Locksmith"
## Quick start
### **Setup**
1. Choose your target project
2. Select Capabilties
3. Enable Keychain Sharing
Xcode then automatically creates a .entitlements file and you are ready to use Locksmith!
**Save data**
```swift
@@ -107,7 +124,7 @@ Creating, reading, and deleting each have their own protocols: `CreateableSecure
**You can conform to all three protocols on the same type!**
```swift
struct TwitterAccount: ReadableSecureStorable,
struct TwitterAccount: ReadableSecureStorable,
CreateableSecureStorable,
DeleteableSecureStorable,
GenericPasswordSecureStorable {
@@ -276,7 +293,7 @@ By adopting a protocol-oriented design from the ground up, Locksmith can provide
Lets start with an example: the Twitter account from before, except its now an `InternetPasswordSecureStorable`, which lets us store a bit more metadata.
```swift
struct TwitterAccount: InternetPasswordSecureStorable,
struct TwitterAccount: InternetPasswordSecureStorable,
ReadableSecureStorable,
CreateableSecureStorable {
let username: String
@@ -394,7 +411,7 @@ public enum LocksmithError: ErrorType {
#### `LocksmithInternetAuthenticationType`
`LocksmithInternetAuthenticationType` lets you pick out the type of authentication you want to store alongside your `.InternetPassword`s—anything from `.MSN` to `.HTTPDigest`. [Apples documentation](https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices/#//apple_ref/doc/constant_group/Authentication_Type_Values) provides more information on these values.
`LocksmithInternetAuthenticationType` lets you pick out the type of authentication you want to store alongside your `.InternetPassword`s—anything from `.MSN` to `.HTTPDigest`. [Apples documentation](https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices/#//apple_ref/doc/constant_group/Authentication_Type_Values) provides more information on these values.
```swift
public enum LocksmithInternetAuthenticationType {
@@ -411,7 +428,7 @@ public enum LocksmithInternetAuthenticationType {
#### `LocksmithInternetProtocol`
`LocksmithInternetProtocol` is used with `.InternetPassword` to choose which protocol was used for the interaction with the web service, including `.HTTP`, `.SMB`, and a whole bunch more. [Apples documentation](https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices/#//apple_ref/doc/constant_group/Protocol_Values) provides more information on these values.
`LocksmithInternetProtocol` is used with `.InternetPassword` to choose which protocol was used for the interaction with the web service, including `.HTTP`, `.SMB`, and a whole bunch more. [Apples documentation](https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices/#//apple_ref/doc/constant_group/Protocol_Values) provides more information on these values.
```swift
public enum {
+1 -1
View File
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.1</string>
<string>4.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
+77 -70
View File
@@ -1,13 +1,13 @@
import Foundation
public let LocksmithDefaultService = NSBundle.mainBundle().infoDictionary![String(kCFBundleIdentifierKey)] as? String ?? "com.locksmith.defaultService"
public let LocksmithDefaultService = Bundle.main.infoDictionary![String(kCFBundleIdentifierKey)] as? String ?? "com.locksmith.defaultService"
public typealias PerformRequestClosureType = (requestReference: CFDictionaryRef, inout result: AnyObject?) -> (OSStatus)
public typealias PerformRequestClosureType = (_ requestReference: CFDictionary, _ result: inout AnyObject?) -> (OSStatus)
// MARK: - Locksmith
public struct Locksmith {
public static func loadDataForUserAccount(userAccount: String, inService service: String = LocksmithDefaultService) -> [String: AnyObject]? {
public static func loadDataForUserAccount(userAccount: String, inService service: String = LocksmithDefaultService) -> [String: Any]? {
struct ReadRequest: GenericPasswordSecureStorable, ReadableSecureStorable {
let service: String
let account: String
@@ -17,11 +17,11 @@ public struct Locksmith {
return request.readFromSecureStore()?.data
}
public static func saveData(data: [String: AnyObject], forUserAccount userAccount: String, inService service: String = LocksmithDefaultService) throws {
public static func saveData(data: [String: Any], forUserAccount userAccount: String, inService service: String = LocksmithDefaultService) throws {
struct CreateRequest: GenericPasswordSecureStorable, CreateableSecureStorable {
let service: String
let account: String
let data: [String: AnyObject]
let data: [String: Any]
}
let request = CreateRequest(service: service, account: userAccount, data: data)
@@ -38,11 +38,11 @@ public struct Locksmith {
return try request.deleteFromSecureStore()
}
public static func updateData(data: [String: AnyObject], forUserAccount userAccount: String, inService service: String = LocksmithDefaultService) throws {
public static func updateData(data: [String: Any], forUserAccount userAccount: String, inService service: String = LocksmithDefaultService) throws {
struct UpdateRequest: GenericPasswordSecureStorable, CreateableSecureStorable {
let service: String
let account: String
let data: [String: AnyObject]
let data: [String: Any]
}
let request = UpdateRequest(service: service, account: userAccount, data: data)
@@ -61,7 +61,7 @@ public extension SecureStorable {
var accessible: LocksmithAccessibleOption? { return nil }
var accessGroup: String? { return nil }
var secureStorableBaseStoragePropertyDictionary: [String: AnyObject] {
var secureStorableBaseStoragePropertyDictionary: [String: Any] {
let dictionary = [
String(kSecAttrAccessGroup): accessGroup,
String(kSecAttrAccessible): accessible?.rawValue
@@ -70,12 +70,13 @@ public extension SecureStorable {
return Dictionary(withoutOptionalValues: dictionary)
}
private func performSecureStorageAction(closure: PerformRequestClosureType, secureStoragePropertyDictionary: [String: AnyObject]) throws -> [String: AnyObject]? {
@discardableResult
fileprivate func performSecureStorageAction(closure: PerformRequestClosureType, secureStoragePropertyDictionary: [String: Any]) throws -> [String: Any]? {
var result: AnyObject?
let request = secureStoragePropertyDictionary
let requestReference = request as CFDictionaryRef
let requestReference = request as CFDictionary
let status = closure(requestReference: requestReference, result: &result)
let status = closure(requestReference, &result)
let statusCode = Int(status)
@@ -96,13 +97,13 @@ public extension SecureStorable {
return nil
}
return result as? [String: AnyObject]
return result as? [String: Any]
}
}
public extension SecureStorable where Self : InternetPasswordSecureStorable {
private var internetPasswordBaseStoragePropertyDictionary: [String: AnyObject] {
var dictionary = [String: AnyObject]()
fileprivate var internetPasswordBaseStoragePropertyDictionary: [String: Any] {
var dictionary = [String: Any]()
// add in whatever turns out to be required...
dictionary[String(kSecAttrServer)] = server
@@ -111,7 +112,7 @@ public extension SecureStorable where Self : InternetPasswordSecureStorable {
dictionary[String(kSecAttrAuthenticationType)] = authenticationType.rawValue
dictionary[String(kSecAttrSecurityDomain)] = securityDomain
dictionary[String(kSecAttrPath)] = path
dictionary[String(kSecClass)] = LocksmithSecurityClass.InternetPassword.rawValue
dictionary[String(kSecClass)] = LocksmithSecurityClass.internetPassword.rawValue
let toMergeWith = [
accountSecureStoragePropertyDictionary,
@@ -137,7 +138,7 @@ public protocol AccountBasedSecureStorable {
}
public extension AccountBasedSecureStorable {
private var accountSecureStoragePropertyDictionary: [String: AnyObject] {
fileprivate var accountSecureStoragePropertyDictionary: [String: Any] {
return [String(kSecAttrAccount): account]
}
}
@@ -158,7 +159,7 @@ public protocol DescribableSecureStorable {
public extension DescribableSecureStorable {
var description: String? { return nil }
private var describableSecureStoragePropertyDictionary: [String: AnyObject] {
fileprivate var describableSecureStoragePropertyDictionary: [String: Any] {
return Dictionary(withoutOptionalValues: [
String(kSecAttrDescription): description
])
@@ -181,7 +182,7 @@ public protocol CommentableSecureStorable {
public extension CommentableSecureStorable {
var comment: String? { return nil }
private var commentableSecureStoragePropertyDictionary: [String: AnyObject] {
fileprivate var commentableSecureStoragePropertyDictionary: [String: Any] {
return Dictionary(withoutOptionalValues: [
String(kSecAttrComment): comment
])
@@ -204,7 +205,7 @@ public protocol CreatorDesignatableSecureStorable {
public extension CreatorDesignatableSecureStorable {
var creator: UInt? { return nil }
private var creatorDesignatableSecureStoragePropertyDictionary: [String: AnyObject] {
fileprivate var creatorDesignatableSecureStoragePropertyDictionary: [String: Any] {
return Dictionary(withoutOptionalValues: [String(kSecAttrCreator): creator])
}
}
@@ -225,7 +226,7 @@ public protocol LabellableSecureStorable {
public extension LabellableSecureStorable {
var label: String? { return nil }
private var labellableSecureStoragePropertyDictionary: [String: AnyObject] {
fileprivate var labellableSecureStoragePropertyDictionary: [String: Any] {
return Dictionary(withoutOptionalValues: [String(kSecAttrLabel): label])
}
}
@@ -246,7 +247,7 @@ public protocol TypeDesignatableSecureStorable {
public extension TypeDesignatableSecureStorable {
var type: UInt? { return nil }
private var typeDesignatableSecureStoragePropertyDictionary: [String: AnyObject] {
fileprivate var typeDesignatableSecureStoragePropertyDictionary: [String: Any] {
return Dictionary(withoutOptionalValues: [String(kSecAttrType): type])
}
}
@@ -266,7 +267,7 @@ public protocol IsInvisibleAssignableSecureStorable {
public extension IsInvisibleAssignableSecureStorable {
var isInvisible: Bool? { return nil }
private var isInvisibleSecureStoragePropertyDictionary: [String: AnyObject] {
fileprivate var isInvisibleSecureStoragePropertyDictionary: [String: Any] {
return Dictionary(withoutOptionalValues: [String(kSecAttrIsInvisible): isInvisible])
}
}
@@ -286,7 +287,7 @@ public protocol IsNegativeAssignableSecureStorable {
public extension IsNegativeAssignableSecureStorable {
var isNegative: Bool? { return nil }
private var isNegativeSecureStoragePropertyDictionary: [String: AnyObject] {
fileprivate var isNegativeSecureStoragePropertyDictionary: [String: Any] {
return Dictionary(withoutOptionalValues: [String(kSecAttrIsNegative): isNegative])
}
}
@@ -318,7 +319,7 @@ public extension GenericPasswordSecureStorable {
}
// dear god what have i done...
public protocol GenericPasswordSecureStorableResultType: GenericPasswordSecureStorable, SecureStorableResultType, AccountBasedSecureStorableResultType, DescribableSecureStorableResultType, CommentableSecureStorableResultType, CreatorDesignatableSecureStorableResultType, LabellableSecureStorableResultType, TypeDesignatableSecureStorableResultType, IsInvisibleAssignableSecureStorableResultType, IsNegativeAssignableSecureStorableResultType {}
public protocol GenericPasswordSecureStorableResultType: GenericPasswordSecureStorable, AccountBasedSecureStorableResultType, DescribableSecureStorableResultType, CommentableSecureStorableResultType, CreatorDesignatableSecureStorableResultType, LabellableSecureStorableResultType, TypeDesignatableSecureStorableResultType, IsInvisibleAssignableSecureStorableResultType, IsNegativeAssignableSecureStorableResultType {}
public extension GenericPasswordSecureStorableResultType {
var service: String {
@@ -331,12 +332,12 @@ public extension GenericPasswordSecureStorableResultType {
}
public extension SecureStorable where Self : GenericPasswordSecureStorable {
private var genericPasswordBaseStoragePropertyDictionary: [String: AnyObject] {
var dictionary = [String: AnyObject?]()
fileprivate var genericPasswordBaseStoragePropertyDictionary: [String: Any] {
var dictionary = [String: Any?]()
dictionary[String(kSecAttrService)] = service
dictionary[String(kSecAttrGeneric)] = generic
dictionary[String(kSecClass)] = LocksmithSecurityClass.GenericPassword.rawValue
dictionary[String(kSecClass)] = LocksmithSecurityClass.genericPassword.rawValue
dictionary = Dictionary(initial: dictionary, toMerge: describableSecureStoragePropertyDictionary)
@@ -384,7 +385,7 @@ public extension InternetPasswordSecureStorableResultType {
}
var server: String {
return stringFromResultDictionary(kSecAttrServer)!
return stringFromResultDictionary(key: kSecAttrServer)!
}
var port: Int {
@@ -392,19 +393,19 @@ public extension InternetPasswordSecureStorableResultType {
}
var internetProtocol: LocksmithInternetProtocol {
return LocksmithInternetProtocol(rawValue: stringFromResultDictionary(kSecAttrProtocol)!)!
return LocksmithInternetProtocol(rawValue: stringFromResultDictionary(key: kSecAttrProtocol)!)!
}
var authenticationType: LocksmithInternetAuthenticationType {
return LocksmithInternetAuthenticationType(rawValue: stringFromResultDictionary(kSecAttrAuthenticationType)!)!
return LocksmithInternetAuthenticationType(rawValue: stringFromResultDictionary(key: kSecAttrAuthenticationType)!)!
}
var securityDomain: String? {
return stringFromResultDictionary(kSecAttrSecurityDomain)
return stringFromResultDictionary(key: kSecAttrSecurityDomain)
}
var path: String? {
return stringFromResultDictionary(kSecAttrPath)
return stringFromResultDictionary(key: kSecAttrPath)
}
}
@@ -420,7 +421,7 @@ public protocol KeySecureStorable: SecureStorable {}
/// Conformance to this protocol indicates that your type is able to be created and saved to a secure storage container.
public protocol CreateableSecureStorable: SecureStorable {
var data: [String: AnyObject] { get }
var data: [String: Any] { get }
var performCreateRequestClosure: PerformRequestClosureType { get }
func createInSecureStore() throws
func updateInSecureStore() throws
@@ -435,8 +436,8 @@ public protocol ReadableSecureStorable: SecureStorable {
public extension ReadableSecureStorable {
var performReadRequestClosure: PerformRequestClosureType {
return { (requestReference: CFDictionaryRef, inout result: AnyObject?) in
return withUnsafeMutablePointer(&result) { SecItemCopyMatching(requestReference, UnsafeMutablePointer($0)) }
return { (requestReference: CFDictionary, result: inout AnyObject?) in
return withUnsafeMutablePointer(to: &result) { SecItemCopyMatching(requestReference, UnsafeMutablePointer($0)) }
}
}
@@ -447,9 +448,9 @@ public extension ReadableSecureStorable {
}
public extension ReadableSecureStorable where Self : GenericPasswordSecureStorable {
var asReadableSecureStoragePropertyDictionary: [String: AnyObject] {
var asReadableSecureStoragePropertyDictionary: [String: Any] {
var old = genericPasswordBaseStoragePropertyDictionary
old[String(kSecReturnData)] = true
old[String(kSecReturnData)] = kCFBooleanTrue
old[String(kSecMatchLimit)] = kSecMatchLimitOne
old[String(kSecReturnAttributes)] = kCFBooleanTrue
@@ -458,9 +459,9 @@ public extension ReadableSecureStorable where Self : GenericPasswordSecureStorab
}
public extension ReadableSecureStorable where Self : InternetPasswordSecureStorable {
var asReadableSecureStoragePropertyDictionary: [String: AnyObject] {
var asReadableSecureStoragePropertyDictionary: [String: Any] {
var old = internetPasswordBaseStoragePropertyDictionary
old[String(kSecReturnData)] = true
old[String(kSecReturnData)] = kCFBooleanTrue
old[String(kSecMatchLimit)] = kSecMatchLimitOne
old[String(kSecReturnAttributes)] = kCFBooleanTrue
return old
@@ -468,13 +469,13 @@ public extension ReadableSecureStorable where Self : InternetPasswordSecureStora
}
struct GenericPasswordResult: GenericPasswordSecureStorableResultType {
var resultDictionary: [String: AnyObject]
var resultDictionary: [String: Any]
}
public extension ReadableSecureStorable where Self : GenericPasswordSecureStorable {
func readFromSecureStore() -> GenericPasswordSecureStorableResultType? {
do {
if let result = try performSecureStorageAction(performReadRequestClosure, secureStoragePropertyDictionary: asReadableSecureStoragePropertyDictionary) {
if let result = try performSecureStorageAction(closure: performReadRequestClosure, secureStoragePropertyDictionary: asReadableSecureStoragePropertyDictionary) {
return GenericPasswordResult(resultDictionary: result)
} else {
return nil
@@ -488,7 +489,7 @@ public extension ReadableSecureStorable where Self : GenericPasswordSecureStorab
public extension ReadableSecureStorable where Self : InternetPasswordSecureStorable {
func readFromSecureStore() -> InternetPasswordSecureStorableResultType? {
do {
if let result = try performSecureStorageAction(performReadRequestClosure, secureStoragePropertyDictionary: asReadableSecureStoragePropertyDictionary) {
if let result = try performSecureStorageAction(closure: performReadRequestClosure, secureStoragePropertyDictionary: asReadableSecureStoragePropertyDictionary) {
return InternetPasswordResult(resultDictionary: result)
} else {
return nil
@@ -510,61 +511,67 @@ public protocol DeleteableSecureStorable: SecureStorable {
// MARK: - Default property dictionaries
extension CreateableSecureStorable {
func updateInSecureStore(query: [String: AnyObject]) throws {
func updateInSecureStore(query: [String: Any]) throws {
var attributesToUpdate = query
attributesToUpdate[String(kSecClass)] = nil
let status = SecItemUpdate(query, attributesToUpdate)
let status = SecItemUpdate(query as CFDictionary, attributesToUpdate as CFDictionary)
if let error = LocksmithError(fromStatusCode: Int(status)) {
throw error
}
if status != errSecSuccess {
throw LocksmithError.Undefined
if error == .notFound || error == .notAvailable {
try self.createInSecureStore()
} else {
throw error
}
} else {
if status != errSecSuccess {
throw LocksmithError.undefined
}
}
}
}
public extension CreateableSecureStorable where Self : GenericPasswordSecureStorable {
var asCreateableSecureStoragePropertyDictionary: [String: AnyObject] {
var asCreateableSecureStoragePropertyDictionary: [String: Any] {
var old = genericPasswordBaseStoragePropertyDictionary
old[String(kSecValueData)] = NSKeyedArchiver.archivedDataWithRootObject(data)
old[String(kSecValueData)] = NSKeyedArchiver.archivedData(withRootObject: data)
return old
}
}
public extension CreateableSecureStorable where Self : GenericPasswordSecureStorable {
func createInSecureStore() throws {
try performSecureStorageAction(performCreateRequestClosure, secureStoragePropertyDictionary: asCreateableSecureStoragePropertyDictionary)
try performSecureStorageAction(closure: performCreateRequestClosure, secureStoragePropertyDictionary: asCreateableSecureStoragePropertyDictionary)
}
func updateInSecureStore() throws {
try self.updateInSecureStore(self.asCreateableSecureStoragePropertyDictionary)
try self.updateInSecureStore(query: self.asCreateableSecureStoragePropertyDictionary)
}
}
public extension CreateableSecureStorable where Self : InternetPasswordSecureStorable {
var asCreateableSecureStoragePropertyDictionary: [String: AnyObject] {
var asCreateableSecureStoragePropertyDictionary: [String: Any] {
var old = internetPasswordBaseStoragePropertyDictionary
old[String(kSecValueData)] = NSKeyedArchiver.archivedDataWithRootObject(data)
old[String(kSecValueData)] = NSKeyedArchiver.archivedData(withRootObject: data)
return old
}
}
public extension CreateableSecureStorable {
var performCreateRequestClosure: PerformRequestClosureType {
return { (requestReference: CFDictionaryRef, inout result: AnyObject?) in
return withUnsafeMutablePointer(&result) { SecItemAdd(requestReference, UnsafeMutablePointer($0)) }
return { (requestReference: CFDictionary, result: inout AnyObject?) in
return withUnsafeMutablePointer(to: &result) { mutablePointer in
SecItemAdd(requestReference, mutablePointer)
}
}
}
}
public extension CreateableSecureStorable where Self : InternetPasswordSecureStorable {
func createInSecureStore() throws {
try performSecureStorageAction(performCreateRequestClosure, secureStoragePropertyDictionary: asCreateableSecureStoragePropertyDictionary)
try performSecureStorageAction(closure: performCreateRequestClosure, secureStoragePropertyDictionary: asCreateableSecureStoragePropertyDictionary)
}
func updateInSecureStore() throws {
try self.updateInSecureStore(self.asCreateableSecureStoragePropertyDictionary)
try self.updateInSecureStore(query: self.asCreateableSecureStoragePropertyDictionary)
}
}
@@ -577,49 +584,49 @@ public extension DeleteableSecureStorable {
}
public extension DeleteableSecureStorable where Self : GenericPasswordSecureStorable {
var asDeleteableSecureStoragePropertyDictionary: [String: AnyObject] {
var asDeleteableSecureStoragePropertyDictionary: [String: Any] {
return genericPasswordBaseStoragePropertyDictionary
}
}
public extension DeleteableSecureStorable where Self : InternetPasswordSecureStorable {
var asDeleteableSecureStoragePropertyDictionary: [String: AnyObject] {
var asDeleteableSecureStoragePropertyDictionary: [String: Any] {
return internetPasswordBaseStoragePropertyDictionary
}
}
public extension DeleteableSecureStorable where Self : GenericPasswordSecureStorable {
func deleteFromSecureStore() throws {
try performSecureStorageAction(performDeleteRequestClosure, secureStoragePropertyDictionary: asDeleteableSecureStoragePropertyDictionary)
try performSecureStorageAction(closure: performDeleteRequestClosure, secureStoragePropertyDictionary: asDeleteableSecureStoragePropertyDictionary)
}
}
public extension DeleteableSecureStorable where Self : InternetPasswordSecureStorable {
func deleteFromSecureStore() throws {
try performSecureStorageAction(performDeleteRequestClosure, secureStoragePropertyDictionary: asDeleteableSecureStoragePropertyDictionary)
try performSecureStorageAction(closure: performDeleteRequestClosure, secureStoragePropertyDictionary: asDeleteableSecureStoragePropertyDictionary)
}
}
// MARK: ResultTypes
public protocol SecureStorableResultType: SecureStorable {
var resultDictionary: [String: AnyObject] { get }
var data: [String: AnyObject]? { get }
var resultDictionary: [String: Any] { get }
var data: [String: Any]? { get }
}
struct InternetPasswordResult: InternetPasswordSecureStorableResultType {
var resultDictionary: [String: AnyObject]
var resultDictionary: [String: Any]
}
public extension SecureStorableResultType {
var resultDictionary: [String: AnyObject] {
return [String: AnyObject]()
var resultDictionary: [String: Any] {
return [String: Any]()
}
var data: [String: AnyObject]? {
var data: [String: Any]? {
guard let aData = resultDictionary[String(kSecValueData)] as? NSData else {
return nil
}
return NSKeyedUnarchiver.unarchiveObjectWithData(aData) as? [String: AnyObject]
return NSKeyedUnarchiver.unarchiveObject(with: aData as Data) as? [String: Any]
}
}
+16 -16
View File
@@ -2,44 +2,44 @@ import Foundation
// MARK: Accessible
public enum LocksmithAccessibleOption: RawRepresentable {
case WhenUnlocked, AfterFirstUnlock, Always, WhenUnlockedThisDeviceOnly, AfterFirstUnlockThisDeviceOnly, AlwaysThisDeviceOnly, WhenPasscodeSetThisDeviceOnly
case whenUnlocked, afterFirstUnlock, always, whenUnlockedThisDeviceOnly, afterFirstUnlockThisDeviceOnly, alwaysThisDeviceOnly, whenPasscodeSetThisDeviceOnly
public init?(rawValue: String) {
switch rawValue {
case String(kSecAttrAccessibleWhenUnlocked):
self = WhenUnlocked
self = .whenUnlocked
case String(kSecAttrAccessibleAfterFirstUnlock):
self = AfterFirstUnlock
self = .afterFirstUnlock
case String(kSecAttrAccessibleAlways):
self = Always
self = .always
case String(kSecAttrAccessibleWhenUnlockedThisDeviceOnly):
self = WhenUnlockedThisDeviceOnly
self = .whenUnlockedThisDeviceOnly
case String(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly):
self = AfterFirstUnlockThisDeviceOnly
self = .afterFirstUnlockThisDeviceOnly
case String(kSecAttrAccessibleAlwaysThisDeviceOnly):
self = AlwaysThisDeviceOnly
self = .alwaysThisDeviceOnly
case String(kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly):
self = WhenPasscodeSetThisDeviceOnly
self = .whenPasscodeSetThisDeviceOnly
default:
self = WhenUnlocked
self = .whenUnlocked
}
}
public var rawValue: String {
switch self {
case .WhenUnlocked:
case .whenUnlocked:
return String(kSecAttrAccessibleWhenUnlocked)
case .AfterFirstUnlock:
case .afterFirstUnlock:
return String(kSecAttrAccessibleAfterFirstUnlock)
case .Always:
case .always:
return String(kSecAttrAccessibleAlways)
case .WhenPasscodeSetThisDeviceOnly:
case .whenPasscodeSetThisDeviceOnly:
return String(kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly)
case .WhenUnlockedThisDeviceOnly:
case .whenUnlockedThisDeviceOnly:
return String(kSecAttrAccessibleWhenUnlockedThisDeviceOnly)
case .AfterFirstUnlockThisDeviceOnly:
case .afterFirstUnlockThisDeviceOnly:
return String(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly)
case .AlwaysThisDeviceOnly:
case .alwaysThisDeviceOnly:
return String(kSecAttrAccessibleAlwaysThisDeviceOnly)
}
}
+24 -24
View File
@@ -1,42 +1,42 @@
import Foundation
// MARK: Locksmith Error
public enum LocksmithError: String, ErrorType {
case Allocate = "Failed to allocate memory."
case AuthFailed = "Authorization/Authentication failed."
case Decode = "Unable to decode the provided data."
case Duplicate = "The item already exists."
case InteractionNotAllowed = "Interaction with the Security Server is not allowed."
case NoError = "No error."
case NotAvailable = "No trust results are available."
case NotFound = "The item cannot be found."
case Param = "One or more parameters passed to the function were not valid."
case RequestNotSet = "The request was not set"
case TypeNotFound = "The type was not found"
case UnableToClear = "Unable to clear the keychain"
case Undefined = "An undefined error occurred"
case Unimplemented = "Function or operation not implemented."
public enum LocksmithError: String, Error {
case allocate = "Failed to allocate memory."
case authFailed = "Authorization/Authentication failed."
case decode = "Unable to decode the provided data."
case duplicate = "The item already exists."
case interactionNotAllowed = "Interaction with the Security Server is not allowed."
case noError = "No error."
case notAvailable = "No trust results are available."
case notFound = "The item cannot be found."
case param = "One or more parameters passed to the function were not valid."
case requestNotSet = "The request was not set"
case typeNotFound = "The type was not found"
case unableToClear = "Unable to clear the keychain"
case undefined = "An undefined error occurred"
case unimplemented = "Function or operation not implemented."
init?(fromStatusCode code: Int) {
switch code {
case Int(errSecAllocate):
self = Allocate
self = .allocate
case Int(errSecAuthFailed):
self = AuthFailed
self = .authFailed
case Int(errSecDecode):
self = Decode
self = .decode
case Int(errSecDuplicateItem):
self = Duplicate
self = .duplicate
case Int(errSecInteractionNotAllowed):
self = InteractionNotAllowed
self = .interactionNotAllowed
case Int(errSecItemNotFound):
self = NotFound
self = .notFound
case Int(errSecNotAvailable):
self = NotAvailable
self = .notAvailable
case Int(errSecParam):
self = Param
self = .param
case Int(errSecUnimplemented):
self = Unimplemented
self = .unimplemented
default:
return nil
}
@@ -1,48 +1,48 @@
import Foundation
public enum LocksmithInternetAuthenticationType: RawRepresentable {
case NTLM, MSN, DPA, RPA, HTTPBasic, HTTPDigest, HTMLForm, Default
case ntlm, msn, dpa, rpa, httpBasic, httpDigest, htmlForm, `default`
public init?(rawValue: String) {
switch rawValue {
case String(kSecAttrAuthenticationTypeNTLM):
self = NTLM
self = .ntlm
case String(kSecAttrAuthenticationTypeMSN):
self = MSN
self = .msn
case String(kSecAttrAuthenticationTypeDPA):
self = DPA
self = .dpa
case String(kSecAttrAuthenticationTypeRPA):
self = RPA
self = .rpa
case String(kSecAttrAuthenticationTypeHTTPBasic):
self = HTTPBasic
self = .httpBasic
case String(kSecAttrAuthenticationTypeHTTPDigest):
self = HTTPDigest
self = .httpDigest
case String(kSecAttrAuthenticationTypeHTMLForm):
self = HTMLForm
self = .htmlForm
case String(kSecAttrAuthenticationTypeDefault):
self = Default
self = .default
default:
self = Default
self = .default
}
}
public var rawValue: String {
switch self {
case .NTLM:
case .ntlm:
return String(kSecAttrAuthenticationTypeNTLM)
case .MSN:
case .msn:
return String(kSecAttrAuthenticationTypeMSN)
case .DPA:
case .dpa:
return String(kSecAttrAuthenticationTypeDPA)
case .RPA:
case .rpa:
return String(kSecAttrAuthenticationTypeRPA)
case .HTTPBasic:
case .httpBasic:
return String(kSecAttrAuthenticationTypeHTTPBasic)
case .HTTPDigest:
case .httpDigest:
return String(kSecAttrAuthenticationTypeHTTPDigest)
case .HTMLForm:
case .htmlForm:
return String(kSecAttrAuthenticationTypeHTMLForm)
case .Default:
case .default:
return String(kSecAttrAuthenticationTypeDefault)
}
}
+64 -64
View File
@@ -1,140 +1,140 @@
import Foundation
public enum LocksmithInternetProtocol: RawRepresentable {
case FTP, FTPAccount, HTTP, IRC, NNTP, POP3, SMTP, SOCKS, IMAP, LDAP, AppleTalk, AFP, Telnet, SSH, FTPS, HTTPS, HTTPProxy, HTTPSProxy, FTPProxy, SMB, RTSP, RTSPProxy, DAAP, EPPC, IPP, NNTPS, LDAPS, TelnetS, IMAPS, IRCS, POP3S
case ftp, ftpAccount, http, irc, nntp, pop3, smtp, socks, imap, ldap, appleTalk, afp, telnet, ssh, ftps, https, httpProxy, httpsProxy, ftpProxy, smb, rtsp, rtspProxy, daap, eppc, ipp, nntps, ldaps, telnetS, imaps, ircs, pop3S
public init?(rawValue: String) {
switch rawValue {
case String(kSecAttrProtocolFTP):
self = FTP
self = .ftp
case String(kSecAttrProtocolFTPAccount):
self = FTPAccount
self = .ftpAccount
case String(kSecAttrProtocolHTTP):
self = HTTP
self = .http
case String(kSecAttrProtocolIRC):
self = IRC
self = .irc
case String(kSecAttrProtocolNNTP):
self = NNTP
self = .nntp
case String(kSecAttrProtocolPOP3):
self = POP3
self = .pop3
case String(kSecAttrProtocolSMTP):
self = SMTP
self = .smtp
case String(kSecAttrProtocolSOCKS):
self = SOCKS
self = .socks
case String(kSecAttrProtocolIMAP):
self = IMAP
self = .imap
case String(kSecAttrProtocolLDAP):
self = LDAP
self = .ldap
case String(kSecAttrProtocolAppleTalk):
self = AppleTalk
self = .appleTalk
case String(kSecAttrProtocolAFP):
self = AFP
self = .afp
case String(kSecAttrProtocolTelnet):
self = Telnet
self = .telnet
case String(kSecAttrProtocolSSH):
self = SSH
self = .ssh
case String(kSecAttrProtocolFTPS):
self = FTPS
self = .ftps
case String(kSecAttrProtocolHTTPS):
self = HTTPS
self = .https
case String(kSecAttrProtocolHTTPProxy):
self = HTTPProxy
self = .httpProxy
case String(kSecAttrProtocolHTTPSProxy):
self = HTTPSProxy
self = .httpsProxy
case String(kSecAttrProtocolFTPProxy):
self = FTPProxy
self = .ftpProxy
case String(kSecAttrProtocolSMB):
self = SMB
self = .smb
case String(kSecAttrProtocolRTSP):
self = RTSP
self = .rtsp
case String(kSecAttrProtocolRTSPProxy):
self = RTSPProxy
self = .rtspProxy
case String(kSecAttrProtocolDAAP):
self = DAAP
self = .daap
case String(kSecAttrProtocolEPPC):
self = EPPC
self = .eppc
case String(kSecAttrProtocolIPP):
self = IPP
self = .ipp
case String(kSecAttrProtocolNNTPS):
self = NNTPS
self = .nntps
case String(kSecAttrProtocolLDAPS):
self = LDAPS
self = .ldaps
case String(kSecAttrProtocolTelnetS):
self = TelnetS
self = .telnetS
case String(kSecAttrProtocolIMAPS):
self = IMAPS
self = .imaps
case String(kSecAttrProtocolIRCS):
self = IRCS
self = .ircs
case String(kSecAttrProtocolPOP3S):
self = POP3S
self = .pop3S
default:
self = HTTP
self = .http
}
}
public var rawValue: String {
switch self {
case .FTP:
case .ftp:
return String(kSecAttrProtocolFTP)
case .FTPAccount:
case .ftpAccount:
return String(kSecAttrProtocolFTPAccount)
case .HTTP:
case .http:
return String(kSecAttrProtocolHTTP)
case .IRC:
case .irc:
return String(kSecAttrProtocolIRC)
case .NNTP:
case .nntp:
return String(kSecAttrProtocolNNTP)
case .POP3:
case .pop3:
return String(kSecAttrProtocolPOP3)
case .SMTP:
case .smtp:
return String(kSecAttrProtocolSMTP)
case .SOCKS:
case .socks:
return String(kSecAttrProtocolSOCKS)
case .IMAP:
case .imap:
return String(kSecAttrProtocolIMAP)
case .LDAP:
case .ldap:
return String(kSecAttrProtocolLDAP)
case .AppleTalk:
case .appleTalk:
return String(kSecAttrProtocolAppleTalk)
case .AFP:
case .afp:
return String(kSecAttrProtocolAFP)
case .Telnet:
case .telnet:
return String(kSecAttrProtocolTelnet)
case .SSH:
case .ssh:
return String(kSecAttrProtocolSSH)
case .FTPS:
case .ftps:
return String(kSecAttrProtocolFTPS)
case .HTTPS:
case .https:
return String(kSecAttrProtocolHTTPS)
case .HTTPProxy:
case .httpProxy:
return String(kSecAttrProtocolHTTPProxy)
case .HTTPSProxy:
case .httpsProxy:
return String(kSecAttrProtocolHTTPSProxy)
case .FTPProxy:
case .ftpProxy:
return String(kSecAttrProtocolFTPProxy)
case .SMB:
case .smb:
return String(kSecAttrProtocolSMB)
case .RTSP:
case .rtsp:
return String(kSecAttrProtocolRTSP)
case .RTSPProxy:
case .rtspProxy:
return String(kSecAttrProtocolRTSPProxy)
case .DAAP:
case .daap:
return String(kSecAttrProtocolDAAP)
case .EPPC:
case .eppc:
return String(kSecAttrProtocolEPPC)
case .IPP:
case .ipp:
return String(kSecAttrProtocolIPP)
case .NNTPS:
case .nntps:
return String(kSecAttrProtocolNNTPS)
case .LDAPS:
case .ldaps:
return String(kSecAttrProtocolLDAPS)
case .TelnetS:
case .telnetS:
return String(kSecAttrProtocolTelnetS)
case .IMAPS:
case .imaps:
return String(kSecAttrProtocolIMAPS)
case .IRCS:
case .ircs:
return String(kSecAttrProtocolIRCS)
case .POP3S:
case .pop3S:
return String(kSecAttrProtocolPOP3S)
}
}
+12 -12
View File
@@ -3,36 +3,36 @@ import Foundation
// With thanks to http://iosdeveloperzone.com/2014/10/22/taming-foundation-constants-into-swift-enums/
// MARK: Security Class
public enum LocksmithSecurityClass: RawRepresentable {
case GenericPassword, InternetPassword, Certificate, Key, Identity
case genericPassword, internetPassword, certificate, key, identity
public init?(rawValue: String) {
switch rawValue {
case String(kSecClassGenericPassword):
self = GenericPassword
self = .genericPassword
case String(kSecClassInternetPassword):
self = InternetPassword
self = .internetPassword
case String(kSecClassCertificate):
self = Certificate
self = .certificate
case String(kSecClassKey):
self = Key
self = .key
case String(kSecClassIdentity):
self = Identity
self = .identity
default:
self = GenericPassword
self = .genericPassword
}
}
public var rawValue: String {
switch self {
case .GenericPassword:
case .genericPassword:
return String(kSecClassGenericPassword)
case .InternetPassword:
case .internetPassword:
return String(kSecClassInternetPassword)
case .Certificate:
case .certificate:
return String(kSecClassCertificate)
case .Key:
case .key:
return String(kSecClassKey)
case .Identity:
case .identity:
return String(kSecClassIdentity)
}
}
+46
View File
@@ -0,0 +1,46 @@
//
// AppDelegate.swift
// Test Host
//
// Created by Federico Trimboli on 9/10/16.
// Copyright © 2016 Locksmith. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
@@ -0,0 +1,68 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11134" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11106"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
+26
View File
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11134" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11106"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
+45
View File
@@ -0,0 +1,45 @@
<?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>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
+10
View File
@@ -0,0 +1,10 @@
<?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>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)net.matthewpalmer.Test-Host</string>
</array>
</dict>
</plist>
+25
View File
@@ -0,0 +1,25 @@
//
// ViewController.swift
// Test Host
//
// Created by Federico Trimboli on 9/10/16.
// Copyright © 2016 Locksmith. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
@@ -17,8 +17,8 @@ class LocksmithTests: XCTestCase {
func clear() {
do {
try Locksmith.deleteDataForUserAccount(userAccount, inService: service)
try Locksmith.deleteDataForUserAccount(userAccount)
try Locksmith.deleteDataForUserAccount(userAccount: userAccount, inService: service)
try Locksmith.deleteDataForUserAccount(userAccount: userAccount)
} catch {
// no-op
}
@@ -34,53 +34,59 @@ class LocksmithTests: XCTestCase {
func testStaticMethods() {
let data = ["some": "data"]
try! Locksmith.saveData(data, forUserAccount: userAccount, inService: service)
try! Locksmith.saveData(data: data, forUserAccount: userAccount, inService: service)
let loaded = Locksmith.loadDataForUserAccount(userAccount, inService: service)! as! TestingDictionaryType
let loaded = Locksmith.loadDataForUserAccount(userAccount: userAccount, inService: service)! as! TestingDictionaryType
XCTAssertEqual(loaded, data)
try! Locksmith.deleteDataForUserAccount(userAccount, inService: service)
try! Locksmith.deleteDataForUserAccount(userAccount: userAccount, inService: service)
let otherData: TestingDictionaryType = ["something": "way different"]
try! Locksmith.saveData(otherData, forUserAccount: userAccount, inService: service)
try! Locksmith.saveData(data: otherData, forUserAccount: userAccount, inService: service)
let loadedAgain = Locksmith.loadDataForUserAccount(userAccount, inService: service)! as! TestingDictionaryType
let loadedAgain = Locksmith.loadDataForUserAccount(userAccount: userAccount, inService: service)! as! TestingDictionaryType
XCTAssertEqual(loadedAgain, otherData)
let updatedData = ["this update": "brings the ruckus"]
try! Locksmith.updateData(updatedData, forUserAccount: userAccount, inService: service)
try! Locksmith.updateData(data: updatedData, forUserAccount: userAccount, inService: service)
let loaded3 = Locksmith.loadDataForUserAccount(userAccount, inService: service)! as! TestingDictionaryType
let loaded3 = Locksmith.loadDataForUserAccount(userAccount: userAccount, inService: service)! as! TestingDictionaryType
XCTAssertEqual(loaded3, updatedData)
try! Locksmith.deleteDataForUserAccount(userAccount: userAccount, inService: service)
try! Locksmith.updateData(data: ["some update": "data"], forUserAccount: userAccount, inService: service)
let updateResult = Locksmith.loadDataForUserAccount(userAccount: userAccount, inService: service)! as! [String: String]
XCTAssertEqual(updateResult, ["some update": "data"])
}
func testStaticMethodsForDefaultService() {
let data = ["some": "data"]
try! Locksmith.saveData(data, forUserAccount: userAccount)
try! Locksmith.saveData(data: data, forUserAccount: userAccount)
let loaded = Locksmith.loadDataForUserAccount(userAccount)! as! TestingDictionaryType
let loaded = Locksmith.loadDataForUserAccount(userAccount: userAccount)! as! TestingDictionaryType
XCTAssertEqual(loaded, data)
try! Locksmith.deleteDataForUserAccount(userAccount)
try! Locksmith.deleteDataForUserAccount(userAccount: userAccount)
let otherData: TestingDictionaryType = ["something": "way different"]
try! Locksmith.saveData(otherData, forUserAccount: userAccount)
try! Locksmith.saveData(data: otherData, forUserAccount: userAccount)
let loadedAgain = Locksmith.loadDataForUserAccount(userAccount)! as! TestingDictionaryType
let loadedAgain = Locksmith.loadDataForUserAccount(userAccount: userAccount)! as! TestingDictionaryType
XCTAssertEqual(loadedAgain, otherData)
let updatedData = ["this update": "brings the ruckus"]
try! Locksmith.updateData(updatedData, forUserAccount: userAccount)
try! Locksmith.updateData(data: updatedData, forUserAccount: userAccount)
let loaded3 = Locksmith.loadDataForUserAccount(userAccount)! as! TestingDictionaryType
let loaded3 = Locksmith.loadDataForUserAccount(userAccount: userAccount)! as! TestingDictionaryType
XCTAssertEqual(loaded3, updatedData)
}
func createGenericPasswordWithData(data: [String: AnyObject]) {
func createGenericPasswordWithData(_ data: [String: Any]) {
struct CreateGenericPassword: CreateableSecureStorable, GenericPasswordSecureStorable {
let data: [String: AnyObject]
let data: [String: Any]
let account: String
let service: String
}
@@ -94,11 +100,27 @@ class LocksmithTests: XCTestCase {
createGenericPasswordWithData(data)
}
func testUpdateCreatesIfNotExists() {
let data = ["some": "data"]
struct CreateGenericPassword: CreateableSecureStorable, GenericPasswordSecureStorable, ReadableSecureStorable {
var data: [String: Any]
let account: String
let service: String
}
let update = CreateGenericPassword(data: data, account: userAccount, service: service)
try! update.updateInSecureStore()
let read = update.readFromSecureStore()!.data as! [String: String]
XCTAssertEqual(read, ["some": "data"])
}
func testUpdateForGenericPassword() {
let data = ["some": "data"]
struct CreateGenericPassword: CreateableSecureStorable, GenericPasswordSecureStorable, ReadableSecureStorable {
var data: [String: AnyObject]
var data: [String: Any]
let account: String
let service: String
}
@@ -139,7 +161,7 @@ class LocksmithTests: XCTestCase {
let delete = DeleteGenericPassword(account: userAccount, service: service)
try! delete.deleteFromSecureStore()
let d = Locksmith.loadDataForUserAccount(userAccount, inService: service)
let d = Locksmith.loadDataForUserAccount(userAccount: userAccount, inService: service)
XCTAssertNil(d)
}
@@ -147,7 +169,7 @@ class LocksmithTests: XCTestCase {
struct Omnivore: ReadableSecureStorable, CreateableSecureStorable, DeleteableSecureStorable, GenericPasswordSecureStorable {
let account: String
let service: String
let data: [String: AnyObject]
let data: [String: Any]
}
let data: [String: String] = ["something": "else"]
@@ -177,7 +199,7 @@ class LocksmithTests: XCTestCase {
struct Create : CreateableSecureStorable, InternetPasswordSecureStorable {
let account: String
let server: String
let data: [String: AnyObject]
let data: [String: Any]
let port: Int
let internetProtocol: LocksmithInternetProtocol
let authenticationType: LocksmithInternetAuthenticationType
@@ -186,8 +208,8 @@ class LocksmithTests: XCTestCase {
let server = "server"
let initialData = ["one": "two"]
let port = 8080
let internetProtocol = LocksmithInternetProtocol.HTTPS
let authenticationType = LocksmithInternetAuthenticationType.DPA
let internetProtocol = LocksmithInternetProtocol.https
let authenticationType = LocksmithInternetAuthenticationType.dpa
struct Delete: DeleteableSecureStorable, InternetPasswordSecureStorable {
let account: String
@@ -225,7 +247,7 @@ class LocksmithTests: XCTestCase {
let comment: String?
let description: String?
let creator: UInt?
let data: [String: AnyObject]
let data: [String: Any]
}
let initialData = ["one": "two"]
@@ -257,7 +279,7 @@ class LocksmithTests: XCTestCase {
func testInternetPasswordMetaAttributesAreCreatedAndReturned() {
struct CreateInternetPassword: CreateableSecureStorable, InternetPasswordSecureStorable {
let account: String
var data: [String: AnyObject]
var data: [String: Any]
let server: String
let port: Int
let internetProtocol: LocksmithInternetProtocol
@@ -266,12 +288,12 @@ class LocksmithTests: XCTestCase {
let securityDomain: String?
}
let userAccount = "user \(NSDate())"
let userAccount = "user \(Date())"
let initialData = ["internet": "data"]
let server = "net.matthewpalmer"
let port = 8080
let internetProtocol = LocksmithInternetProtocol.FTP
let authenticationType = LocksmithInternetAuthenticationType.HTTPBasic
let internetProtocol = LocksmithInternetProtocol.ftp
let authenticationType = LocksmithInternetAuthenticationType.httpBasic
let path = "somePath"
let securityDomain = "someDomain"
@@ -286,7 +308,7 @@ class LocksmithTests: XCTestCase {
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?) {
func assertResultMetadataIsOk(_ result: InternetPasswordSecureStorableResultType?) {
XCTAssertEqual(result?.account, userAccount)
XCTAssertEqual(result?.server, server)
XCTAssertEqual(result?.port, port)
@@ -310,9 +332,9 @@ class LocksmithTests: XCTestCase {
assertResultMetadataIsOk(result2)
}
func assertStringPairsMatchInDictionary(dictionary: NSDictionary, pairs: [(key: CFString, expectedOutput: String)]) {
func assertStringPairsMatchInDictionary(_ dictionary: NSDictionary, pairs: [(key: CFString, expectedOutput: String)]) {
for pair in pairs {
let a = dictionary[String(pair.0)] as! CFStringRef
let a = dictionary[String(pair.0)] as! CFString
XCTAssertEqual(a as String, pair.1)
}
}
@@ -321,7 +343,7 @@ class LocksmithTests: XCTestCase {
struct CreateInternetPassword: CreateableSecureStorable, InternetPasswordSecureStorable, DeleteableSecureStorable {
let account: String
let service: String
let data: [String: AnyObject]
let data: [String: Any]
let server: String
let port: Int
let internetProtocol: LocksmithInternetProtocol
@@ -333,14 +355,14 @@ class LocksmithTests: XCTestCase {
let account = "myUser"
let port = 8080
let internetProtocol = LocksmithInternetProtocol.HTTP
let authenticationType = LocksmithInternetAuthenticationType.HTTPBasic
let internetProtocol = LocksmithInternetProtocol.http
let authenticationType = LocksmithInternetAuthenticationType.httpBasic
let path = "some_path"
let securityDomain = "secdomain"
let data = ["some": "data"]
let server = "server"
let expect = expectationWithDescription("Must enter the closure")
let expect = expectation(description: "Must enter the closure")
let performRequestClosure: PerformRequestClosureType = { (requestReference, result) in
let dict = requestReference as NSDictionary
@@ -355,8 +377,8 @@ class LocksmithTests: XCTestCase {
(kSecClass, String(kSecClassInternetPassword))
])
let p = dict[String(kSecAttrPort)] as! CFNumberRef
XCTAssertEqual(p as Int, port)
let p = dict[String(kSecAttrPort)] as! CFNumber
XCTAssertEqual(p as! Int, port)
expect.fulfill()
@@ -367,12 +389,12 @@ class LocksmithTests: XCTestCase {
do { try create.deleteFromSecureStore() } catch {}
try! create.createInSecureStore()
waitForExpectationsWithTimeout(0.1, handler: nil)
waitForExpectations(timeout: 0.1, handler: nil)
}
func testGenericPasswordOptionalAttributesAreAppliedForConformingTypes() {
struct CreateGenericPassword: CreateableSecureStorable, GenericPasswordSecureStorable {
let data: [String: AnyObject]
let data: [String: Any]
let account: String
let service: String
let accessGroup: String?
@@ -384,23 +406,23 @@ class LocksmithTests: XCTestCase {
let type: UInt?
let isInvisible: Bool?
let isNegative: Bool?
let generic: NSData?
let generic: Data?
}
let data: [String: AnyObject] = ["some": "data"]
let data: [String: Any] = ["some": "data"]
let account: String = "myUser"
let service: String = "myService"
let accessGroup: String = "myAccessGroup"
let description: String = "myDescription"
let creator: UInt = 5
let accessible: LocksmithAccessibleOption = LocksmithAccessibleOption.Always
let accessible: LocksmithAccessibleOption = LocksmithAccessibleOption.always
let comment: String = "myComment"
let type: UInt = 10
let isInvisible: Bool = false
let isNegative: Bool = false
let generic: NSData = NSData()
let generic: Data = Data()
let expect = expectationWithDescription("Must enter the closure")
let expect = expectation(description: "Must enter the closure")
let performRequestClosure: PerformRequestClosureType = { (requestReference, result) in
let dict = requestReference as NSDictionary
@@ -415,20 +437,20 @@ class LocksmithTests: XCTestCase {
(kSecClass, String(kSecClassGenericPassword))
])
let cr = dict[String(kSecAttrCreator)] as! CFNumberRef
XCTAssertEqual(cr as UInt, creator)
let cr = dict[String(kSecAttrCreator)] as! CFNumber
XCTAssertEqual(cr as! UInt, creator)
let ty = dict[String(kSecAttrType)] as! CFNumberRef
XCTAssertEqual(ty as UInt, type)
let ty = dict[String(kSecAttrType)] as! CFNumber
XCTAssertEqual(ty as! UInt, type)
let inv = dict[String(kSecAttrIsInvisible)] as! CFBooleanRef
XCTAssertEqual(inv as Bool, isInvisible)
let inv = dict[String(kSecAttrIsInvisible)] as! CFBoolean
XCTAssertEqual(inv as! Bool, isInvisible)
let neg = dict[String(kSecAttrIsNegative)] as! CFBooleanRef
XCTAssertEqual(neg as Bool, isNegative)
let neg = dict[String(kSecAttrIsNegative)] as! CFBoolean
XCTAssertEqual(neg as! Bool, isNegative)
let gen = dict[String(kSecAttrGeneric)] as! CFDataRef
XCTAssertEqual(gen, generic)
let gen = dict[String(kSecAttrGeneric)]
XCTAssertNil(gen)
expect.fulfill()
@@ -439,6 +461,6 @@ class LocksmithTests: XCTestCase {
try! create.createInSecureStore()
waitForExpectationsWithTimeout(0.1, handler: nil)
waitForExpectations(timeout: 0.1, handler: nil)
}
}