Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1039eedb31 | |||
| 23c4eff1bf | |||
| 096285a39f | |||
| 27e8863baa | |||
| 06fbc41df5 | |||
| 818938df81 | |||
| ca96ace5d0 | |||
| 70369178ec | |||
| 6e15b6ee42 | |||
| 5055c8997e | |||
| 8744bef07c | |||
| 67ded45500 | |||
| dd159e10a7 | |||
| 1b278e59a5 | |||
| 1359edf840 | |||
| 6b32c7ec68 | |||
| 80df919791 | |||
| 2f54712fda | |||
| 78060ecc28 | |||
| e04d6291d4 | |||
| c29ebcdba8 | |||
| ed56b9015c | |||
| b5f7410d0e | |||
| e002690ccf | |||
| 6ae6aaedf2 | |||
| c75cccde53 | |||
| ecef17994c | |||
| 55d9ad27a3 | |||
| 3393682ee7 | |||
| ff6e09e051 | |||
| 6298dc0ec6 | |||
| 96d1958632 | |||
| ee5351dfe9 | |||
| 2459d0c2ff | |||
| effbd18736 | |||
| bb380ebd3b | |||
| 4d9fcd7f77 | |||
| 2ed51c13e7 | |||
| 60a44fe471 | |||
| da2ea377bc | |||
| 90fb6207ae | |||
| e91be340b8 | |||
| db0802cdaf | |||
| 03ff3ae76a | |||
| f086127b46 | |||
| b36864e1da | |||
| ecd63efd8b | |||
| f3afe2d968 | |||
| b096465a33 | |||
| 157e4531f1 | |||
| 3b2523e89e | |||
| a8a1abca7b | |||
| eb4d2f8351 | |||
| f7b5ee5c57 | |||
| c6af051213 | |||
| cbcada16dc |
+19
-13
@@ -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
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
Did you know that git does not support storing empty directories?
|
||||
@@ -0,0 +1,11 @@
|
||||
//
|
||||
// ExtensionDelegate.swift
|
||||
// Locksmith Extension
|
||||
//
|
||||
// Created by Tai Heng on 12/09/2015.
|
||||
// Copyright © 2015 Matthew Palmer. All rights reserved.
|
||||
//
|
||||
|
||||
import WatchKit
|
||||
|
||||
class ExtensionDelegate: NSObject, WKExtensionDelegate {}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?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>CFBundleDisplayName</key>
|
||||
<string>Locksmith Extension</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>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionAttributes</key>
|
||||
<dict>
|
||||
<key>WKAppBundleIdentifier</key>
|
||||
<string>net.matthewpalmer.Locksmith-iOS-Example.watchkitapp</string>
|
||||
</dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.watchkit</string>
|
||||
</dict>
|
||||
<key>RemoteInterfacePrincipalClass</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).InterfaceController</string>
|
||||
<key>WKExtensionDelegateClassName</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).ExtensionDelegate</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// InterfaceController.swift
|
||||
// LocksmithExample WatchKit Extension
|
||||
//
|
||||
// Created by Tai Heng on 05/09/2015.
|
||||
// Copyright © 2015 matthewpalmer. All rights reserved.
|
||||
//
|
||||
|
||||
import WatchKit
|
||||
import Foundation
|
||||
import Locksmith
|
||||
import WatchConnectivity
|
||||
|
||||
class InterfaceController: WKInterfaceController, WCSessionDelegate {
|
||||
override func willActivate() {
|
||||
// This method is called when watch view controller is about to be visible to user
|
||||
super.willActivate()
|
||||
|
||||
if (WCSession.isSupported()) {
|
||||
let session = WCSession.default()
|
||||
session.delegate = self
|
||||
session.activate()
|
||||
}
|
||||
|
||||
struct TwitterAccount: ReadableSecureStorable, CreateableSecureStorable, DeleteableSecureStorable, GenericPasswordSecureStorable {
|
||||
let username: String
|
||||
let password: String
|
||||
|
||||
let service = "Twitter"
|
||||
|
||||
var account: String { return username }
|
||||
|
||||
var data: [String: Any] {
|
||||
return ["password": password]
|
||||
}
|
||||
}
|
||||
|
||||
let account = TwitterAccount(username: "_matthewpalmer", password: "my_password")
|
||||
|
||||
// CreateableSecureStorable lets us create the account in the keychain
|
||||
try! account.createInSecureStore()
|
||||
|
||||
// ReadableSecureStorable lets us read the account from the keychain
|
||||
let result = account.readFromSecureStore()
|
||||
|
||||
print("Watch app: \(result), \(result?.data)")
|
||||
|
||||
// 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?) {
|
||||
}
|
||||
}
|
||||
@@ -7,15 +7,62 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
056F2A731BA42E3C00B24B65 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 056F2A711BA42E3C00B24B65 /* Interface.storyboard */; };
|
||||
056F2A751BA42E3C00B24B65 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 056F2A741BA42E3C00B24B65 /* Assets.xcassets */; };
|
||||
056F2A7C1BA42E3C00B24B65 /* Locksmith Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 056F2A7B1BA42E3C00B24B65 /* Locksmith Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
056F2A811BA42E3C00B24B65 /* InterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056F2A801BA42E3C00B24B65 /* InterfaceController.swift */; };
|
||||
056F2A831BA42E3C00B24B65 /* ExtensionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 056F2A821BA42E3C00B24B65 /* ExtensionDelegate.swift */; };
|
||||
056F2A851BA42E3C00B24B65 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 056F2A841BA42E3C00B24B65 /* Assets.xcassets */; };
|
||||
056F2A891BA42E3C00B24B65 /* Locksmith.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 056F2A6F1BA42E3C00B24B65 /* Locksmith.app */; };
|
||||
056F2A941BA42FFC00B24B65 /* Locksmith.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 056F2A931BA42FFC00B24B65 /* Locksmith.framework */; };
|
||||
056F2A961BA4300700B24B65 /* Locksmith.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 056F2A951BA4300700B24B65 /* Locksmith.framework */; };
|
||||
0E13A9A41BA3EE8700A06FF9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E13A9A31BA3EE8700A06FF9 /* AppDelegate.swift */; };
|
||||
0E13A9A61BA3EE8700A06FF9 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E13A9A51BA3EE8700A06FF9 /* ViewController.swift */; };
|
||||
0E13A9A91BA3EE8700A06FF9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E13A9A71BA3EE8700A06FF9 /* Main.storyboard */; };
|
||||
0E13A9AB1BA3EE8700A06FF9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0E13A9AA1BA3EE8700A06FF9 /* Assets.xcassets */; };
|
||||
0E13A9AE1BA3EE8700A06FF9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E13A9AC1BA3EE8700A06FF9 /* LaunchScreen.storyboard */; };
|
||||
0E13A9B81BA3EFFA00A06FF9 /* Locksmith.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E13A9B71BA3EFFA00A06FF9 /* Locksmith.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
056F2A7D1BA42E3C00B24B65 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 0E13A9981BA3EE8600A06FF9 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 056F2A7A1BA42E3C00B24B65;
|
||||
remoteInfo = "Locksmith Extension";
|
||||
};
|
||||
056F2A871BA42E3C00B24B65 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 0E13A9981BA3EE8600A06FF9 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 056F2A6E1BA42E3C00B24B65;
|
||||
remoteInfo = Locksmith;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
056F2A8F1BA42E3C00B24B65 /* Embed App Extensions */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 13;
|
||||
files = (
|
||||
056F2A7C1BA42E3C00B24B65 /* Locksmith Extension.appex in Embed App Extensions */,
|
||||
);
|
||||
name = "Embed App Extensions";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
056F2A911BA42E3C00B24B65 /* Embed Watch Content */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "$(CONTENTS_FOLDER_PATH)/Watch";
|
||||
dstSubfolderSpec = 16;
|
||||
files = (
|
||||
056F2A891BA42E3C00B24B65 /* Locksmith.app in Embed Watch Content */,
|
||||
);
|
||||
name = "Embed Watch Content";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0E13A9BA1BA3F03D00A06FF9 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -28,6 +75,17 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
056F2A6F1BA42E3C00B24B65 /* Locksmith.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Locksmith.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
056F2A721BA42E3C00B24B65 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = "<group>"; };
|
||||
056F2A741BA42E3C00B24B65 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
056F2A761BA42E3C00B24B65 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
056F2A7B1BA42E3C00B24B65 /* Locksmith Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Locksmith Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
056F2A801BA42E3C00B24B65 /* InterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InterfaceController.swift; sourceTree = "<group>"; };
|
||||
056F2A821BA42E3C00B24B65 /* ExtensionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionDelegate.swift; sourceTree = "<group>"; };
|
||||
056F2A841BA42E3C00B24B65 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
056F2A861BA42E3C00B24B65 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
056F2A931BA42FFC00B24B65 /* Locksmith.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Locksmith.framework; path = "../../build/Debug-iphoneos/Locksmith.framework"; sourceTree = "<group>"; };
|
||||
056F2A951BA4300700B24B65 /* Locksmith.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Locksmith.framework; path = "../../build/Debug-watchos/Locksmith.framework"; sourceTree = "<group>"; };
|
||||
0E13A9A01BA3EE8700A06FF9 /* Locksmith iOS Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Locksmith iOS Example.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0E13A9A31BA3EE8700A06FF9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
0E13A9A51BA3EE8700A06FF9 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
||||
@@ -35,27 +93,71 @@
|
||||
0E13A9AA1BA3EE8700A06FF9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
0E13A9AD1BA3EE8700A06FF9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
0E13A9AF1BA3EE8700A06FF9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
0E13A9B71BA3EFFA00A06FF9 /* Locksmith.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Locksmith.framework; path = "../build/Debug-iphoneos/Locksmith.framework"; sourceTree = "<group>"; };
|
||||
15FCF62F6935D11C671F41FF /* Pods_app.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_app.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
1D62CFE6D2814693AE03CF5C /* Pods_watch.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_watch.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
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 */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
056F2A781BA42E3C00B24B65 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
056F2A961BA4300700B24B65 /* Locksmith.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0E13A99D1BA3EE8700A06FF9 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0E13A9B81BA3EFFA00A06FF9 /* Locksmith.framework in Frameworks */,
|
||||
056F2A941BA42FFC00B24B65 /* Locksmith.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
056F2A701BA42E3C00B24B65 /* Locksmith */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
056F2A711BA42E3C00B24B65 /* Interface.storyboard */,
|
||||
056F2A741BA42E3C00B24B65 /* Assets.xcassets */,
|
||||
056F2A761BA42E3C00B24B65 /* Info.plist */,
|
||||
);
|
||||
path = Locksmith;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
056F2A7F1BA42E3C00B24B65 /* Locksmith Extension */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
056F2A801BA42E3C00B24B65 /* InterfaceController.swift */,
|
||||
056F2A821BA42E3C00B24B65 /* ExtensionDelegate.swift */,
|
||||
056F2A841BA42E3C00B24B65 /* Assets.xcassets */,
|
||||
056F2A861BA42E3C00B24B65 /* Info.plist */,
|
||||
);
|
||||
path = "Locksmith Extension";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0E13A9971BA3EE8600A06FF9 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0E13A9B71BA3EFFA00A06FF9 /* Locksmith.framework */,
|
||||
0E13A9A21BA3EE8700A06FF9 /* Locksmith iOS Example */,
|
||||
056F2A701BA42E3C00B24B65 /* Locksmith */,
|
||||
056F2A7F1BA42E3C00B24B65 /* Locksmith Extension */,
|
||||
E3DD3B1F1D84354F00A59312 /* Test Host */,
|
||||
0E13A9A11BA3EE8700A06FF9 /* Products */,
|
||||
74B88A8534E794C2027D6B3D /* Pods */,
|
||||
D1E3110F9ED1A0EE737E7A37 /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@@ -63,6 +165,8 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0E13A9A01BA3EE8700A06FF9 /* Locksmith iOS Example.app */,
|
||||
056F2A6F1BA42E3C00B24B65 /* Locksmith.app */,
|
||||
056F2A7B1BA42E3C00B24B65 /* Locksmith Extension.appex */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -80,9 +184,78 @@
|
||||
path = "Locksmith iOS Example";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
74B88A8534E794C2027D6B3D /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FFB6EBF2507E751B53E55514 /* Pods-app.debug.xcconfig */,
|
||||
8D5C601685F38F2EA6AA2CA0 /* Pods-app.release.xcconfig */,
|
||||
74E67F961D2CBE4F8D171223 /* Pods-watch.debug.xcconfig */,
|
||||
379DD1E5C8CDE5ABD6E50A38 /* Pods-watch.release.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D1E3110F9ED1A0EE737E7A37 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
056F2A951BA4300700B24B65 /* Locksmith.framework */,
|
||||
056F2A931BA42FFC00B24B65 /* Locksmith.framework */,
|
||||
15FCF62F6935D11C671F41FF /* Pods_app.framework */,
|
||||
1D62CFE6D2814693AE03CF5C /* Pods_watch.framework */,
|
||||
);
|
||||
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 */
|
||||
056F2A6E1BA42E3C00B24B65 /* Locksmith */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 056F2A901BA42E3C00B24B65 /* Build configuration list for PBXNativeTarget "Locksmith" */;
|
||||
buildPhases = (
|
||||
056F2A6D1BA42E3C00B24B65 /* Resources */,
|
||||
056F2A8F1BA42E3C00B24B65 /* Embed App Extensions */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
056F2A7E1BA42E3C00B24B65 /* PBXTargetDependency */,
|
||||
);
|
||||
name = Locksmith;
|
||||
productName = Locksmith;
|
||||
productReference = 056F2A6F1BA42E3C00B24B65 /* Locksmith.app */;
|
||||
productType = "com.apple.product-type.application.watchapp2";
|
||||
};
|
||||
056F2A7A1BA42E3C00B24B65 /* Locksmith Extension */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 056F2A8E1BA42E3C00B24B65 /* Build configuration list for PBXNativeTarget "Locksmith Extension" */;
|
||||
buildPhases = (
|
||||
056F2A771BA42E3C00B24B65 /* Sources */,
|
||||
056F2A781BA42E3C00B24B65 /* Frameworks */,
|
||||
056F2A791BA42E3C00B24B65 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "Locksmith Extension";
|
||||
productName = "Locksmith Extension";
|
||||
productReference = 056F2A7B1BA42E3C00B24B65 /* Locksmith Extension.appex */;
|
||||
productType = "com.apple.product-type.watchkit2-extension";
|
||||
};
|
||||
0E13A99F1BA3EE8700A06FF9 /* Locksmith iOS Example */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 0E13A9B21BA3EE8700A06FF9 /* Build configuration list for PBXNativeTarget "Locksmith iOS Example" */;
|
||||
@@ -91,10 +264,12 @@
|
||||
0E13A99D1BA3EE8700A06FF9 /* Frameworks */,
|
||||
0E13A99E1BA3EE8700A06FF9 /* Resources */,
|
||||
0E13A9BA1BA3F03D00A06FF9 /* CopyFiles */,
|
||||
056F2A911BA42E3C00B24B65 /* Embed Watch Content */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
056F2A881BA42E3C00B24B65 /* PBXTargetDependency */,
|
||||
);
|
||||
name = "Locksmith iOS Example";
|
||||
productName = "Locksmith iOS Example";
|
||||
@@ -107,9 +282,16 @@
|
||||
0E13A9981BA3EE8600A06FF9 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0700;
|
||||
LastSwiftUpdateCheck = 0800;
|
||||
LastUpgradeCheck = 0800;
|
||||
ORGANIZATIONNAME = "Matthew Palmer";
|
||||
TargetAttributes = {
|
||||
056F2A6E1BA42E3C00B24B65 = {
|
||||
CreatedOnToolsVersion = 7.0;
|
||||
};
|
||||
056F2A7A1BA42E3C00B24B65 = {
|
||||
CreatedOnToolsVersion = 7.0;
|
||||
};
|
||||
0E13A99F1BA3EE8700A06FF9 = {
|
||||
CreatedOnToolsVersion = 7.0;
|
||||
};
|
||||
@@ -129,11 +311,30 @@
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
0E13A99F1BA3EE8700A06FF9 /* Locksmith iOS Example */,
|
||||
056F2A6E1BA42E3C00B24B65 /* Locksmith */,
|
||||
056F2A7A1BA42E3C00B24B65 /* Locksmith Extension */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
056F2A6D1BA42E3C00B24B65 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
056F2A751BA42E3C00B24B65 /* Assets.xcassets in Resources */,
|
||||
056F2A731BA42E3C00B24B65 /* Interface.storyboard in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
056F2A791BA42E3C00B24B65 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
056F2A851BA42E3C00B24B65 /* Assets.xcassets in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0E13A99E1BA3EE8700A06FF9 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -147,6 +348,15 @@
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
056F2A771BA42E3C00B24B65 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
056F2A831BA42E3C00B24B65 /* ExtensionDelegate.swift in Sources */,
|
||||
056F2A811BA42E3C00B24B65 /* InterfaceController.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0E13A99C1BA3EE8700A06FF9 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -158,7 +368,28 @@
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
056F2A7E1BA42E3C00B24B65 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 056F2A7A1BA42E3C00B24B65 /* Locksmith Extension */;
|
||||
targetProxy = 056F2A7D1BA42E3C00B24B65 /* PBXContainerItemProxy */;
|
||||
};
|
||||
056F2A881BA42E3C00B24B65 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 056F2A6E1BA42E3C00B24B65 /* Locksmith */;
|
||||
targetProxy = 056F2A871BA42E3C00B24B65 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
056F2A711BA42E3C00B24B65 /* Interface.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
056F2A721BA42E3C00B24B65 /* Base */,
|
||||
);
|
||||
name = Interface.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0E13A9A71BA3EE8700A06FF9 /* Main.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
@@ -175,9 +406,90 @@
|
||||
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;
|
||||
IBSC_MODULE = Locksmith_Extension;
|
||||
INFOPLIST_FILE = Locksmith/Info.plist;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-iOS-Example.watchkitapp";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = watchos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 2.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
056F2A8B1BA42E3C00B24B65 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
IBSC_MODULE = Locksmith_Extension;
|
||||
INFOPLIST_FILE = Locksmith/Info.plist;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-iOS-Example.watchkitapp";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = watchos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 2.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
056F2A8C1BA42E3C00B24B65 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 74E67F961D2CBE4F8D171223 /* Pods-watch.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
INFOPLIST_FILE = "Locksmith Extension/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-iOS-Example.watchkitapp.watchkitextension";
|
||||
PRODUCT_NAME = "${TARGET_NAME}";
|
||||
SDKROOT = watchos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 3.0;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 2.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
056F2A8D1BA42E3C00B24B65 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 379DD1E5C8CDE5ABD6E50A38 /* Pods-watch.release.xcconfig */;
|
||||
buildSettings = {
|
||||
INFOPLIST_FILE = "Locksmith Extension/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-iOS-Example.watchkitapp.watchkitextension";
|
||||
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;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
0E13A9B01BA3EE8700A06FF9 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@@ -263,6 +575,7 @@
|
||||
};
|
||||
0E13A9B31BA3EE8700A06FF9 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = FFB6EBF2507E751B53E55514 /* Pods-app.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
INFOPLIST_FILE = "Locksmith iOS Example/Info.plist";
|
||||
@@ -270,11 +583,13 @@
|
||||
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;
|
||||
};
|
||||
0E13A9B41BA3EE8700A06FF9 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 8D5C601685F38F2EA6AA2CA0 /* Pods-app.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
INFOPLIST_FILE = "Locksmith iOS Example/Info.plist";
|
||||
@@ -282,12 +597,32 @@
|
||||
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;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
056F2A8E1BA42E3C00B24B65 /* Build configuration list for PBXNativeTarget "Locksmith Extension" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
056F2A8C1BA42E3C00B24B65 /* Debug */,
|
||||
056F2A8D1BA42E3C00B24B65 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
056F2A901BA42E3C00B24B65 /* Build configuration list for PBXNativeTarget "Locksmith" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
056F2A8A1BA42E3C00B24B65 /* Debug */,
|
||||
056F2A8B1BA42E3C00B24B65 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
0E13A99B1BA3EE8600A06FF9 /* Build configuration list for PBXProject "Locksmith iOS Example" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
LastUpgradeVersion = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -11,20 +11,18 @@ import Locksmith
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
|
||||
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
|
||||
struct TwitterAccount: ReadableSecureStorable,
|
||||
CreateableSecureStorable,
|
||||
DeleteableSecureStorable,
|
||||
GenericPasswordSecureStorable {
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
|
||||
struct TwitterAccount: ReadableSecureStorable, CreateableSecureStorable, DeleteableSecureStorable, GenericPasswordSecureStorable {
|
||||
let username: String
|
||||
let password: String
|
||||
|
||||
let service = "Twitter"
|
||||
|
||||
var account: String { return username }
|
||||
var data: [String: AnyObject] {
|
||||
|
||||
var data: [String: Any] {
|
||||
return ["password": password]
|
||||
}
|
||||
}
|
||||
@@ -37,7 +35,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
// ReadableSecureStorable lets us read the account from the keychain
|
||||
let result = account.readFromSecureStore()
|
||||
|
||||
print("Result: \(result) \(result?.data)")
|
||||
print("iOS app: \(result), \(result?.data)")
|
||||
|
||||
// DeleteableSecureStorable lets us delete the account from the keychain
|
||||
try! account.deleteFromSecureStore()
|
||||
|
||||
@@ -1,40 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8173.3" systemVersion="14F27" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8173.3" systemVersion="14F27" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="kvZ-1V-3wx">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8142"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<!--Locksmith Example-->
|
||||
<scene sceneID="DFV-sl-Fly">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="Locksmith_iOS_Example" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<viewController title="Locksmith Example" id="kvZ-1V-3wx" customClass="ViewController" customModule="Locksmith_iOS_Example" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
<viewControllerLayoutGuide type="top" id="Jdi-8X-X7l"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="xfR-hD-RHw"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<view key="view" contentMode="scaleToFill" id="tK0-bv-krV">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Locksmith Example—see AppDelegate.swift" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mhD-FU-PNz">
|
||||
<rect key="frame" x="132" y="289" width="337" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="wfy-db-euE" firstAttribute="top" secondItem="mhD-FU-PNz" secondAttribute="bottom" constant="290" id="0ha-lJ-FNO"/>
|
||||
<constraint firstItem="mhD-FU-PNz" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" constant="112" id="3eM-ve-Fq1"/>
|
||||
<constraint firstItem="mhD-FU-PNz" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" constant="269" id="ZCS-J6-lWh"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="mhD-FU-PNz" secondAttribute="trailing" constant="111" id="o19-IS-K4H"/>
|
||||
</constraints>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="zND-74-PgH" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="347" y="447"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"size" : "24x24",
|
||||
"idiom" : "watch",
|
||||
"scale" : "2x",
|
||||
"role" : "notificationCenter",
|
||||
"subtype" : "38mm"
|
||||
},
|
||||
{
|
||||
"size" : "27.5x27.5",
|
||||
"idiom" : "watch",
|
||||
"scale" : "2x",
|
||||
"role" : "notificationCenter",
|
||||
"subtype" : "42mm"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "watch",
|
||||
"role" : "companionSettings",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "watch",
|
||||
"role" : "companionSettings",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "watch",
|
||||
"scale" : "2x",
|
||||
"role" : "appLauncher",
|
||||
"subtype" : "38mm"
|
||||
},
|
||||
{
|
||||
"size" : "44x44",
|
||||
"idiom" : "watch",
|
||||
"scale" : "2x",
|
||||
"role" : "longLook",
|
||||
"subtype" : "42mm"
|
||||
},
|
||||
{
|
||||
"size" : "86x86",
|
||||
"idiom" : "watch",
|
||||
"scale" : "2x",
|
||||
"role" : "quickLook",
|
||||
"subtype" : "38mm"
|
||||
},
|
||||
{
|
||||
"size" : "98x98",
|
||||
"idiom" : "watch",
|
||||
"scale" : "2x",
|
||||
"role" : "quickLook",
|
||||
"subtype" : "42mm"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder.WatchKit.Storyboard" version="3.0" toolsVersion="8173.3" systemVersion="14F27" targetRuntime="watchKit" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="AgC-eL-Hgc">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8142"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBWatchKitPlugin" version="8089"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Interface Controller-->
|
||||
<scene sceneID="aou-V4-d1y">
|
||||
<objects>
|
||||
<controller id="AgC-eL-Hgc" customClass="InterfaceController" customModule="Locksmith" customModuleProvider="target">
|
||||
<items>
|
||||
<label width="136" alignment="left" text="Locksmith" id="0hb-l0-xFa"/>
|
||||
</items>
|
||||
</controller>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="220" y="345"/>
|
||||
</scene>
|
||||
<!--Static Notification Interface Controller-->
|
||||
<scene sceneID="AEw-b0-oYE">
|
||||
<objects>
|
||||
<notificationController id="YCC-NB-fut">
|
||||
<items>
|
||||
<label alignment="left" text="Alert Label" id="IdU-wH-bcW"/>
|
||||
</items>
|
||||
<notificationCategory key="notificationCategory" identifier="myCategory" id="JfB-70-Muf"/>
|
||||
<connections>
|
||||
<outlet property="notificationAlertLabel" destination="IdU-wH-bcW" id="JKC-fr-R95"/>
|
||||
<segue destination="4sK-HA-Art" kind="relationship" relationship="dynamicNotificationInterface" id="kXh-Jw-8B1"/>
|
||||
</connections>
|
||||
</notificationController>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="220" y="643"/>
|
||||
</scene>
|
||||
<!--Notification Controller-->
|
||||
<scene sceneID="ZPc-GJ-vnh">
|
||||
<objects>
|
||||
<controller id="4sK-HA-Art" customClass="NotificationController" customModule="Locksmith" customModuleProvider="target"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="468" y="643"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?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>CFBundleDisplayName</key>
|
||||
<string>Locksmith iOS Example</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>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
</array>
|
||||
<key>WKCompanionAppBundleIdentifier</key>
|
||||
<string>net.matthewpalmer.Locksmith-iOS-Example</string>
|
||||
<key>WKWatchKitApp</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -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:.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+68
@@ -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.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "Locksmith"
|
||||
s.version = "2.0.1"
|
||||
s.version = "2.0.8"
|
||||
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.
|
||||
@@ -14,6 +14,7 @@ Pod::Spec.new do |s|
|
||||
s.ios.deployment_target = '8.0'
|
||||
s.osx.deployment_target = '10.10'
|
||||
s.watchos.deployment_target = '2.0'
|
||||
s.tvos.deployment_target = '9.0'
|
||||
|
||||
s.requires_arc = true
|
||||
|
||||
|
||||
@@ -7,6 +7,13 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
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 */; };
|
||||
@@ -25,7 +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 */
|
||||
@@ -43,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 */
|
||||
@@ -61,6 +90,16 @@
|
||||
0EC25C9D1BA389BD004191AF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
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 */
|
||||
@@ -101,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 */
|
||||
@@ -108,6 +161,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0EC25C401BA38539004191AF /* Dictionary_Initializers.swift */,
|
||||
DF6BD4B61BB051ED00A3EB64 /* Locksmith.h */,
|
||||
0EC25C421BA38539004191AF /* Locksmith.swift */,
|
||||
0EC25C431BA38539004191AF /* LocksmithAccessibleOption.swift */,
|
||||
0EC25C441BA38539004191AF /* LocksmithError.swift */,
|
||||
@@ -149,6 +203,7 @@
|
||||
children = (
|
||||
0EC25C481BA38539004191AF /* Source */,
|
||||
0EC25C4A1BA38539004191AF /* Tests */,
|
||||
E3DD3B351D84356500A59312 /* Test Host */,
|
||||
BFFB19D11A4870A300CCFFC3 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
@@ -161,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 */
|
||||
@@ -172,6 +243,7 @@
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
DF6BD4BD1BB054D400A3EB64 /* Locksmith.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -179,6 +251,7 @@
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
DF6BD4BC1BB054CB00A3EB64 /* Locksmith.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -186,6 +259,15 @@
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
DF6BD4B91BB0524500A3EB64 /* Locksmith.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
FBD0C9461C1866BE00291F2A /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FBD0C9521C18693900291F2A /* Locksmith.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -222,6 +304,7 @@
|
||||
);
|
||||
dependencies = (
|
||||
0EC25C651BA385AB004191AF /* PBXTargetDependency */,
|
||||
E3DD3B481D84360300A59312 /* PBXTargetDependency */,
|
||||
);
|
||||
name = "Locksmith iOS Tests";
|
||||
productName = "Locksmith iOSTests";
|
||||
@@ -282,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 = 0800;
|
||||
ORGANIZATIONNAME = "Mathew Palmer";
|
||||
TargetAttributes = {
|
||||
0EC25C581BA385AA004191AF = {
|
||||
CreatedOnToolsVersion = 7.0;
|
||||
LastSwiftMigration = 0800;
|
||||
};
|
||||
0EC25C611BA385AB004191AF = {
|
||||
CreatedOnToolsVersion = 7.0;
|
||||
LastSwiftMigration = 0800;
|
||||
TestTargetID = E3DD3B331D84356500A59312;
|
||||
};
|
||||
0EC25C741BA385F6004191AF = {
|
||||
CreatedOnToolsVersion = 7.0;
|
||||
@@ -307,6 +428,18 @@
|
||||
0EC25CA61BA39C9F004191AF = {
|
||||
CreatedOnToolsVersion = 7.0;
|
||||
};
|
||||
E3DD3B331D84356500A59312 = {
|
||||
CreatedOnToolsVersion = 8.0;
|
||||
ProvisioningStyle = Automatic;
|
||||
SystemCapabilities = {
|
||||
com.apple.Keychain = {
|
||||
enabled = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
FBD0C9481C1866BE00291F2A = {
|
||||
CreatedOnToolsVersion = 7.2;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = BFFB19CA1A4870A300CCFFC3 /* Build configuration list for PBXProject "Locksmith" */;
|
||||
@@ -315,6 +448,7 @@
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = BFFB19C61A4870A300CCFFC3;
|
||||
productRefGroup = BFFB19D11A4870A300CCFFC3 /* Products */;
|
||||
@@ -326,6 +460,8 @@
|
||||
0EC25C741BA385F6004191AF /* Locksmith OS X */,
|
||||
0EC25C7D1BA385F6004191AF /* Locksmith OS X Tests */,
|
||||
0EC25CA61BA39C9F004191AF /* Locksmith watchOS */,
|
||||
FBD0C9481C1866BE00291F2A /* Locksmith tvOS */,
|
||||
E3DD3B331D84356500A59312 /* Test Host */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@@ -335,7 +471,6 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0EC25C9F1BA389CB004191AF /* Info.plist in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -367,6 +502,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 */
|
||||
@@ -418,6 +570,36 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
056F2A991BA4316700B24B65 /* LocksmithAccessibleOption.swift in Sources */,
|
||||
056F2A9D1BA4316700B24B65 /* LocksmithSecurityClass.swift in Sources */,
|
||||
056F2A981BA4316700B24B65 /* Locksmith.swift in Sources */,
|
||||
056F2A971BA4316700B24B65 /* Dictionary_Initializers.swift in Sources */,
|
||||
056F2A9A1BA4316700B24B65 /* LocksmithError.swift in Sources */,
|
||||
056F2A9B1BA4316700B24B65 /* LocksmithInternetAuthenticationType.swift in Sources */,
|
||||
056F2A9C1BA4316700B24B65 /* LocksmithInternetProtocol.swift in Sources */,
|
||||
);
|
||||
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;
|
||||
};
|
||||
@@ -434,8 +616,32 @@
|
||||
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;
|
||||
@@ -454,6 +660,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-iOS";
|
||||
PRODUCT_NAME = Locksmith;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 3.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -474,6 +681,8 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-iOS";
|
||||
PRODUCT_NAME = Locksmith;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_VERSION = 3.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -488,6 +697,8 @@
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-iOSTests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 3.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Test Host.app/Test Host";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -502,6 +713,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 = 3.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Test Host.app/Test Host";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -525,6 +739,7 @@
|
||||
PRODUCT_NAME = Locksmith;
|
||||
SDKROOT = macosx;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 3.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -548,6 +763,8 @@
|
||||
PRODUCT_NAME = Locksmith;
|
||||
SDKROOT = macosx;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_VERSION = 3.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -564,6 +781,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-OS-XTests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
SWIFT_VERSION = 3.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -580,6 +798,8 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "net.matthewpalmer.Locksmith-OS-XTests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_VERSION = 3.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -599,6 +819,7 @@
|
||||
PRODUCT_NAME = Locksmith;
|
||||
SDKROOT = watchos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 3.0;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 2.0;
|
||||
};
|
||||
@@ -621,6 +842,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;
|
||||
};
|
||||
@@ -650,6 +873,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",
|
||||
@@ -698,6 +922,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;
|
||||
@@ -716,6 +941,99 @@
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
E3DD3B431D84356600A59312 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
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 = 3.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
E3DD3B441D84356600A59312 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
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 = 3.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
FBD0C94E1C1866BE00291F2A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BITCODE_GENERATION_MODE = bitcode;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_BITCODE = YES;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INFOPLIST_FILE = Source/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
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;
|
||||
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 */
|
||||
@@ -762,6 +1080,7 @@
|
||||
0EC25CAD1BA39CA0004191AF /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
BFFB19CA1A4870A300CCFFC3 /* Build configuration list for PBXProject "Locksmith" */ = {
|
||||
isa = XCConfigurationList;
|
||||
@@ -772,6 +1091,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 = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
LastUpgradeVersion = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
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"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
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 = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -5,7 +5,7 @@ A powerful, protocol-oriented library for working with the keychain in Swift.
|
||||
- [x] 📱 iOS 8.0+
|
||||
- [x] 💻 Mac OS X 10.10+
|
||||
- [x] ⌚️ watchOS 2
|
||||
- [ ] 📺 tvOS (*coming soon?*)
|
||||
- [x] 📺 tvOS
|
||||
|
||||
How is Locksmith different to other keychain wrappers?
|
||||
|
||||
@@ -28,6 +28,12 @@ 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
|
||||
|
||||
**Save data**
|
||||
@@ -365,7 +371,7 @@ public enum LocksmithAccessibleOption {
|
||||
|
||||
#### `LocksmithError`
|
||||
|
||||
`LocksmithError` provides Swift-friendly translations of common keychain error codes. These are thrown from methods throughout the library.
|
||||
`LocksmithError` provides Swift-friendly translations of common keychain error codes. These are thrown from methods throughout the library. [Apple’s documentation](https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices/#//apple_ref/c/econst/errSecSuccess) provides more information on these errors.
|
||||
|
||||
```swift
|
||||
public enum LocksmithError: ErrorType {
|
||||
@@ -388,7 +394,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`.
|
||||
`LocksmithInternetAuthenticationType` lets you pick out the type of authentication you want to store alongside your `.InternetPassword`s—anything from `.MSN` to `.HTTPDigest`. [Apple’s 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 +411,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.
|
||||
`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. [Apple’s 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
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<string>2.1</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
FOUNDATION_EXPORT double LocksmithVersionNumber;
|
||||
FOUNDATION_EXPORT const unsigned char LocksmithVersionString[];
|
||||
+103
-71
@@ -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])
|
||||
}
|
||||
}
|
||||
@@ -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,16 +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 {
|
||||
let result = try performSecureStorageAction(performReadRequestClosure, secureStoragePropertyDictionary: asReadableSecureStoragePropertyDictionary)
|
||||
return GenericPasswordResult(resultDictionary: result!)
|
||||
if let result = try performSecureStorageAction(closure: performReadRequestClosure, secureStoragePropertyDictionary: asReadableSecureStoragePropertyDictionary) {
|
||||
return GenericPasswordResult(resultDictionary: result)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
} catch {
|
||||
print(error)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -486,10 +489,12 @@ public extension ReadableSecureStorable where Self : GenericPasswordSecureStorab
|
||||
public extension ReadableSecureStorable where Self : InternetPasswordSecureStorable {
|
||||
func readFromSecureStore() -> InternetPasswordSecureStorableResultType? {
|
||||
do {
|
||||
let result = try performSecureStorageAction(performReadRequestClosure, secureStoragePropertyDictionary: asReadableSecureStoragePropertyDictionary)
|
||||
return InternetPasswordResult(resultDictionary: result!)
|
||||
if let result = try performSecureStorageAction(closure: performReadRequestClosure, secureStoragePropertyDictionary: asReadableSecureStoragePropertyDictionary) {
|
||||
return InternetPasswordResult(resultDictionary: result)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
} catch {
|
||||
print(error)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -505,39 +510,66 @@ 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) { SecItemAdd(requestReference, UnsafeMutablePointer($0)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -550,49 +582,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]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -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,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>
|
||||
@@ -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.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+109
-58
@@ -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,7 +377,7 @@ class LocksmithTests: XCTestCase {
|
||||
(kSecClass, String(kSecClassInternetPassword))
|
||||
])
|
||||
|
||||
let p = dict[String(kSecAttrPort)] as! CFNumberRef
|
||||
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
|
||||
let cr = dict[String(kSecAttrCreator)] as! CFNumber
|
||||
XCTAssertEqual(cr as UInt, creator)
|
||||
|
||||
let ty = dict[String(kSecAttrType)] as! CFNumberRef
|
||||
let ty = dict[String(kSecAttrType)] as! CFNumber
|
||||
XCTAssertEqual(ty as UInt, type)
|
||||
|
||||
let inv = dict[String(kSecAttrIsInvisible)] as! CFBooleanRef
|
||||
let inv = dict[String(kSecAttrIsInvisible)] as! CFBoolean
|
||||
XCTAssertEqual(inv as Bool, isInvisible)
|
||||
|
||||
let neg = dict[String(kSecAttrIsNegative)] as! CFBooleanRef
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user