Compare commits

..

33 Commits

Author SHA1 Message Date
Matthew Palmer e7ece35421 Update README.md 2015-08-31 21:29:27 +10:00
Matthew Palmer 8dd3200ae3 Update README.md 2015-08-31 21:28:39 +10:00
Matthew Palmer 48f008a26e Update README.md 2015-08-11 22:30:00 +10:00
Matthew Palmer 0dda3a7208 Update README.md
Add note on Swift 2 support
2015-06-23 07:42:03 +10:00
Matthew Palmer c218c1fbea Add note on running tests 2015-05-24 09:34:49 +10:00
Matthew Palmer 68515bdc2c Merge pull request #34 from larslockefeer/CarthageSupport
Fixed some leftover Carthage issues
2015-05-24 09:05:42 +10:00
Lars Lockefeer f38046bb9e Added Info.plist file 2015-05-23 12:50:51 +02:00
Lars Lockefeer e804dd0452 Set deployment target to iOS 8.0 2015-05-22 17:52:26 +02:00
Matthew Palmer 04c6084a8f Merge pull request #33 from larslockefeer/CarthageSupport
Carthage support
2015-05-22 21:05:24 +10:00
Lars Lockefeer fbc549973b Made the xcode scheme shared for Carthage support 2015-05-21 18:30:19 +02:00
Lars Lockefeer 4ad7ca14e6 Made LocksmithDefaultService resilient against absent plist keys 2015-05-21 18:26:06 +02:00
Lars Lockefeer 582f74e305 Updated the tests
The signature of some methods in `Locksmith.swift` was updated, but the
tests weren’t. This commit updates the tests such that they resemble
the API exposed by `Locksmith.swift` again.
2015-05-21 18:25:38 +02:00
Lars Lockefeer 1758691bc2 Restored the project file
The main project file was still based on the Project Structure before
the addition of Cocoapods support. It has now been restored, such that
the project can be opened and compiled
2015-05-21 18:24:03 +02:00
Matthew Palmer 2a21d9d0d1 Merge pull request #30 from matthewpalmer/1.2.1
Update podspec and tests for latest version
2015-04-10 10:18:17 +10:00
matthewpalmer ca70968264 Update podspec and tests for latest version 2015-04-10 10:15:08 +10:00
Matthew Palmer 8017ad0d4e Merge pull request #29 from matthewpalmer/1.2.1
Update README and podspec for 1.2.1
2015-04-10 09:21:46 +10:00
matthewpalmer e77cffad00 Update README and podspec for 1.2.1 2015-04-10 09:18:45 +10:00
matthewpalmer 8d825ab368 Add Swift 1.2 support
Merge branch 'ChaosCoder-master'

* ChaosCoder-master:
  Converted to Swift 1.2
  Trying to fix travis builds
  removing comments
  public'ing all the things
  kSecAttrAccessible
  Update README.md
  Update README.md
  Remove false Travis badge
2015-04-10 08:53:54 +10:00
Andreas Ganske fb4030034d Converted to Swift 1.2 2015-02-11 22:51:53 +01:00
Matthew Palmer 8f21125a77 Trying to fix travis builds 2015-02-04 14:01:02 +11:00
Matthew Palmer 3d6ce4d5f0 Merge pull request #24 from marcelofabri/kSecAttrAccessible
Adding support for kSecAttrAccessible
2015-02-04 13:58:35 +11:00
Marcelo Fabri 4caf3e99b4 removing comments 2015-02-03 23:48:58 -02:00
Marcelo Fabri d04d2fe9b7 public'ing all the things 2015-02-03 23:48:33 -02:00
Marcelo Fabri 440de6f490 kSecAttrAccessible 2015-02-03 23:26:50 -02:00
Matthew Palmer 658233b596 Update README.md 2015-02-03 16:30:22 +11:00
Matthew Palmer 4246e19952 Update README.md 2015-01-28 21:13:33 +11:00
Matthew Palmer b988530bce Remove false Travis badge 2015-01-28 21:12:50 +11:00
Matthew Palmer 73d14afcfa Merge pull request #18 from matthewpalmer/1.2.0
1.2.0
2015-01-28 21:06:45 +11:00
matthewpalmer c8a14a87b0 Attempt to fix travis build 2015-01-28 21:04:18 +11:00
matthewpalmer 73074c7755 Remove old files
Cleanup for release
2015-01-28 21:02:08 +11:00
matthewpalmer 480c51f0bc Update pods to specify 1.2.0 2015-01-28 21:00:31 +11:00
matthewpalmer 780e9afe24 Pre push commit 2015-01-28 20:50:33 +11:00
matthewpalmer a64c1d9dc7 Updated to allow for default services.
Note that this commit comes after a gruelling battle with git and Xcode,
so stuff might get weird
2015-01-28 20:46:17 +11:00
34 changed files with 2743 additions and 7516 deletions
+2 -2
View File
@@ -2,7 +2,7 @@
# * http://www.objc.io/issue-6/travis-ci.html
# * https://github.com/supermarin/xcpretty#usage
language: objective-c
language: swift
# cache: cocoapods
# podfile: Example/Podfile
# before_install:
@@ -11,5 +11,5 @@ language: objective-c
install:
- gem install xcpretty --no-rdoc --no-ri --no-document --quiet
script:
- set -o pipefail && xcodebuild test -workspace Example/Locksmith.xcworkspace -scheme Locksmith-Example -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO | xcpretty -c
- set -o pipefail && xcodebuild test -workspace Example/Locksmith.xcworkspace -scheme Locksmith -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO | xcpretty -c
- pod lib lint --quick
File diff suppressed because it is too large Load Diff
+2
View File
@@ -1,5 +1,7 @@
source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
platform :ios, '8.0'
target 'Locksmith', :exclusive => true do
+6 -6
View File
@@ -1,6 +1,6 @@
PODS:
- Expecta (0.3.1)
- Locksmith (1.1.1)
- Locksmith (1.2.1)
- Specta (0.2.1)
DEPENDENCIES:
@@ -10,11 +10,11 @@ DEPENDENCIES:
EXTERNAL SOURCES:
Locksmith:
:path: ../
:path: "../"
SPEC CHECKSUMS:
Expecta: 03aabd0a89d8dea843baecb19a7fd7466a69a31d
Locksmith: c2b5a219b27d0317b71a7b1a70f0148cee03a9f6
Specta: 9141310f46b1f68b676650ff2854e1ed0b74163a
Expecta: a354d4633409dd9fe8c4f5ff5130426adbe31628
Locksmith: 770f6c5c6e5c5c712d1f00e709c62b8a7240c716
Specta: 15a276a6343867b426d5ed135d5aa4d04123a573
COCOAPODS: 0.36.0.beta.1
COCOAPODS: 0.36.3
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "Locksmith",
"version": "1.1.1",
"version": "1.2.1",
"summary": "Locksmith is a sane way to work with the iOS Keychain in Swift.",
"description": " Locksmith is a sane way to work with the iOS Keychain in Swift.\n It provides a fast and intuitive way to work with the C Keychain API.\n Results are provided as tuples, and errors are informative and easily detected.\n",
"homepage": "https://github.com/matthewpalmer/Locksmith",
@@ -10,7 +10,7 @@
},
"source": {
"git": "https://github.com/matthewpalmer/Locksmith.git",
"tag": "1.1.1"
"tag": "1.2.1"
},
"social_media_url": "https://twitter.com/_matthewpalmer",
"platforms": {
+6 -6
View File
@@ -1,6 +1,6 @@
PODS:
- Expecta (0.3.1)
- Locksmith (1.1.1)
- Locksmith (1.2.1)
- Specta (0.2.1)
DEPENDENCIES:
@@ -10,11 +10,11 @@ DEPENDENCIES:
EXTERNAL SOURCES:
Locksmith:
:path: ../
:path: "../"
SPEC CHECKSUMS:
Expecta: 03aabd0a89d8dea843baecb19a7fd7466a69a31d
Locksmith: c2b5a219b27d0317b71a7b1a70f0148cee03a9f6
Specta: 9141310f46b1f68b676650ff2854e1ed0b74163a
Expecta: a354d4633409dd9fe8c4f5ff5130426adbe31628
Locksmith: 770f6c5c6e5c5c712d1f00e709c62b8a7240c716
Specta: 15a276a6343867b426d5ed135d5aa4d04123a573
COCOAPODS: 0.36.0.beta.1
COCOAPODS: 0.36.3
+1746 -6211
View File
File diff suppressed because it is too large Load Diff
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.1.1</string>
<string>1.2.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
@@ -4,6 +4,7 @@ FRAMEWORK_SEARCH_PATHS = "$PODS_FRAMEWORK_BUILD_PATH"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Locksmith" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Expecta" "${PODS_ROOT}/Headers/Public/Locksmith" "${PODS_ROOT}/Headers/Public/Specta"
OTHER_LDFLAGS = ${PODS_LOCKSMITH_LOCKSMITH_OTHER_LDFLAGS} -ObjC
OTHER_SWIFT_FLAGS = "-D COCOAPODS"
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-Locksmith
PODS_ROOT = ${SRCROOT}
PODS_ROOT = ${SRCROOT}
SKIP_INSTALL = YES
@@ -9,6 +9,6 @@
// Locksmith
#define COCOAPODS_POD_AVAILABLE_Locksmith
#define COCOAPODS_VERSION_MAJOR_Locksmith 1
#define COCOAPODS_VERSION_MINOR_Locksmith 1
#define COCOAPODS_VERSION_MINOR_Locksmith 2
#define COCOAPODS_VERSION_PATCH_Locksmith 1
@@ -11,7 +11,7 @@ install_framework()
local source="${BUILT_PRODUCTS_DIR}/Pods-Locksmith/$1"
local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [ -L ${source} ]; then
if [ -L "${source}" ]; then
echo "Symlinked..."
source=$(readlink "${source}")
fi
@@ -28,10 +28,13 @@ install_framework()
local basename
basename=$(echo $1 | sed -E s/\\..+// && exit ${PIPESTATUS[0]})
local swift_runtime_libs
swift_runtime_libs=$(xcrun otool -LX "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/$1/${basename}" | grep @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]})
swift_runtime_libs=$(xcrun otool -LX "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/$1/${basename}" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]})
for lib in $swift_runtime_libs; do
echo "rsync -av \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
rsync -av "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
if [ "${CODE_SIGNING_REQUIRED}" == "YES" ]; then
code_sign "${destination}/${lib}"
fi
done
}
@@ -6,6 +6,8 @@ mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
> "$RESOURCES_TO_COPY"
XCASSET_FILES=""
install_resource()
{
case $1 in
@@ -36,6 +38,7 @@ install_resource()
xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm"
;;
*.xcassets)
XCASSET_FILES="$XCASSET_FILES '${PODS_ROOT}/$1'"
;;
/*)
echo "$1"
@@ -54,7 +57,7 @@ if [[ "${ACTION}" == "install" ]]; then
fi
rm -f "$RESOURCES_TO_COPY"
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ `find . -name '*.xcassets' | wc -l` -ne 0 ]
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ]
then
case "${TARGETED_DEVICE_FAMILY}" in
1,2)
@@ -70,5 +73,6 @@ then
TARGET_DEVICE_ARGS="--target-device mac"
;;
esac
find "${PWD}" -name "*.xcassets" -print0 | xargs -0 actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
while read line; do XCASSET_FILES="$XCASSET_FILES '$line'"; done <<<$(find "$PWD" -name "*.xcassets" | egrep -v "^$PODS_ROOT")
echo $XCASSET_FILES | xargs actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
fi
@@ -2,8 +2,8 @@ FRAMEWORK_SEARCH_PATHS = "$PODS_FRAMEWORK_BUILD_PATH"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$PODS_FRAMEWORK_BUILD_PATH/Locksmith.framework/Headers"
OTHER_LDFLAGS = -ObjC -framework "Locksmith"
OTHER_LDFLAGS = $(inherited) -ObjC -framework "Locksmith"
OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS)
OTHER_SWIFT_FLAGS = "-D COCOAPODS"
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-Locksmith
PODS_ROOT = ${SRCROOT}/Pods
@@ -2,8 +2,8 @@ FRAMEWORK_SEARCH_PATHS = "$PODS_FRAMEWORK_BUILD_PATH"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$PODS_FRAMEWORK_BUILD_PATH/Locksmith.framework/Headers"
OTHER_LDFLAGS = -ObjC -framework "Locksmith"
OTHER_LDFLAGS = $(inherited) -ObjC -framework "Locksmith"
OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS)
OTHER_SWIFT_FLAGS = "-D COCOAPODS"
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-Locksmith
PODS_ROOT = ${SRCROOT}/Pods
@@ -5,4 +5,5 @@ GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Expecta" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Expecta" "${PODS_ROOT}/Headers/Public/Locksmith" "${PODS_ROOT}/Headers/Public/Specta"
OTHER_LDFLAGS = ${PODS_TESTS_EXPECTA_OTHER_LDFLAGS} -ObjC
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-Tests
PODS_ROOT = ${SRCROOT}
PODS_ROOT = ${SRCROOT}
SKIP_INSTALL = YES
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.1.1</string>
<string>1.2.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
@@ -4,6 +4,7 @@ FRAMEWORK_SEARCH_PATHS = "$PODS_FRAMEWORK_BUILD_PATH"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Locksmith" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Expecta" "${PODS_ROOT}/Headers/Public/Locksmith" "${PODS_ROOT}/Headers/Public/Specta"
OTHER_LDFLAGS = ${PODS_TESTS_LOCKSMITH_OTHER_LDFLAGS} -ObjC
OTHER_SWIFT_FLAGS = "-D COCOAPODS"
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-Tests
PODS_ROOT = ${SRCROOT}
PODS_ROOT = ${SRCROOT}
SKIP_INSTALL = YES
@@ -5,4 +5,5 @@ GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Specta" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Expecta" "${PODS_ROOT}/Headers/Public/Locksmith" "${PODS_ROOT}/Headers/Public/Specta"
OTHER_LDFLAGS = ${PODS_TESTS_SPECTA_OTHER_LDFLAGS} -ObjC
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-Tests
PODS_ROOT = ${SRCROOT}
PODS_ROOT = ${SRCROOT}
SKIP_INSTALL = YES
@@ -15,7 +15,7 @@
// Locksmith
#define COCOAPODS_POD_AVAILABLE_Locksmith
#define COCOAPODS_VERSION_MAJOR_Locksmith 1
#define COCOAPODS_VERSION_MINOR_Locksmith 1
#define COCOAPODS_VERSION_MINOR_Locksmith 2
#define COCOAPODS_VERSION_PATCH_Locksmith 1
// Specta
@@ -11,7 +11,7 @@ install_framework()
local source="${BUILT_PRODUCTS_DIR}/Pods-Tests/$1"
local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [ -L ${source} ]; then
if [ -L "${source}" ]; then
echo "Symlinked..."
source=$(readlink "${source}")
fi
@@ -28,10 +28,13 @@ install_framework()
local basename
basename=$(echo $1 | sed -E s/\\..+// && exit ${PIPESTATUS[0]})
local swift_runtime_libs
swift_runtime_libs=$(xcrun otool -LX "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/$1/${basename}" | grep @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]})
swift_runtime_libs=$(xcrun otool -LX "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/$1/${basename}" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]})
for lib in $swift_runtime_libs; do
echo "rsync -av \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
rsync -av "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
if [ "${CODE_SIGNING_REQUIRED}" == "YES" ]; then
code_sign "${destination}/${lib}"
fi
done
}
@@ -6,6 +6,8 @@ mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
> "$RESOURCES_TO_COPY"
XCASSET_FILES=""
install_resource()
{
case $1 in
@@ -36,6 +38,7 @@ install_resource()
xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm"
;;
*.xcassets)
XCASSET_FILES="$XCASSET_FILES '${PODS_ROOT}/$1'"
;;
/*)
echo "$1"
@@ -54,7 +57,7 @@ if [[ "${ACTION}" == "install" ]]; then
fi
rm -f "$RESOURCES_TO_COPY"
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ `find . -name '*.xcassets' | wc -l` -ne 0 ]
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ]
then
case "${TARGETED_DEVICE_FAMILY}" in
1,2)
@@ -70,5 +73,6 @@ then
TARGET_DEVICE_ARGS="--target-device mac"
;;
esac
find "${PWD}" -name "*.xcassets" -print0 | xargs -0 actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
while read line; do XCASSET_FILES="$XCASSET_FILES '$line'"; done <<<$(find "$PWD" -name "*.xcassets" | egrep -v "^$PODS_ROOT")
echo $XCASSET_FILES | xargs actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
fi
@@ -2,8 +2,8 @@ FRAMEWORK_SEARCH_PATHS = "$PODS_FRAMEWORK_BUILD_PATH"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$PODS_FRAMEWORK_BUILD_PATH/Expecta.framework/Headers" -iquote "$PODS_FRAMEWORK_BUILD_PATH/Locksmith.framework/Headers" -iquote "$PODS_FRAMEWORK_BUILD_PATH/Specta.framework/Headers"
OTHER_LDFLAGS = -ObjC -framework "Expecta" -framework "Locksmith" -framework "Specta"
OTHER_LDFLAGS = $(inherited) -ObjC -framework "Expecta" -framework "Locksmith" -framework "Specta"
OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS)
OTHER_SWIFT_FLAGS = "-D COCOAPODS"
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-Tests
PODS_ROOT = ${SRCROOT}/Pods
@@ -2,8 +2,8 @@ FRAMEWORK_SEARCH_PATHS = "$PODS_FRAMEWORK_BUILD_PATH"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$PODS_FRAMEWORK_BUILD_PATH/Expecta.framework/Headers" -iquote "$PODS_FRAMEWORK_BUILD_PATH/Locksmith.framework/Headers" -iquote "$PODS_FRAMEWORK_BUILD_PATH/Specta.framework/Headers"
OTHER_LDFLAGS = -ObjC -framework "Expecta" -framework "Locksmith" -framework "Specta"
OTHER_LDFLAGS = $(inherited) -ObjC -framework "Expecta" -framework "Locksmith" -framework "Specta"
OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS)
OTHER_SWIFT_FLAGS = "-D COCOAPODS"
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-Tests
PODS_ROOT = ${SRCROOT}/Pods
+39 -24
View File
@@ -9,6 +9,10 @@ import UIKit
import XCTest
import Locksmith
let myService = "myService"
let sampleData = ["key": "value"]
let myUserAccount = "myUserAccount"
class LocksmithTests: XCTestCase {
override func setUp() {
@@ -22,69 +26,80 @@ class LocksmithTests: XCTestCase {
super.tearDown()
}
// public class func saveData(data: Dictionary<String, String>, inService service: String, forUserAccount userAccount: String) -> NSError?
func testSaveData_Once() {
let error = Locksmith.saveData(data: ["key": "value"], forUserAccount: "myUserAccount", inService: "myService")
// var error = Locksmith.saveData(["key": "value"], inService: <#String#>, forUserAccount: <#String#>)
// var error = Locksmith.saveData(, inService: "myService", forUserAccount: "myUserAccount")
let error = Locksmith.saveData(["key": "value"], forUserAccount: myUserAccount, inService: myService)
XCTAssert(error == nil, "❌: saving data")
}
func testSaveData_Multiple() {
var errors: [NSError?] = []
for i in 0...10 {
errors.append(Locksmith.saveData(["key": "value \(i)"], inService: "myService", forUserAccount: "myAccount\(i)"))
errors.append(Locksmith.saveData(["key": "value \(i)"], forUserAccount: "myAccount\(i)", inService: "myService"))
}
XCTAssert(errors.filter({ $0 != nil }).isEmpty, "❌: saving multiple items")
}
func testSaveData_Duplicate() {
// Should be successful
let error1 = Locksmith.saveData(["key": "value"], inService: "myService", forUserAccount: "user")
let error1 = Locksmith.saveData(sampleData, forUserAccount: "user", inService: myService)
// Should fail
let error2 = Locksmith.saveData(["key": "value"], inService: "myService", forUserAccount: "user")
let error2 = Locksmith.saveData(sampleData, forUserAccount: "user", inService: "myService")
XCTAssert(error1 == nil && error2 != nil, "❌: saving duplicate data")
}
// Test using default values for the service
func testWorkflow_Defaults() {
let error1 = Locksmith.saveData(sampleData, forUserAccount: "me")
let error2 = Locksmith.saveData(sampleData, forUserAccount: "me2")
XCTAssert(error1 == nil && error2 == nil, "❌: saving with default service")
let (dict1, err1) = Locksmith.loadDataForUserAccount("me")
let (dict2, err2) = Locksmith.loadDataForUserAccount("me2")
XCTAssert(dict1 != nil && dict2 != nil && err1 == nil && err2 == nil, "❌: loading with default service")
}
// Setup the keychain for requests that use pre-existing values on the keychain (update, read, delete)
func setupLoads() {
Locksmith.saveData(["key": "value"], inService: "myService", forUserAccount: "user1")
Locksmith.saveData(["anotherkey": "anothervalue"], inService: "myService", forUserAccount: "user2")
Locksmith.saveData(["word": "definition"], inService: "myService", forUserAccount: "user3")
Locksmith.saveData(["key": "value"], forUserAccount: "user1", inService: "myService")
Locksmith.saveData(["anotherkey": "anothervalue"], forUserAccount: "user2", inService: "myService")
Locksmith.saveData(["word": "definition"], forUserAccount: "user3", inService: "myService")
}
// public class func loadDataInService(service: String, forUserAccount userAccount: String) -> (NSDictionary?, NSError?)
func testLoadData_Once() {
setupLoads()
let (dictionary, error) = Locksmith.loadDataInService("myService", forUserAccount: "user1")
XCTAssert(dictionary!.valueForKey("key")! as NSString == "value" && error == nil, "❌: loading one item")
let (dictionary, error) = Locksmith.loadDataForUserAccount("user1", inService: "myService")
XCTAssert(dictionary!.valueForKey("key")! as! NSString == "value" && error == nil, "❌: loading one item")
}
func testLoadData_Multiple() {
setupLoads()
let (dictionary, error) = Locksmith.loadDataInService("myService", forUserAccount: "user1")
let (dictionary2, error2) = Locksmith.loadDataInService("myService", forUserAccount: "user2")
let (dictionary3, error3) = Locksmith.loadDataInService("myService", forUserAccount: "user3")
let (dictionary, error) = Locksmith.loadDataForUserAccount("user1", inService: "myService")
let (dictionary2, error2) = Locksmith.loadDataForUserAccount("user2", inService: "myService")
let (dictionary3, error3) = Locksmith.loadDataForUserAccount("user3", inService: "myService")
XCTAssert(dictionary!.valueForKey("key")! as NSString == "value" && error == nil, "❌: loading multiple items")
XCTAssert(dictionary2!.valueForKey("anotherkey")! as NSString == "anothervalue" && error == nil, "❌: loading multiple items")
XCTAssert(dictionary3!.valueForKey("word")! as NSString == "definition" && error == nil, "❌: loading multiple items")
XCTAssert(dictionary!.valueForKey("key")! as! NSString == "value" && error == nil, "❌: loading multiple items")
XCTAssert(dictionary2!.valueForKey("anotherkey")! as! NSString == "anothervalue" && error == nil, "❌: loading multiple items")
XCTAssert(dictionary3!.valueForKey("word")! as! NSString == "definition" && error == nil, "❌: loading multiple items")
}
// public class func updateData(data: Dictionary<String, String>, inService service: String, forUserAccount userAccount: String) -> NSError?
func testUpdateData() {
setupLoads()
let error = Locksmith.updateData(["key": "newvalue"], inService: "myService", forUserAccount: "user1")
let (dictionary, err) = Locksmith.loadDataInService("myService", forUserAccount: "user1")
XCTAssert(dictionary!.valueForKey("key")! as NSString == "newvalue" && error == nil, "❌: updating item")
let error = Locksmith.updateData(["key": "newvalue"], forUserAccount: "user1", inService: "myService")
let (dictionary, err) = Locksmith.loadDataForUserAccount("user1", inService: "myService")
XCTAssert(dictionary!.valueForKey("key")! as! NSString == "newvalue" && error == nil, "❌: updating item")
// Updating an item that doesn't exist should create that item (i.e. performs a regular create request)
let error2 = Locksmith.updateData(["key": "anothervalue"], inService: "myService", forUserAccount: "user1")
let error2 = Locksmith.updateData(["key": "anothervalue"], forUserAccount: "user1", inService: "myService")
XCTAssert(error2 == nil, "❌: updating item that doesn't exist")
}
@@ -92,10 +107,10 @@ class LocksmithTests: XCTestCase {
func testDeleteData() {
setupLoads()
let error = Locksmith.deleteDataInService("myService", forUserAccount: "user1")
let error = Locksmith.deleteDataForUserAccount("user1", inService: "myService")
XCTAssert(error == nil, "❌: deleting existing item")
let error2 = Locksmith.deleteDataInService("myService", forUserAccount: "user1")
let error2 = Locksmith.deleteDataForUserAccount("user1", inService: "myService")
XCTAssert(error2 != nil, "❌: deleting non existent item")
}
+1 -1
View File
@@ -9,7 +9,7 @@
Pod::Spec.new do |s|
s.name = "Locksmith"
s.version = "1.1.1"
s.version = "1.2.1"
s.summary = "Locksmith is a sane way to work with the iOS Keychain in Swift."
s.description = <<-DESC
Locksmith is a sane way to work with the iOS Keychain in Swift.
+24 -22
View File
@@ -7,11 +7,12 @@
objects = {
/* Begin PBXBuildFile section */
BFFB19D61A4870A300CCFFC3 /* Locksmith.h in Headers */ = {isa = PBXBuildFile; fileRef = BFFB19D51A4870A300CCFFC3 /* Locksmith.h */; settings = {ATTRIBUTES = (Public, ); }; };
9D60D8141B10927B00BE14A9 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9D60D8131B10927B00BE14A9 /* Info.plist */; };
9DF0A2C01B0E394F0049F83A /* Locksmith.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DF0A2BE1B0E394F0049F83A /* Locksmith.swift */; };
9DF0A2C11B0E394F0049F83A /* LocksmithRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DF0A2BF1B0E394F0049F83A /* LocksmithRequest.swift */; };
9DF0A2C81B0E3D370049F83A /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9DF0A2C71B0E3D370049F83A /* Info.plist */; };
BFFB19DC1A4870A300CCFFC3 /* Locksmith.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFFB19D01A4870A300CCFFC3 /* Locksmith.framework */; };
BFFB19E31A4870A300CCFFC3 /* LocksmithTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFB19E21A4870A300CCFFC3 /* LocksmithTests.swift */; };
BFFB19EE1A4870E400CCFFC3 /* LocksmithRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFB19EC1A4870E400CCFFC3 /* LocksmithRequest.swift */; };
BFFB19EF1A4870E400CCFFC3 /* Locksmith.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFFB19ED1A4870E400CCFFC3 /* Locksmith.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -25,14 +26,13 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
9D60D8131B10927B00BE14A9 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Pod/Info.plist; sourceTree = SOURCE_ROOT; };
9DF0A2BE1B0E394F0049F83A /* Locksmith.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Locksmith.swift; path = Pod/Classes/Locksmith.swift; sourceTree = SOURCE_ROOT; };
9DF0A2BF1B0E394F0049F83A /* LocksmithRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LocksmithRequest.swift; path = Pod/Classes/LocksmithRequest.swift; sourceTree = SOURCE_ROOT; };
9DF0A2C71B0E3D370049F83A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
BFFB19D01A4870A300CCFFC3 /* Locksmith.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Locksmith.framework; sourceTree = BUILT_PRODUCTS_DIR; };
BFFB19D41A4870A300CCFFC3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
BFFB19D51A4870A300CCFFC3 /* Locksmith.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Locksmith.h; sourceTree = "<group>"; };
BFFB19DB1A4870A300CCFFC3 /* LocksmithTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LocksmithTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
BFFB19E11A4870A300CCFFC3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
BFFB19E21A4870A300CCFFC3 /* LocksmithTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocksmithTests.swift; sourceTree = "<group>"; };
BFFB19EC1A4870E400CCFFC3 /* LocksmithRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocksmithRequest.swift; sourceTree = "<group>"; };
BFFB19ED1A4870E400CCFFC3 /* Locksmith.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Locksmith.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -75,9 +75,8 @@
BFFB19D21A4870A300CCFFC3 /* Locksmith */ = {
isa = PBXGroup;
children = (
BFFB19EC1A4870E400CCFFC3 /* LocksmithRequest.swift */,
BFFB19ED1A4870E400CCFFC3 /* Locksmith.swift */,
BFFB19D51A4870A300CCFFC3 /* Locksmith.h */,
9DF0A2BE1B0E394F0049F83A /* Locksmith.swift */,
9DF0A2BF1B0E394F0049F83A /* LocksmithRequest.swift */,
BFFB19D31A4870A300CCFFC3 /* Supporting Files */,
);
path = Locksmith;
@@ -86,7 +85,7 @@
BFFB19D31A4870A300CCFFC3 /* Supporting Files */ = {
isa = PBXGroup;
children = (
BFFB19D41A4870A300CCFFC3 /* Info.plist */,
9D60D8131B10927B00BE14A9 /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
@@ -103,7 +102,7 @@
BFFB19E01A4870A300CCFFC3 /* Supporting Files */ = {
isa = PBXGroup;
children = (
BFFB19E11A4870A300CCFFC3 /* Info.plist */,
9DF0A2C71B0E3D370049F83A /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
@@ -115,7 +114,6 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
BFFB19D61A4870A300CCFFC3 /* Locksmith.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -198,6 +196,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9D60D8141B10927B00BE14A9 /* Info.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -205,6 +204,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9DF0A2C81B0E3D370049F83A /* Info.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -215,8 +215,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BFFB19EF1A4870E400CCFFC3 /* Locksmith.swift in Sources */,
BFFB19EE1A4870E400CCFFC3 /* LocksmithRequest.swift in Sources */,
9DF0A2C11B0E394F0049F83A /* LocksmithRequest.swift in Sources */,
9DF0A2C01B0E394F0049F83A /* Locksmith.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -274,7 +274,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -314,7 +314,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -327,11 +327,12 @@
BFFB19E71A4870A300CCFFC3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = Locksmith/Info.plist;
INFOPLIST_FILE = "$(SRCROOT)/Pod/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -343,11 +344,12 @@
BFFB19E81A4870A300CCFFC3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = Locksmith/Info.plist;
INFOPLIST_FILE = "$(SRCROOT)/Pod/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -367,7 +369,7 @@
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = LocksmithTests/Info.plist;
INFOPLIST_FILE = LockSmithTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
};
@@ -380,7 +382,7 @@
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
INFOPLIST_FILE = LocksmithTests/Info.plist;
INFOPLIST_FILE = LockSmithTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
};
@@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0630"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BFFB19CF1A4870A300CCFFC3"
BuildableName = "Locksmith.framework"
BlueprintName = "Locksmith"
ReferencedContainer = "container:Locksmith.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BFFB19DA1A4870A300CCFFC3"
BuildableName = "LocksmithTests.xctest"
BlueprintName = "LocksmithTests"
ReferencedContainer = "container:Locksmith.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BFFB19DA1A4870A300CCFFC3"
BuildableName = "LocksmithTests.xctest"
BlueprintName = "LocksmithTests"
ReferencedContainer = "container:Locksmith.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BFFB19CF1A4870A300CCFFC3"
BuildableName = "Locksmith.framework"
BlueprintName = "Locksmith"
ReferencedContainer = "container:Locksmith.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BFFB19CF1A4870A300CCFFC3"
BuildableName = "Locksmith.framework"
BlueprintName = "Locksmith"
ReferencedContainer = "container:Locksmith.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BFFB19CF1A4870A300CCFFC3"
BuildableName = "Locksmith.framework"
BlueprintName = "Locksmith"
ReferencedContainer = "container:Locksmith.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
-19
View File
@@ -1,19 +0,0 @@
//
// Locksmith.h
// Locksmith
//
// Created by Michael Hahn on 12/22/14.
// Copyright (c) 2014 Mathew Palmer. All rights reserved.
//
#import <UIKit/UIKit.h>
//! Project version number for Locksmith.
FOUNDATION_EXPORT double LocksmithVersionNumber;
//! Project version string for Locksmith.
FOUNDATION_EXPORT const unsigned char LocksmithVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <Locksmith/PublicHeader.h>
@@ -13,14 +13,12 @@
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
<string>1</string>
</dict>
</plist>
+109
View File
@@ -0,0 +1,109 @@
//
// LocksmithTests.swift
// LocksmithTests
//
// Created by Michael Hahn on 12/22/14.
// Copyright (c) 2014 Mathew Palmer. All rights reserved.
//
import UIKit
import XCTest
import Locksmith
class LocksmithTests: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
Locksmith.clearKeychain()
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
// public class func saveData(data: Dictionary<String, String>, inService service: String, forUserAccount userAccount: String) -> NSError?
func testSaveData_Once() {
var error = Locksmith.saveData(["key": "value"], forUserAccount: "myUserAccount", inService: "myService")
XCTAssert(error == nil, "❌: saving data")
}
func testSaveData_Multiple() {
var errors: [NSError?] = []
for i in 0...10 {
errors.append(Locksmith.saveData(["key": "value \(i)"], forUserAccount: "myAccount\(i)", inService: "myService"))
}
XCTAssert(errors.filter({ $0 != nil }).isEmpty, "❌: saving multiple items")
}
func testSaveData_Duplicate() {
// Should be successful
let error1 = Locksmith.saveData(["key": "value"], forUserAccount: "user", inService: "myService")
// Should fail
let error2 = Locksmith.saveData(["key": "value"], forUserAccount: "user", inService: "myService")
XCTAssert(error1 == nil && error2 != nil, "❌: saving duplicate data")
}
// Setup the keychain for requests that use pre-existing values on the keychain (update, read, delete)
func setupLoads() {
Locksmith.saveData(["key": "value"], forUserAccount: "user1", inService: "myService")
Locksmith.saveData(["anotherkey": "anothervalue"], forUserAccount: "user2", inService: "myService")
Locksmith.saveData(["word": "definition"], forUserAccount: "user3", inService: "myService")
}
// public class func loadDataInService(service: String, forUserAccount userAccount: String) -> (NSDictionary?, NSError?)
func testLoadData_Once() {
setupLoads()
let (dictionary, error) = Locksmith.loadDataForUserAccount("user1", inService: "myService")
XCTAssert(dictionary!.valueForKey("key") as! NSString == "value" && error == nil, "❌: loading one item")
}
func testLoadData_Multiple() {
setupLoads()
let (dictionary, error) = Locksmith.loadDataForUserAccount("user1", inService: "myService")
let (dictionary2, error2) = Locksmith.loadDataForUserAccount("user2", inService: "myService")
let (dictionary3, error3) = Locksmith.loadDataForUserAccount("user3", inService: "myService")
XCTAssert(dictionary!.valueForKey("key") as! NSString == "value" && error == nil, "❌: loading multiple items")
XCTAssert(dictionary2!.valueForKey("anotherkey") as! NSString == "anothervalue" && error == nil, "❌: loading multiple items")
XCTAssert(dictionary3!.valueForKey("word") as! NSString == "definition" && error == nil, "❌: loading multiple items")
}
// public class func updateData(data: Dictionary<String, String>, inService service: String, forUserAccount userAccount: String) -> NSError?
func testUpdateData() {
setupLoads()
let error = Locksmith.updateData(["key": "newvalue"], forUserAccount: "user1", inService: "myService")
let (dictionary, err) = Locksmith.loadDataForUserAccount("user1", inService: "myService")
XCTAssert(dictionary!.valueForKey("key") as! NSString == "newvalue" && error == nil, "❌: updating item")
// Updating an item that doesn't exist should create that item (i.e. performs a regular create request)
let error2 = Locksmith.updateData(["key": "anothervalue"], forUserAccount: "user1", inService: "myService")
XCTAssert(error2 == nil, "❌: updating item that doesn't exist")
}
// public class func deleteDataInService(service: String, forUserAccount userAccount: String) -> NSError?
func testDeleteData() {
setupLoads()
let error = Locksmith.deleteDataForUserAccount("user1", inService: "myService")
XCTAssert(error == nil, "❌: deleting existing item")
let error2 = Locksmith.deleteDataForUserAccount("user1", inService: "myService")
XCTAssert(error2 != nil, "❌: deleting non existent item")
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measureBlock() {
// Put the code you want to measure the time of here.
}
}
}
+25 -3
View File
@@ -9,12 +9,12 @@ import UIKit
import Security
public let LocksmithErrorDomain = "com.locksmith.error"
public let LocksmithDefaultService = NSBundle.mainBundle().infoDictionary![kCFBundleIdentifierKey] as String
public let LocksmithDefaultService = NSBundle.mainBundle().infoDictionary![kCFBundleIdentifierKey] as? String ?? "com.locksmith.defaultService"
public class Locksmith: NSObject {
// MARK: Perform request
class func performRequest(request: LocksmithRequest) -> (NSDictionary?, NSError?) {
public class func performRequest(request: LocksmithRequest) -> (NSDictionary?, NSError?) {
let type = request.type
//var result: Unmanaged<AnyObject>? = nil
var result: AnyObject?
@@ -130,6 +130,9 @@ public class Locksmith: NSObject {
options[String(kSecAttrService)] = request.service
options[String(kSecAttrSynchronizable)] = request.synchronizable
options[String(kSecClass)] = securityCode(request.securityClass)
if let accessibleMode = request.accessible {
options[String(kSecAttrAccessible)] = accessible(accessibleMode)
}
for (key, option) in options {
parsedRequest.setOptional(option, forKey: key)
@@ -220,6 +223,25 @@ public class Locksmith: NSObject {
return kSecClassGenericPassword
}
}
private class func accessible(accessible: Accessible) -> CFStringRef {
switch accessible {
case .WhenUnlock:
return kSecAttrAccessibleWhenUnlocked
case .AfterFirstUnlock:
return kSecAttrAccessibleAfterFirstUnlock
case .Always:
return kSecAttrAccessibleAlways
case .WhenPasscodeSetThisDeviceOnly:
return kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
case .WhenUnlockedThisDeviceOnly:
return kSecAttrAccessibleWhenUnlockedThisDeviceOnly
case .AfterFirstUnlockThisDeviceOnly:
return kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
case .AlwaysThisDeviceOnly:
return kSecAttrAccessibleAlwaysThisDeviceOnly
}
}
}
// MARK: Convenient Class Methods
@@ -302,4 +324,4 @@ extension NSMutableDictionary {
self.setObject(object, forKey: key)
}
}
}
}
+17 -11
View File
@@ -20,19 +20,25 @@ public enum RequestType: Int {
case Create, Read, Update, Delete
}
public enum Accessible: Int {
case WhenUnlock, AfterFirstUnlock, Always, WhenPasscodeSetThisDeviceOnly,
WhenUnlockedThisDeviceOnly, AfterFirstUnlockThisDeviceOnly, AlwaysThisDeviceOnly
}
public class LocksmithRequest: NSObject, DebugPrintable {
// Keychain Options
// Required
var service: String = NSBundle.mainBundle().infoDictionary![kCFBundleIdentifierKey] as String // Default to Bundle Identifier
var userAccount: String
var type: RequestType = .Read // Default to non-destructive
public var service: String = LocksmithDefaultService
public var userAccount: String
public var type: RequestType = .Read // Default to non-destructive
// Optional
var securityClass: SecurityClass = .GenericPassword // Default to password lookup
var group: String?
var data: NSDictionary?
var matchLimit: MatchLimit = .One
var synchronizable = false
public var securityClass: SecurityClass = .GenericPassword // Default to password lookup
public var group: String?
public var data: NSDictionary?
public var matchLimit: MatchLimit = .One
public var synchronizable = false
public var accessible: Accessible?
// Debugging
override public var debugDescription: String {
@@ -44,13 +50,13 @@ public class LocksmithRequest: NSObject, DebugPrintable {
self.userAccount = userAccount
}
convenience init(userAccount: String, requestType: RequestType, service: String = LocksmithDefaultService) {
public convenience init(userAccount: String, requestType: RequestType, service: String = LocksmithDefaultService) {
self.init(userAccount: userAccount, service: service)
self.type = requestType
}
convenience init(userAccount: String, requestType: RequestType, data: NSDictionary, service: String = LocksmithDefaultService) {
public convenience init(userAccount: String, requestType: RequestType, data: NSDictionary, service: String = LocksmithDefaultService) {
self.init(userAccount: userAccount, requestType: requestType, service: service)
self.data = data
}
}
}
+26
View File
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>com.matthewpalmer.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.1.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
+12 -1
View File
@@ -1,12 +1,16 @@
> This is Locksmiths compatibility branch for Swift 1.2
# Locksmith
A sane way to work with the iOS Keychain in Swift.
<!--[![CI Status](http://img.shields.io/travis/matthewpalmer/Locksmith.svg?style=flat)](https://travis-ci.org/matthewpalmer/Locksmith)-->
[![Version](https://img.shields.io/cocoapods/v/Locksmith.svg?style=flat)](http://cocoadocs.org/docsets/Locksmith)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
[![License](https://img.shields.io/cocoapods/l/Locksmith.svg?style=flat)](http://cocoadocs.org/docsets/Locksmith)
[![Platform](https://img.shields.io/cocoapods/p/Locksmith.svg?style=flat)](http://cocoadocs.org/docsets/Locksmith)
## Installation
### CocoaPods
@@ -14,7 +18,7 @@ A sane way to work with the iOS Keychain in Swift.
Locksmith is available through [CocoaPods](http://cocoapods.org). To install
it, simply add the following line to your Podfile:
pod "Locksmith"
pod "Locksmith", :git => 'https://github.com/matthewpalmer/Locksmith.git', :branch => '1.2.2'
### Manual
@@ -26,6 +30,8 @@ In the following examples, you can choose not to provide a value for the `inServ
**Save data**
- writes the data to the keychain if it does not exist already
```swift
let error = Locksmith.saveData(["some key": "some value"], forUserAccount: "myUserAccount")
```
@@ -50,6 +56,8 @@ let (dictionary, error) = Locksmith.loadDataForUserAccount("myUserAccount", inSe
**Update data**
- overwrites whatever is stored on the keychain under this user account (if nothing is stored, we save as normal)
```swift
let error = Locksmith.updateData(["some key": "another value"], forUserAccount: "myUserAccount")
```
@@ -116,6 +124,9 @@ var securityClass: SecurityClass // Defaults to .GenericPassword
var synchronizable: Bool // Defaults to false
```
## Testing
I can't work out why, but opening `Example/Locksmith.xcworkspace` and trying to run the tests from there won't work. (Pull requests greatly appreciated on this!) Instead, you can run the tests by opening `Locksmith.xcodeproj` in the root directory, and doing Product -> Test.
## Author
[Matthew Palmer](http://matthewpalmer.net), matt@matthewpalmer.net