Compare commits

..

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

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

You will get one of two kinds of errors:

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

The solution is to disable ONLY_ACTIVE_ARCH, which will ensure that both processor architectures are built and the symbols can be found.
2016-01-22 12:23:25 -05:00
Matthew Palmer 6ae6aaedf2 Merge pull request #93 from gambcl/gambcl-carthage-tvos
Added support for tvOS for Carthage builds
2015-12-15 07:31:43 +11:00
Charles Gamble c75cccde53 Change tvOS Deployment Target to 9.0 2015-12-14 13:12:55 +00:00
Matthew Palmer ecef17994c Update README.md 2015-12-11 20:51:19 +11:00
Matthew Palmer 55d9ad27a3 Merge pull request #87 from tc/master
carthage install instructions
2015-12-11 20:50:26 +11:00
Matthew Palmer 3393682ee7 Merge pull request #91 from juliangrosshauser/remove-info-plist-copy-bundle-resources
Remove Info.plist from Copy Bundle Resources phase
2015-12-11 20:49:53 +11:00
Matthew Palmer ff6e09e051 Merge pull request #90 from emrekyv/remove-print-statements
Remove print statements
2015-12-11 20:49:26 +11:00
Julian Grosshauser 6298dc0ec6 Remove Info.plist from Copy Bundle Resources phase
The removal of Info.plist from the Copy Bundle Resources build phase of the iOS target fixes the following warning:

Warning: The Copy Bundle Resources build phase contains this target's Info.plist file 'Source/Info.plist'.
2015-12-11 00:55:13 +01:00
Emre Kucukayvaz 96d1958632 Remove print statements 2015-12-10 10:47:03 +01:00
Charles Gamble ee5351dfe9 Added carthage support for tvOS build 2015-12-09 13:55:10 +00:00
Matthew Palmer 2459d0c2ff Update README.md 2015-11-23 08:19:06 +11:00
Matthew Palmer effbd18736 Merge pull request #83 from matthewpalmer/matthewpalmer-tvos
Re-add tvOS support
2015-11-22 20:20:41 +11:00
Tommy Chheng bb380ebd3b carthage install instructions 2015-11-16 14:24:33 -08:00
Matthew Palmer 4d9fcd7f77 Update README.md 2015-10-15 06:46:08 +11:00
Matthew Palmer 2ed51c13e7 Update README.md 2015-10-15 06:45:57 +11:00
Matthew Palmer 60a44fe471 Re-add tvOS support 2015-10-15 06:45:02 +11:00
Matthew Palmer da2ea377bc Merge pull request #82 from matthewpalmer/revert-81-master
Revert "Add support for tvOS"
2015-10-15 06:42:32 +11:00
Matthew Palmer 90fb6207ae Revert "Add support for tvOS" 2015-10-15 06:41:29 +11:00
36 changed files with 1409 additions and 312 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 = "0700"
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.2"
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.
+357 -12
View File
@@ -7,13 +7,13 @@
objects = {
/* Begin PBXBuildFile section */
056F2A971BA4316700B24B65 /* Dictionary_Initializers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C401BA38539004191AF /* Dictionary_Initializers.swift */; settings = {ASSET_TAGS = (); }; };
056F2A981BA4316700B24B65 /* Locksmith.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C421BA38539004191AF /* Locksmith.swift */; settings = {ASSET_TAGS = (); }; };
056F2A991BA4316700B24B65 /* LocksmithAccessibleOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C431BA38539004191AF /* LocksmithAccessibleOption.swift */; settings = {ASSET_TAGS = (); }; };
056F2A9A1BA4316700B24B65 /* LocksmithError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C441BA38539004191AF /* LocksmithError.swift */; settings = {ASSET_TAGS = (); }; };
056F2A9B1BA4316700B24B65 /* LocksmithInternetAuthenticationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C451BA38539004191AF /* LocksmithInternetAuthenticationType.swift */; settings = {ASSET_TAGS = (); }; };
056F2A9C1BA4316700B24B65 /* LocksmithInternetProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C461BA38539004191AF /* LocksmithInternetProtocol.swift */; settings = {ASSET_TAGS = (); }; };
056F2A9D1BA4316700B24B65 /* LocksmithSecurityClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C471BA38539004191AF /* LocksmithSecurityClass.swift */; settings = {ASSET_TAGS = (); }; };
056F2A971BA4316700B24B65 /* Dictionary_Initializers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C401BA38539004191AF /* Dictionary_Initializers.swift */; };
056F2A981BA4316700B24B65 /* Locksmith.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C421BA38539004191AF /* Locksmith.swift */; };
056F2A991BA4316700B24B65 /* LocksmithAccessibleOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C431BA38539004191AF /* LocksmithAccessibleOption.swift */; };
056F2A9A1BA4316700B24B65 /* LocksmithError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C441BA38539004191AF /* LocksmithError.swift */; };
056F2A9B1BA4316700B24B65 /* LocksmithInternetAuthenticationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C451BA38539004191AF /* LocksmithInternetAuthenticationType.swift */; };
056F2A9C1BA4316700B24B65 /* LocksmithInternetProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C461BA38539004191AF /* LocksmithInternetProtocol.swift */; };
056F2A9D1BA4316700B24B65 /* LocksmithSecurityClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C471BA38539004191AF /* LocksmithSecurityClass.swift */; };
0EC25C631BA385AB004191AF /* Locksmith.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0EC25C591BA385AA004191AF /* Locksmith.framework */; };
0EC25C7F1BA385F6004191AF /* Locksmith.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0EC25C751BA385F6004191AF /* Locksmith.framework */; };
0EC25C8D1BA38648004191AF /* LocksmithTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C491BA38539004191AF /* LocksmithTests.swift */; };
@@ -32,10 +32,22 @@
0EC25C9A1BA38660004191AF /* LocksmithInternetProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C461BA38539004191AF /* LocksmithInternetProtocol.swift */; };
0EC25C9B1BA38662004191AF /* LocksmithSecurityClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C471BA38539004191AF /* LocksmithSecurityClass.swift */; };
0EC25C9C1BA38663004191AF /* LocksmithSecurityClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C471BA38539004191AF /* LocksmithSecurityClass.swift */; };
0EC25C9F1BA389CB004191AF /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0EC25C9E1BA389CB004191AF /* Info.plist */; };
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 */; };
FBD0C9541C18694600291F2A /* LocksmithAccessibleOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C431BA38539004191AF /* LocksmithAccessibleOption.swift */; };
FBD0C9551C18694C00291F2A /* LocksmithError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C441BA38539004191AF /* LocksmithError.swift */; };
FBD0C9561C18695000291F2A /* LocksmithInternetAuthenticationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C451BA38539004191AF /* LocksmithInternetAuthenticationType.swift */; };
FBD0C9571C18695600291F2A /* LocksmithInternetProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C461BA38539004191AF /* LocksmithInternetProtocol.swift */; };
FBD0C9581C18695A00291F2A /* LocksmithSecurityClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC25C471BA38539004191AF /* LocksmithSecurityClass.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -53,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 */
@@ -63,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; };
@@ -72,6 +91,15 @@
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 */
/* Begin PBXFrameworksBuildPhase section */
@@ -112,6 +140,20 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
E3DD3B311D84356500A59312 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
FBD0C9451C1866BE00291F2A /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@@ -161,6 +203,7 @@
children = (
0EC25C481BA38539004191AF /* Source */,
0EC25C4A1BA38539004191AF /* Tests */,
E3DD3B351D84356500A59312 /* Test Host */,
BFFB19D11A4870A300CCFFC3 /* Products */,
);
sourceTree = "<group>";
@@ -173,10 +216,26 @@
0EC25C751BA385F6004191AF /* Locksmith.framework */,
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 */
@@ -204,6 +263,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
FBD0C9461C1866BE00291F2A /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
FBD0C9521C18693900291F2A /* Locksmith.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
@@ -237,6 +304,7 @@
);
dependencies = (
0EC25C651BA385AB004191AF /* PBXTargetDependency */,
E3DD3B481D84360300A59312 /* PBXTargetDependency */,
);
name = "Locksmith iOS Tests";
productName = "Locksmith iOSTests";
@@ -297,21 +365,59 @@
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" */;
buildPhases = (
FBD0C9441C1866BE00291F2A /* Sources */,
FBD0C9451C1866BE00291F2A /* Frameworks */,
FBD0C9461C1866BE00291F2A /* Headers */,
FBD0C9471C1866BE00291F2A /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "Locksmith tvOS";
productName = "Locksmith tvOS";
productReference = FBD0C9491C1866BE00291F2A /* Locksmith.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
BFFB19C71A4870A300CCFFC3 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0700;
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;
@@ -322,6 +428,19 @@
0EC25CA61BA39C9F004191AF = {
CreatedOnToolsVersion = 7.0;
};
E3DD3B331D84356500A59312 = {
CreatedOnToolsVersion = 8.0;
LastSwiftMigration = 0900;
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.Keychain = {
enabled = 1;
};
};
};
FBD0C9481C1866BE00291F2A = {
CreatedOnToolsVersion = 7.2;
};
};
};
buildConfigurationList = BFFB19CA1A4870A300CCFFC3 /* Build configuration list for PBXProject "Locksmith" */;
@@ -330,6 +449,7 @@
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = BFFB19C61A4870A300CCFFC3;
productRefGroup = BFFB19D11A4870A300CCFFC3 /* Products */;
@@ -341,6 +461,8 @@
0EC25C741BA385F6004191AF /* Locksmith OS X */,
0EC25C7D1BA385F6004191AF /* Locksmith OS X Tests */,
0EC25CA61BA39C9F004191AF /* Locksmith watchOS */,
FBD0C9481C1866BE00291F2A /* Locksmith tvOS */,
E3DD3B331D84356500A59312 /* Test Host */,
);
};
/* End PBXProject section */
@@ -350,7 +472,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0EC25C9F1BA389CB004191AF /* Info.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -382,6 +503,23 @@
);
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;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -443,6 +581,29 @@
);
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;
files = (
FBD0C9541C18694600291F2A /* LocksmithAccessibleOption.swift in Sources */,
FBD0C9581C18695A00291F2A /* LocksmithSecurityClass.swift in Sources */,
FBD0C9531C18694100291F2A /* Locksmith.swift in Sources */,
FBD0C9511C18693200291F2A /* Dictionary_Initializers.swift in Sources */,
FBD0C9551C18694C00291F2A /* LocksmithError.swift in Sources */,
FBD0C9561C18695000291F2A /* LocksmithInternetAuthenticationType.swift in Sources */,
FBD0C9571C18695600291F2A /* LocksmithInternetProtocol.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
@@ -456,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;
@@ -476,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;
@@ -496,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;
@@ -510,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;
@@ -524,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;
};
@@ -547,6 +744,7 @@
PRODUCT_NAME = Locksmith;
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
};
name = Debug;
};
@@ -570,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;
@@ -586,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";
@@ -602,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;
@@ -621,6 +827,7 @@
PRODUCT_NAME = Locksmith;
SDKROOT = watchos;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 2.0;
};
@@ -629,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;
@@ -643,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;
};
@@ -652,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";
@@ -672,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",
@@ -701,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";
@@ -720,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;
@@ -738,6 +968,103 @@
};
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;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_BITCODE = YES;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = Source/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-tvOS";
PRODUCT_NAME = Locksmith;
SDKROOT = appletvos;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = 3;
TVOS_DEPLOYMENT_TARGET = 9.0;
};
name = Debug;
};
FBD0C94F1C1866BE00291F2A /* Release */ = {
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;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_BITCODE = YES;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = Source/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-tvOS";
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;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -795,6 +1122,24 @@
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 = (
FBD0C94E1C1866BE00291F2A /* Debug */,
FBD0C94F1C1866BE00291F2A /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = BFFB19C71A4870A300CCFFC3 /* Project object */;
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
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 = "0700"
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"
@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "FBD0C9481C1866BE00291F2A"
BuildableName = "Locksmith.framework"
BlueprintName = "Locksmith tvOS"
ReferencedContainer = "container:Locksmith.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "FBD0C9481C1866BE00291F2A"
BuildableName = "Locksmith.framework"
BlueprintName = "Locksmith tvOS"
ReferencedContainer = "container:Locksmith.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "FBD0C9481C1866BE00291F2A"
BuildableName = "Locksmith.framework"
BlueprintName = "Locksmith tvOS"
ReferencedContainer = "container:Locksmith.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
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"
)
+27 -4
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,14 +30,29 @@ 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).
pod 'Locksmith'
### Carthage
Locksmith is available through [Carthage](https://github.com/Carthage/Carthage).
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
@@ -101,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 {
@@ -270,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
@@ -388,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 {
@@ -405,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>
+98 -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,16 +38,15 @@ public struct Locksmith {
return try request.deleteFromSecureStore()
}
public static func updateData(data: [String: AnyObject], forUserAccount userAccount: String, inService service: String = LocksmithDefaultService) throws {
// Delete and then re-save
do {
try Locksmith.deleteDataForUserAccount(userAccount, inService: service)
} catch {
// Deletion is likely to fail if the piece of data doesn't exist yet.
// This doesn't matter--we only tell the user about errors on the save request.
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: Any]
}
return try Locksmith.saveData(data, forUserAccount: userAccount, inService: service)
let request = UpdateRequest(service: service, account: userAccount, data: data)
try request.updateInSecureStore()
}
}
@@ -62,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
@@ -71,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)
@@ -97,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
@@ -112,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,
@@ -138,7 +138,7 @@ public protocol AccountBasedSecureStorable {
}
public extension AccountBasedSecureStorable {
private var accountSecureStoragePropertyDictionary: [String: AnyObject] {
fileprivate var accountSecureStoragePropertyDictionary: [String: Any] {
return [String(kSecAttrAccount): account]
}
}
@@ -159,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
])
@@ -182,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
])
@@ -205,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])
}
}
@@ -226,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])
}
}
@@ -247,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])
}
}
@@ -267,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])
}
}
@@ -287,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])
}
}
@@ -319,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 {
@@ -332,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)
@@ -385,7 +385,7 @@ public extension InternetPasswordSecureStorableResultType {
}
var server: String {
return stringFromResultDictionary(kSecAttrServer)!
return stringFromResultDictionary(key: kSecAttrServer)!
}
var port: Int {
@@ -393,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)
}
}
@@ -421,9 +421,10 @@ 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
}
// MARK: - ReadableSecureStorable
@@ -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,19 +469,18 @@ 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
}
} catch {
print(error)
return nil
}
}
@@ -489,13 +489,12 @@ 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
}
} catch {
print(error)
return nil
}
}
@@ -511,39 +510,68 @@ public protocol DeleteableSecureStorable: SecureStorable {
// MARK: - Default property dictionaries
extension CreateableSecureStorable {
func updateInSecureStore(query: [String: Any]) throws {
var attributesToUpdate = query
attributesToUpdate[String(kSecClass)] = nil
let status = SecItemUpdate(query as CFDictionary, attributesToUpdate as CFDictionary)
if let error = LocksmithError(fromStatusCode: Int(status)) {
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(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(query: self.asCreateableSecureStoragePropertyDictionary)
}
}
@@ -556,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 -13
View File
@@ -3,37 +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:
print("SecurityClass: Invalid raw value provided. Defaulting to .GenericPassword")
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,6 +100,40 @@ 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: Any]
let account: String
let service: String
}
var create = CreateGenericPassword(data: data, account: userAccount, service: service)
try! create.createInSecureStore() // make sure it doesn't throw
create.data = ["other": "data"]
try! create.updateInSecureStore()
let read = create.readFromSecureStore()!.data as! [String: String]
XCTAssertEqual(read, ["other": "data"])
}
func testLoadForGenericPassword() {
let data = ["one": "two"]
createGenericPasswordWithData(data)
@@ -121,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)
}
@@ -129,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"]
@@ -159,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
@@ -168,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
@@ -207,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"]
@@ -239,7 +279,7 @@ class LocksmithTests: XCTestCase {
func testInternetPasswordMetaAttributesAreCreatedAndReturned() {
struct CreateInternetPassword: CreateableSecureStorable, InternetPasswordSecureStorable {
let account: String
let data: [String: AnyObject]
var data: [String: Any]
let server: String
let port: Int
let internetProtocol: LocksmithInternetProtocol
@@ -248,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"
@@ -265,25 +305,36 @@ class LocksmithTests: XCTestCase {
let authenticationType: LocksmithInternetAuthenticationType
}
let c = CreateInternetPassword(account: userAccount, data: initialData, server: server, port: port, internetProtocol: internetProtocol, authenticationType: authenticationType, path: path, securityDomain: securityDomain)
var c = CreateInternetPassword(account: userAccount, data: initialData, server: server, port: port, internetProtocol: internetProtocol, authenticationType: authenticationType, path: path, securityDomain: securityDomain)
try! c.createInSecureStore()
func assertResultMetadataIsOk(_ result: InternetPasswordSecureStorableResultType?) {
XCTAssertEqual(result?.account, userAccount)
XCTAssertEqual(result?.server, server)
XCTAssertEqual(result?.port, port)
XCTAssertEqual(result?.internetProtocol, internetProtocol)
XCTAssertEqual(result?.authenticationType, authenticationType)
XCTAssertEqual(result?.securityDomain, securityDomain)
XCTAssertEqual(result?.path, path)
}
let r = ReadInternetPassword(account: userAccount, server: server, port: port, internetProtocol: internetProtocol, authenticationType: authenticationType)
let result = r.readFromSecureStore()
XCTAssertEqual(result?.account, userAccount)
XCTAssertEqual(result!.data as! [String: String], initialData)
XCTAssertEqual(result?.server, server)
XCTAssertEqual(result?.port, port)
XCTAssertEqual(result?.internetProtocol, internetProtocol)
XCTAssertEqual(result?.authenticationType, authenticationType)
XCTAssertEqual(result?.securityDomain, securityDomain)
XCTAssertEqual(result?.path, path)
assertResultMetadataIsOk(result)
// Assert that metadata is maintained after an update
c.data = ["other internet": "junk"]
try! c.updateInSecureStore()
let result2 = r.readFromSecureStore()
XCTAssertEqual(result2!.data as! [String: String], ["other internet": "junk"])
assertResultMetadataIsOk(result2)
}
func assertStringPairsMatchInDictionary(dictionary: NSDictionary, pairs: [(key: CFString, expectedOutput: String)]) {
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)
}
}
@@ -292,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
@@ -304,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
@@ -326,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()
@@ -338,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?
@@ -355,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
@@ -386,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()
@@ -410,6 +461,6 @@ class LocksmithTests: XCTestCase {
try! create.createInSecureStore()
waitForExpectationsWithTimeout(0.1, handler: nil)
waitForExpectations(timeout: 0.1, handler: nil)
}
}