Compare commits

..

31 Commits

Author SHA1 Message Date
Jouni Miettunen 35bc00f6de Swift 2 fixes for test cases 2016-02-09 08:51:53 +02:00
Jouni Miettunen 0e72823fee Update podspec to version 1.2.3 2016-02-09 08:46:48 +02:00
Jouni Miettunen 164dabf456 Swift 2.1 fixes 2016-02-09 08:44:23 +02:00
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
34 changed files with 2073 additions and 6319 deletions
+1 -1
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:
+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.2.0)
- Locksmith (1.2.1)
- Specta (0.2.1)
DEPENDENCIES:
@@ -10,11 +10,11 @@ DEPENDENCIES:
EXTERNAL SOURCES:
Locksmith:
:path: ../
:path: "../"
SPEC CHECKSUMS:
Expecta: 03aabd0a89d8dea843baecb19a7fd7466a69a31d
Locksmith: 392ae330eb455e824dab5b714b6719eb29ef5038
Specta: 9141310f46b1f68b676650ff2854e1ed0b74163a
Expecta: a354d4633409dd9fe8c4f5ff5130426adbe31628
Locksmith: 770f6c5c6e5c5c712d1f00e709c62b8a7240c716
Specta: 15a276a6343867b426d5ed135d5aa4d04123a573
COCOAPODS: 0.36.0.beta.1
COCOAPODS: 0.36.3
-37
View File
@@ -1,37 +0,0 @@
#
# Be sure to run `pod lib lint Locksmith.podspec' to ensure this is a
# valid spec and remove all comments before submitting the spec.
#
# Any lines starting with a # are optional, but encouraged
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
#
Pod::Spec.new do |s|
s.name = "Locksmith"
s.version = "1.2.0"
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.
It provides a fast and intuitive way to work with the C Keychain API.
Results are provided as tuples, and errors are informative and easily detected.
DESC
s.homepage = "https://github.com/matthewpalmer/Locksmith"
# s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2"
s.license = 'MIT'
s.author = { "matthewpalmer" => "matt@matthewpalmer.net" }
s.source = { :git => "https://github.com/matthewpalmer/Locksmith.git", :tag => s.version.to_s }
s.social_media_url = 'https://twitter.com/_matthewpalmer'
s.platform = :ios, '8.0'
s.requires_arc = true
s.source_files = 'Pod/Classes'
s.resource_bundles = {
'Locksmith' => ['Pod/Assets/*.png']
}
# s.public_header_files = 'Pod/Classes/**/*.h'
# s.frameworks = 'UIKit', 'MapKit'
# s.dependency 'AFNetworking', '~> 2.3'
end
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "Locksmith",
"version": "1.2.0",
"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.2.0"
"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.2.0)
- Locksmith (1.2.1)
- Specta (0.2.1)
DEPENDENCIES:
@@ -10,11 +10,11 @@ DEPENDENCIES:
EXTERNAL SOURCES:
Locksmith:
:path: ../
:path: "../"
SPEC CHECKSUMS:
Expecta: 03aabd0a89d8dea843baecb19a7fd7466a69a31d
Locksmith: 392ae330eb455e824dab5b714b6719eb29ef5038
Specta: 9141310f46b1f68b676650ff2854e1ed0b74163a
Expecta: a354d4633409dd9fe8c4f5ff5130426adbe31628
Locksmith: 770f6c5c6e5c5c712d1f00e709c62b8a7240c716
Specta: 15a276a6343867b426d5ed135d5aa4d04123a573
COCOAPODS: 0.36.0.beta.1
COCOAPODS: 0.36.3
+1746 -6151
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.2.0</string>
<string>1.2.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
@@ -3,7 +3,8 @@ CONFIGURATION_BUILD_DIR = $PODS_FRAMEWORK_BUILD_PATH
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 = -ObjC
OTHER_SWIFT_FLAGS = "-D COCOAPODS"
OTHER_LDFLAGS = ${PODS_LOCKSMITH_LOCKSMITH_OTHER_LDFLAGS} -ObjC
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
@@ -0,0 +1 @@
PODS_LOCKSMITH_LOCKSMITH_OTHER_LDFLAGS = -framework "Security" -framework "UIKit"
@@ -10,5 +10,5 @@
#define COCOAPODS_POD_AVAILABLE_Locksmith
#define COCOAPODS_VERSION_MAJOR_Locksmith 1
#define COCOAPODS_VERSION_MINOR_Locksmith 2
#define COCOAPODS_VERSION_PATCH_Locksmith 0
#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.2.0</string>
<string>1.2.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
@@ -3,7 +3,8 @@ CONFIGURATION_BUILD_DIR = $PODS_FRAMEWORK_BUILD_PATH
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 = -ObjC
OTHER_SWIFT_FLAGS = "-D COCOAPODS"
OTHER_LDFLAGS = ${PODS_TESTS_LOCKSMITH_OTHER_LDFLAGS} -ObjC
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
@@ -0,0 +1 @@
PODS_TESTS_LOCKSMITH_OTHER_LDFLAGS = -framework "Security" -framework "UIKit"
@@ -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
@@ -16,7 +16,7 @@
#define COCOAPODS_POD_AVAILABLE_Locksmith
#define COCOAPODS_VERSION_MAJOR_Locksmith 1
#define COCOAPODS_VERSION_MINOR_Locksmith 2
#define COCOAPODS_VERSION_PATCH_Locksmith 0
#define COCOAPODS_VERSION_PATCH_Locksmith 1
// Specta
#define COCOAPODS_POD_AVAILABLE_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
+5 -5
View File
@@ -75,7 +75,7 @@ class LocksmithTests: XCTestCase {
setupLoads()
let (dictionary, error) = Locksmith.loadDataForUserAccount("user1", inService: "myService")
XCTAssert(dictionary!.valueForKey("key")! as NSString == "value" && error == nil, "❌: loading one item")
XCTAssert(dictionary!.valueForKey("key")! as! NSString == "value" && error == nil, "❌: loading one item")
}
func testLoadData_Multiple() {
@@ -85,9 +85,9 @@ class LocksmithTests: XCTestCase {
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?
@@ -96,7 +96,7 @@ class LocksmithTests: XCTestCase {
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")
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")
+1 -1
View File
@@ -9,7 +9,7 @@
Pod::Spec.new do |s|
s.name = "Locksmith"
s.version = "1.2.0"
s.version = "1.2.3"
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>
+25 -24
View File
@@ -22,68 +22,69 @@ class LocksmithTests: XCTestCase {
// 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"], 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(["key": "value"], forUserAccount: "user", inService: "myService")
// Should fail
let error2 = Locksmith.saveData(["key": "value"], inService: "myService", forUserAccount: "user")
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"], 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, _) = Locksmith.loadDataForUserAccount("user2", inService: "myService")
let (dictionary3, _) = 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, _) = 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")
}
@@ -91,10 +92,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")
}
@@ -105,4 +106,4 @@ class LocksmithTests: XCTestCase {
}
}
}
}
+35 -17
View File
@@ -9,20 +9,20 @@ import UIKit
import Security
public let LocksmithErrorDomain = "com.locksmith.error"
public let LocksmithDefaultService = NSBundle.mainBundle().infoDictionary![kCFBundleIdentifierKey] as String
public let LocksmithDefaultService = NSBundle.mainBundle().bundleIdentifier ?? "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?
var status: OSStatus?
var parsedRequest: NSMutableDictionary = parseRequest(request)
let parsedRequest: NSMutableDictionary = parseRequest(request)
var requestReference = parsedRequest as CFDictionaryRef
let requestReference = parsedRequest as CFDictionaryRef
switch type {
case .Create:
@@ -33,12 +33,10 @@ public class Locksmith: NSObject {
status = SecItemDelete(requestReference)
case .Update:
status = Locksmith.performUpdate(requestReference, result: &result)
default:
status = nil
}
if let status = status {
var statusCode = Int(status)
let statusCode = Int(status)
let error = Locksmith.keychainError(forCode: statusCode)
var resultsDictionary: NSDictionary?
@@ -66,7 +64,7 @@ public class Locksmith: NSObject {
// Even if the delete request failed (e.g. if the item didn't exist before), still try to save the new item.
// If we get an error saving, we'll tell the user about it.
var status: OSStatus = withUnsafeMutablePointer(&result) { SecItemAdd(request, UnsafeMutablePointer($0)) }
let status: OSStatus = withUnsafeMutablePointer(&result) { SecItemAdd(request, UnsafeMutablePointer($0)) }
return status
}
@@ -130,6 +128,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)
@@ -216,8 +217,25 @@ public class Locksmith: NSObject {
return kSecClassInternetPassword
case .Key:
return kSecClassKey
default:
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
}
}
}
@@ -226,7 +244,7 @@ public class Locksmith: NSObject {
extension Locksmith {
public class func saveData(data: Dictionary<String, String>, forUserAccount userAccount: String, inService service: String = LocksmithDefaultService) -> NSError? {
let saveRequest = LocksmithRequest(userAccount: userAccount, requestType: .Create, data: data, service: service)
let (dictionary, error) = Locksmith.performRequest(saveRequest)
let (_, error) = Locksmith.performRequest(saveRequest)
return error
}
@@ -237,26 +255,26 @@ extension Locksmith {
public class func deleteDataForUserAccount(userAccount: String, inService service: String = LocksmithDefaultService) -> NSError? {
let deleteRequest = LocksmithRequest(userAccount: userAccount, requestType: .Delete, service: service)
let (dictionary, error) = Locksmith.performRequest(deleteRequest)
let (_, error) = Locksmith.performRequest(deleteRequest)
return error
}
public class func updateData(data: Dictionary<String, String>, forUserAccount userAccount: String, inService service: String = LocksmithDefaultService) -> NSError? {
let updateRequest = LocksmithRequest(userAccount: userAccount, requestType: .Update, data: data, service: service)
let (dictionary, error) = Locksmith.performRequest(updateRequest)
let (_, error) = Locksmith.performRequest(updateRequest)
return error
}
public class func clearKeychain() -> NSError? {
// Delete all of the keychain data of the given class
func deleteDataForSecClass(secClass: CFTypeRef) -> NSError? {
var request = NSMutableDictionary()
let request = NSMutableDictionary()
request.setObject(secClass, forKey: String(kSecClass))
var status: OSStatus? = SecItemDelete(request as CFDictionaryRef)
let status: OSStatus? = SecItemDelete(request as CFDictionaryRef)
if let status = status {
var statusCode = Int(status)
let statusCode = Int(status)
return Locksmith.keychainError(forCode: statusCode)
}
@@ -302,4 +320,4 @@ extension NSMutableDictionary {
self.setObject(object, forKey: key)
}
}
}
}
+18 -12
View File
@@ -20,19 +20,25 @@ public enum RequestType: Int {
case Create, Read, Update, Delete
}
public class LocksmithRequest: NSObject, DebugPrintable {
public enum Accessible: Int {
case WhenUnlock, AfterFirstUnlock, Always, WhenPasscodeSetThisDeviceOnly,
WhenUnlockedThisDeviceOnly, AfterFirstUnlockThisDeviceOnly, AlwaysThisDeviceOnly
}
public class LocksmithRequest: NSObject, CustomDebugStringConvertible {
// 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>
+14 -3
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)
<!--[![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,10 +124,13 @@ 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
## License
Locksmith is available under the MIT license. See the LICENSE file for more info.
Locksmith is available under the MIT license. See the LICENSE file for more info.