diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 3c0c119..0000000 --- a/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -osx_image: xcode10.2 -language: swift -script: - - fastlane scan --scheme KeychainStorage --project KeychainStorage.xcodeproj --device 'iPhone Xʀ' diff --git a/Example/KeychainStorageExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Example/KeychainStorageExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index c4ff85a..0000000 --- a/Example/KeychainStorageExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/Example/KeychainStorageExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Example/KeychainStorageExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/Example/KeychainStorageExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/Example/KeychainStorageExample.xcodeproj/xcshareddata/xcschemes/KeychainStorageExample.xcscheme b/Example/KeychainStorageExample.xcodeproj/xcshareddata/xcschemes/KeychainStorageExample.xcscheme deleted file mode 100644 index 3137596..0000000 --- a/Example/KeychainStorageExample.xcodeproj/xcshareddata/xcschemes/KeychainStorageExample.xcscheme +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Example/KeychainStorageExample.xcworkspace/contents.xcworkspacedata b/Example/KeychainStorageExample.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index dd86c7d..0000000 --- a/Example/KeychainStorageExample.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/Example/KeychainStorageExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Example/KeychainStorageExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/Example/KeychainStorageExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/Example/KeychainStorageExample/AppDelegate.swift b/Example/KeychainStorageExample/AppDelegate.swift deleted file mode 100644 index 460ddf9..0000000 --- a/Example/KeychainStorageExample/AppDelegate.swift +++ /dev/null @@ -1,46 +0,0 @@ -// -// AppDelegate.swift -// KeychainStorageExample -// -// Created by Dan, Radu-Ionut (RO - Bucharest) on 26/05/2019. -// Copyright © 2019 radude89. All rights reserved. -// - -import UIKit - -@UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { - - var window: UIWindow? - - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - // Override point for customization after application launch. - return true - } - - func applicationWillResignActive(_ application: UIApplication) { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. - } - - func applicationDidEnterBackground(_ application: UIApplication) { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. - } - - func applicationWillEnterForeground(_ application: UIApplication) { - // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. - } - - func applicationDidBecomeActive(_ application: UIApplication) { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. - } - - func applicationWillTerminate(_ application: UIApplication) { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. - } - - -} - diff --git a/Example/KeychainStorageExample/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example/KeychainStorageExample/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d8db8d6..0000000 --- a/Example/KeychainStorageExample/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "20x20", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "20x20", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "20x20", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "20x20", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "83.5x83.5", - "scale" : "2x" - }, - { - "idiom" : "ios-marketing", - "size" : "1024x1024", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/Example/KeychainStorageExample/Assets.xcassets/Contents.json b/Example/KeychainStorageExample/Assets.xcassets/Contents.json deleted file mode 100644 index da4a164..0000000 --- a/Example/KeychainStorageExample/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/Example/KeychainStorageExample/Base.lproj/LaunchScreen.storyboard b/Example/KeychainStorageExample/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index bfa3612..0000000 --- a/Example/KeychainStorageExample/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Example/KeychainStorageExample/Base.lproj/Main.storyboard b/Example/KeychainStorageExample/Base.lproj/Main.storyboard deleted file mode 100644 index 08f6c1d..0000000 --- a/Example/KeychainStorageExample/Base.lproj/Main.storyboard +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Example/KeychainStorageExample/Info.plist b/Example/KeychainStorageExample/Info.plist deleted file mode 100644 index 16be3b6..0000000 --- a/Example/KeychainStorageExample/Info.plist +++ /dev/null @@ -1,45 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/Example/KeychainStorageExample.xcodeproj/project.pbxproj b/Example/KeychainStorageExample/KeychainStorageExample.xcodeproj/project.pbxproj similarity index 51% rename from Example/KeychainStorageExample.xcodeproj/project.pbxproj rename to Example/KeychainStorageExample/KeychainStorageExample.xcodeproj/project.pbxproj index 2b6b849..36576f8 100644 --- a/Example/KeychainStorageExample.xcodeproj/project.pbxproj +++ b/Example/KeychainStorageExample/KeychainStorageExample.xcodeproj/project.pbxproj @@ -3,189 +3,145 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 77; objects = { /* Begin PBXBuildFile section */ - F7C04AA3229A73A10099699E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7C04AA2229A73A10099699E /* AppDelegate.swift */; }; - F7C04AA5229A73A10099699E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7C04AA4229A73A10099699E /* ViewController.swift */; }; - F7C04AA8229A73A10099699E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7C04AA6229A73A10099699E /* Main.storyboard */; }; - F7C04AAA229A73A10099699E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F7C04AA9229A73A10099699E /* Assets.xcassets */; }; - F7C04AAD229A73A10099699E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7C04AAB229A73A10099699E /* LaunchScreen.storyboard */; }; - F7C04AC8229A7A670099699E /* KeychainStorage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7C04AC7229A7A670099699E /* KeychainStorage.framework */; }; - F7C04ACA229A7BD70099699E /* MyAppKeychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7C04AC9229A7BD70099699E /* MyAppKeychain.swift */; }; + F7D278782CA9920B0096C830 /* KeychainStorage in Frameworks */ = {isa = PBXBuildFile; productRef = F7D278772CA9920B0096C830 /* KeychainStorage */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - F7C04A9F229A73A10099699E /* KeychainStorageExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KeychainStorageExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; - F7C04AA2229A73A10099699E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - F7C04AA4229A73A10099699E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - F7C04AA7229A73A10099699E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - F7C04AA9229A73A10099699E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - F7C04AAC229A73A10099699E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - F7C04AAE229A73A10099699E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - F7C04AC7229A7A670099699E /* KeychainStorage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = KeychainStorage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - F7C04AC9229A7BD70099699E /* MyAppKeychain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyAppKeychain.swift; sourceTree = ""; }; + F7D278652CA991620096C830 /* KeychainStorageExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KeychainStorageExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ +/* Begin PBXFileSystemSynchronizedRootGroup section */ + F7D278672CA991620096C830 /* KeychainStorageExample */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = KeychainStorageExample; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + /* Begin PBXFrameworksBuildPhase section */ - F7C04A9C229A73A10099699E /* Frameworks */ = { + F7D278622CA991620096C830 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F7C04AC8229A7A670099699E /* KeychainStorage.framework in Frameworks */, + F7D278782CA9920B0096C830 /* KeychainStorage in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - F7C04A96229A73A10099699E = { + F7D2785C2CA991620096C830 = { isa = PBXGroup; children = ( - F7C04AA1229A73A10099699E /* KeychainStorageExample */, - F7C04AA0229A73A10099699E /* Products */, - F7C04AC2229A7A4D0099699E /* Frameworks */, + F7D278672CA991620096C830 /* KeychainStorageExample */, + F7D278662CA991620096C830 /* Products */, ); sourceTree = ""; }; - F7C04AA0229A73A10099699E /* Products */ = { + F7D278662CA991620096C830 /* Products */ = { isa = PBXGroup; children = ( - F7C04A9F229A73A10099699E /* KeychainStorageExample.app */, + F7D278652CA991620096C830 /* KeychainStorageExample.app */, ); name = Products; sourceTree = ""; }; - F7C04AA1229A73A10099699E /* KeychainStorageExample */ = { - isa = PBXGroup; - children = ( - F7C04AA2229A73A10099699E /* AppDelegate.swift */, - F7C04AA4229A73A10099699E /* ViewController.swift */, - F7C04AC9229A7BD70099699E /* MyAppKeychain.swift */, - F7C04AA6229A73A10099699E /* Main.storyboard */, - F7C04AA9229A73A10099699E /* Assets.xcassets */, - F7C04AAB229A73A10099699E /* LaunchScreen.storyboard */, - F7C04AAE229A73A10099699E /* Info.plist */, - ); - path = KeychainStorageExample; - sourceTree = ""; - }; - F7C04AC2229A7A4D0099699E /* Frameworks */ = { - isa = PBXGroup; - children = ( - F7C04AC7229A7A670099699E /* KeychainStorage.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - F7C04A9E229A73A10099699E /* KeychainStorageExample */ = { + F7D278642CA991620096C830 /* KeychainStorageExample */ = { isa = PBXNativeTarget; - buildConfigurationList = F7C04AB1229A73A10099699E /* Build configuration list for PBXNativeTarget "KeychainStorageExample" */; + buildConfigurationList = F7D278732CA991640096C830 /* Build configuration list for PBXNativeTarget "KeychainStorageExample" */; buildPhases = ( - F7C04A9B229A73A10099699E /* Sources */, - F7C04A9C229A73A10099699E /* Frameworks */, - F7C04A9D229A73A10099699E /* Resources */, + F7D278612CA991620096C830 /* Sources */, + F7D278622CA991620096C830 /* Frameworks */, + F7D278632CA991620096C830 /* Resources */, ); buildRules = ( ); dependencies = ( ); + fileSystemSynchronizedGroups = ( + F7D278672CA991620096C830 /* KeychainStorageExample */, + ); name = KeychainStorageExample; + packageProductDependencies = ( + F7D278772CA9920B0096C830 /* KeychainStorage */, + ); productName = KeychainStorageExample; - productReference = F7C04A9F229A73A10099699E /* KeychainStorageExample.app */; + productReference = F7D278652CA991620096C830 /* KeychainStorageExample.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ - F7C04A97229A73A10099699E /* Project object */ = { + F7D2785D2CA991620096C830 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 1020; - LastUpgradeCheck = 1020; - ORGANIZATIONNAME = radude89; + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1600; + LastUpgradeCheck = 1600; TargetAttributes = { - F7C04A9E229A73A10099699E = { - CreatedOnToolsVersion = 10.2.1; + F7D278642CA991620096C830 = { + CreatedOnToolsVersion = 16.0; }; }; }; - buildConfigurationList = F7C04A9A229A73A10099699E /* Build configuration list for PBXProject "KeychainStorageExample" */; - compatibilityVersion = "Xcode 9.3"; + buildConfigurationList = F7D278602CA991620096C830 /* Build configuration list for PBXProject "KeychainStorageExample" */; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); - mainGroup = F7C04A96229A73A10099699E; - productRefGroup = F7C04AA0229A73A10099699E /* Products */; + mainGroup = F7D2785C2CA991620096C830; + minimizedProjectReferenceProxies = 1; + packageReferences = ( + F7D278762CA9920B0096C830 /* XCLocalSwiftPackageReference "../../KeychainStorage" */, + ); + preferredProjectObjectVersion = 77; + productRefGroup = F7D278662CA991620096C830 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - F7C04A9E229A73A10099699E /* KeychainStorageExample */, + F7D278642CA991620096C830 /* KeychainStorageExample */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - F7C04A9D229A73A10099699E /* Resources */ = { + F7D278632CA991620096C830 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - F7C04AAD229A73A10099699E /* LaunchScreen.storyboard in Resources */, - F7C04AAA229A73A10099699E /* Assets.xcassets in Resources */, - F7C04AA8229A73A10099699E /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - F7C04A9B229A73A10099699E /* Sources */ = { + F7D278612CA991620096C830 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - F7C04AA5229A73A10099699E /* ViewController.swift in Sources */, - F7C04AA3229A73A10099699E /* AppDelegate.swift in Sources */, - F7C04ACA229A7BD70099699E /* MyAppKeychain.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXVariantGroup section */ - F7C04AA6229A73A10099699E /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - F7C04AA7229A73A10099699E /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - F7C04AAB229A73A10099699E /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - F7C04AAC229A73A10099699E /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - /* Begin XCBuildConfiguration section */ - F7C04AAF229A73A10099699E /* Debug */ = { + F7D278712CA991640096C830 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; @@ -204,18 +160,19 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; @@ -229,24 +186,25 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.2; + IPHONEOS_DEPLOYMENT_TARGET = 18.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; - F7C04AB0229A73A10099699E /* Release */ = { + F7D278722CA991640096C830 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; @@ -265,18 +223,19 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -284,45 +243,69 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.2; + IPHONEOS_DEPLOYMENT_TARGET = 18.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; VALIDATE_PRODUCT = YES; }; name = Release; }; - F7C04AB2229A73A10099699E /* Debug */ = { + F7D278742CA991640096C830 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - INFOPLIST_FILE = KeychainStorageExample/Info.plist; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"KeychainStorageExample/Preview Content\""; + DEVELOPMENT_TEAM = 42L6GB6DU6; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.radude89.KeychainStorageExample; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.rdan.KeychainStorageExample; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - F7C04AB3229A73A10099699E /* Release */ = { + F7D278752CA991640096C830 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - INFOPLIST_FILE = KeychainStorageExample/Info.plist; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"KeychainStorageExample/Preview Content\""; + DEVELOPMENT_TEAM = 42L6GB6DU6; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.radude89.KeychainStorageExample; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.rdan.KeychainStorageExample; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -331,25 +314,39 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - F7C04A9A229A73A10099699E /* Build configuration list for PBXProject "KeychainStorageExample" */ = { + F7D278602CA991620096C830 /* Build configuration list for PBXProject "KeychainStorageExample" */ = { isa = XCConfigurationList; buildConfigurations = ( - F7C04AAF229A73A10099699E /* Debug */, - F7C04AB0229A73A10099699E /* Release */, + F7D278712CA991640096C830 /* Debug */, + F7D278722CA991640096C830 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - F7C04AB1229A73A10099699E /* Build configuration list for PBXNativeTarget "KeychainStorageExample" */ = { + F7D278732CA991640096C830 /* Build configuration list for PBXNativeTarget "KeychainStorageExample" */ = { isa = XCConfigurationList; buildConfigurations = ( - F7C04AB2229A73A10099699E /* Debug */, - F7C04AB3229A73A10099699E /* Release */, + F7D278742CA991640096C830 /* Debug */, + F7D278752CA991640096C830 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + F7D278762CA9920B0096C830 /* XCLocalSwiftPackageReference "../../KeychainStorage" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = ../../KeychainStorage; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + F7D278772CA9920B0096C830 /* KeychainStorage */ = { + isa = XCSwiftPackageProductDependency; + productName = KeychainStorage; + }; +/* End XCSwiftPackageProductDependency section */ }; - rootObject = F7C04A97229A73A10099699E /* Project object */; + rootObject = F7D2785D2CA991620096C830 /* Project object */; } diff --git a/KeychainStorage.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Example/KeychainStorageExample/KeychainStorageExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 90% rename from KeychainStorage.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to Example/KeychainStorageExample/KeychainStorageExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata index fe1aa71..919434a 100644 --- a/KeychainStorage.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/Example/KeychainStorageExample/KeychainStorageExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,4 @@ - \ No newline at end of file + diff --git a/Example/KeychainStorageExample/KeychainStorageExample/Assets.xcassets/AccentColor.colorset/Contents.json b/Example/KeychainStorageExample/KeychainStorageExample/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/Example/KeychainStorageExample/KeychainStorageExample/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/KeychainStorageExample/KeychainStorageExample/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example/KeychainStorageExample/KeychainStorageExample/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..2305880 --- /dev/null +++ b/Example/KeychainStorageExample/KeychainStorageExample/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/KeychainStorageExample/KeychainStorageExample/Assets.xcassets/Contents.json b/Example/KeychainStorageExample/KeychainStorageExample/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example/KeychainStorageExample/KeychainStorageExample/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/KeychainStorageExample/KeychainStorageExample/ContentView.swift b/Example/KeychainStorageExample/KeychainStorageExample/ContentView.swift new file mode 100644 index 0000000..6b076bc --- /dev/null +++ b/Example/KeychainStorageExample/KeychainStorageExample/ContentView.swift @@ -0,0 +1,79 @@ +import SwiftUI + +struct ContentView: View { + @State private var rememberMe = false + @State private var secret = "" + @State private var outputText = Self.initialOutput + + private static let initialOutput = "Enter your desired values to be stored in Keychain and tap 'Store Value' button." + + private let keychain = MyAppKeychain.shared + + var body: some View { + VStack(spacing: 20) { + Text(outputText) + .multilineTextAlignment(.center) + .padding() + + Toggle("Remember Me", isOn: $rememberMe) + .padding() + + TextField("Enter secret", text: $secret) + .textFieldStyle(RoundedBorderTextFieldStyle()) + .padding() + + Button(action: onTouchStoreValues) { + Text("Store Values") + .fontWeight(.bold) + .padding() + .background(Color.blue) + .foregroundColor(.white) + .cornerRadius(8) + } + Button(action: clearValues) { + Text("Clear Values") + .fontWeight(.bold) + .padding() + .background(Color.blue) + .foregroundColor(.white) + .cornerRadius(8) + } + } + .padding() + .onAppear { + readValues() + } + } + + private func onTouchStoreValues() { + guard !secret.isEmpty else { return } + + keychain.rememberMe = rememberMe + keychain.secret = secret + + outputText = "Reading values from Keychain\n" + outputText += "Remember me: \(keychain.rememberMe == true)\n" + outputText += "Secret: \(keychain.secret ?? "-")" + } + + private func readValues() { + guard let rememberMe = keychain.rememberMe, + let secret = keychain.secret else { + return + } + + outputText = "Reading values from Keychain\n" + outputText += "Remember me: \(rememberMe)\n" + outputText += "Secret: \(secret)" + } + + private func clearValues() { + keychain.rememberMe = nil + keychain.secret = nil + outputText = Self.initialOutput + } +} + +#Preview { + ContentView() +} diff --git a/Example/KeychainStorageExample/KeychainStorageExample/KeychainStorageExampleApp.swift b/Example/KeychainStorageExample/KeychainStorageExample/KeychainStorageExampleApp.swift new file mode 100644 index 0000000..87db8b3 --- /dev/null +++ b/Example/KeychainStorageExample/KeychainStorageExample/KeychainStorageExampleApp.swift @@ -0,0 +1,17 @@ +// +// KeychainStorageExampleApp.swift +// KeychainStorageExample +// +// Created by Radu Dan on 29.09.2024. +// + +import SwiftUI + +@main +struct KeychainStorageExampleApp: App { + var body: some Scene { + WindowGroup { + ContentView() + } + } +} diff --git a/Example/KeychainStorageExample/MyAppKeychain.swift b/Example/KeychainStorageExample/KeychainStorageExample/MyAppKeychain.swift similarity index 100% rename from Example/KeychainStorageExample/MyAppKeychain.swift rename to Example/KeychainStorageExample/KeychainStorageExample/MyAppKeychain.swift diff --git a/Example/KeychainStorageExample/KeychainStorageExample/Preview Content/Preview Assets.xcassets/Contents.json b/Example/KeychainStorageExample/KeychainStorageExample/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Example/KeychainStorageExample/KeychainStorageExample/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/KeychainStorageExample/ViewController.swift b/Example/KeychainStorageExample/ViewController.swift deleted file mode 100644 index e566ee3..0000000 --- a/Example/KeychainStorageExample/ViewController.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// ViewController.swift -// KeychainStorageExample -// -// Created by Dan, Radu-Ionut (RO - Bucharest) on 26/05/2019. -// Copyright © 2019 radude89. All rights reserved. -// - -import UIKit - -class ViewController: UIViewController { - - @IBOutlet weak var uiSwitch: UISwitch! - @IBOutlet weak var textField: UITextField! - @IBOutlet weak var outputLabel: UILabel! - - private let keychain = MyAppKeychain.shared - - override func viewDidLoad() { - super.viewDidLoad() - - outputLabel.text = "Enter your desired values to be stored in Keychain and touch 'Store Value' button." - } - - @IBAction func onTouchStoreValues(_ sender: Any) { - guard textField.text?.isEmpty == false else { return } - - keychain.rememberMe = uiSwitch.isOn - keychain.secret = textField.text - - outputLabel.text = "Reading values from Keychain\n" - - outputLabel.text?.append("Remember me: \(keychain.rememberMe == true)\n") - outputLabel.text?.append("Secret: \(keychain.secret ?? "-")") - } - -} diff --git a/KeychainStorage.podspec b/KeychainStorage.podspec deleted file mode 100644 index 5a03e06..0000000 --- a/KeychainStorage.podspec +++ /dev/null @@ -1,32 +0,0 @@ -# -# Be sure to run `pod spec lint KeychainStorage.podspec' to ensure this is a -# valid spec and to remove all comments including this before submitting the spec. -# -# To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html -# To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ -# - -Pod::Spec.new do |s| - - s.platform = :ios - s.ios.deployment_target = '12.0' - s.name = "KeychainStorage" - s.summary = "KeychainStorage is a simple wrapper for Keychain items. Use it to quickly save and retrieve sensitive information from Keychain." - s.requires_arc = true - - s.version = "1.3.0" - - s.license = { :type => "MIT", :file => "LICENSE" } - - s.author = { "Radu Dan" => "contact@radude89.com" } - - s.homepage = "https://github.com/radude89/KeychainStorage" - - s.source = { :git => "https://github.com/radude89/KeychainStorage.git", - :tag => "#{s.version}" } - - s.source_files = "KeychainStorage/*.{swift}" - s.swift_version = "5.0" - s.ios.framework = 'Security' - -end diff --git a/KeychainStorage.xcodeproj/KeychainStorageTests_Info.plist b/KeychainStorage.xcodeproj/KeychainStorageTests_Info.plist deleted file mode 100644 index 7c23420..0000000 --- a/KeychainStorage.xcodeproj/KeychainStorageTests_Info.plist +++ /dev/null @@ -1,25 +0,0 @@ - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSPrincipalClass - - - diff --git a/KeychainStorage.xcodeproj/KeychainStorage_Info.plist b/KeychainStorage.xcodeproj/KeychainStorage_Info.plist deleted file mode 100644 index 9f4a4aa..0000000 --- a/KeychainStorage.xcodeproj/KeychainStorage_Info.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.3.0 - CFBundleSignature - ???? - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSPrincipalClass - - - diff --git a/KeychainStorage.xcodeproj/project.pbxproj b/KeychainStorage.xcodeproj/project.pbxproj deleted file mode 100644 index ccc9e2d..0000000 --- a/KeychainStorage.xcodeproj/project.pbxproj +++ /dev/null @@ -1,721 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXAggregateTarget section */ - "KeychainStorage::KeychainStoragePackageTests::ProductTarget" /* KeychainStoragePackageTests */ = { - isa = PBXAggregateTarget; - buildConfigurationList = OBJ_46 /* Build configuration list for PBXAggregateTarget "KeychainStoragePackageTests" */; - buildPhases = ( - ); - dependencies = ( - OBJ_49 /* PBXTargetDependency */, - ); - name = KeychainStoragePackageTests; - productName = KeychainStoragePackageTests; - }; -/* End PBXAggregateTarget section */ - -/* Begin PBXBuildFile section */ - F7C30DF422D60E0D00D05EA7 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7C30DF322D60E0D00D05EA7 /* AppDelegate.swift */; }; - OBJ_35 /* KeyValueStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_11 /* KeyValueStorage.swift */; }; - OBJ_36 /* KeychainQueryFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* KeychainQueryFactory.swift */; }; - OBJ_37 /* KeychainStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_13 /* KeychainStorage.swift */; }; - OBJ_44 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_6 /* Package.swift */; }; - OBJ_55 /* KeychainQueryFactoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_17 /* KeychainQueryFactoryTests.swift */; }; - OBJ_56 /* KeychainStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_18 /* KeychainStorageTests.swift */; }; - OBJ_58 /* KeychainStorage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "KeychainStorage::KeychainStorage::Product" /* KeychainStorage.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - F792A21A22D608DB00A42B61 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = OBJ_1 /* Project object */; - proxyType = 1; - remoteGlobalIDString = "KeychainStorage::KeychainStorage"; - remoteInfo = KeychainStorage; - }; - F792A21B22D608DD00A42B61 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = OBJ_1 /* Project object */; - proxyType = 1; - remoteGlobalIDString = "KeychainStorage::KeychainStorageTests"; - remoteInfo = KeychainStorageTests; - }; - F7C30E0322D60EA000D05EA7 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = OBJ_1 /* Project object */; - proxyType = 1; - remoteGlobalIDString = F7C30DF022D60E0D00D05EA7; - remoteInfo = KeychainStorageHostApp; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - F7C30DF122D60E0D00D05EA7 /* KeychainStorageHostApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KeychainStorageHostApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; - F7C30DF322D60E0D00D05EA7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - F7C30DFF22D60E0E00D05EA7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - "KeychainStorage::KeychainStorage::Product" /* KeychainStorage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = KeychainStorage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - "KeychainStorage::KeychainStorageTests::Product" /* KeychainStorageTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = KeychainStorageTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - OBJ_10 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - OBJ_11 /* KeyValueStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyValueStorage.swift; sourceTree = ""; }; - OBJ_12 /* KeychainQueryFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainQueryFactory.swift; sourceTree = ""; }; - OBJ_13 /* KeychainStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainStorage.swift; sourceTree = ""; }; - OBJ_16 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - OBJ_17 /* KeychainQueryFactoryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainQueryFactoryTests.swift; sourceTree = ""; }; - OBJ_18 /* KeychainStorageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainStorageTests.swift; sourceTree = ""; }; - OBJ_27 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; - OBJ_28 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; - OBJ_29 /* KeychainStorage.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = KeychainStorage.podspec; sourceTree = ""; }; - OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; - OBJ_9 /* KeychainStorage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeychainStorage.h; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - F7C30DEE22D60E0D00D05EA7 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - OBJ_38 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - OBJ_57 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 0; - files = ( - OBJ_58 /* KeychainStorage.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - F7C30DF222D60E0D00D05EA7 /* KeychainStorageHostApp */ = { - isa = PBXGroup; - children = ( - F7C30DF322D60E0D00D05EA7 /* AppDelegate.swift */, - F7C30DFF22D60E0E00D05EA7 /* Info.plist */, - ); - path = KeychainStorageHostApp; - sourceTree = ""; - }; - OBJ_14 /* Tests */ = { - isa = PBXGroup; - children = ( - OBJ_15 /* KeychainStorageTests */, - ); - name = Tests; - sourceTree = SOURCE_ROOT; - }; - OBJ_15 /* KeychainStorageTests */ = { - isa = PBXGroup; - children = ( - OBJ_16 /* Info.plist */, - OBJ_17 /* KeychainQueryFactoryTests.swift */, - OBJ_18 /* KeychainStorageTests.swift */, - ); - path = KeychainStorageTests; - sourceTree = SOURCE_ROOT; - }; - OBJ_19 /* Products */ = { - isa = PBXGroup; - children = ( - "KeychainStorage::KeychainStorageTests::Product" /* KeychainStorageTests.xctest */, - "KeychainStorage::KeychainStorage::Product" /* KeychainStorage.framework */, - F7C30DF122D60E0D00D05EA7 /* KeychainStorageHostApp.app */, - ); - name = Products; - sourceTree = BUILT_PRODUCTS_DIR; - }; - OBJ_5 = { - isa = PBXGroup; - children = ( - OBJ_6 /* Package.swift */, - OBJ_7 /* Sources */, - OBJ_14 /* Tests */, - F7C30DF222D60E0D00D05EA7 /* KeychainStorageHostApp */, - OBJ_19 /* Products */, - OBJ_27 /* LICENSE */, - OBJ_28 /* README.md */, - OBJ_29 /* KeychainStorage.podspec */, - ); - sourceTree = ""; - }; - OBJ_7 /* Sources */ = { - isa = PBXGroup; - children = ( - OBJ_8 /* KeychainStorage */, - ); - name = Sources; - sourceTree = SOURCE_ROOT; - }; - OBJ_8 /* KeychainStorage */ = { - isa = PBXGroup; - children = ( - OBJ_9 /* KeychainStorage.h */, - OBJ_10 /* Info.plist */, - OBJ_11 /* KeyValueStorage.swift */, - OBJ_12 /* KeychainQueryFactory.swift */, - OBJ_13 /* KeychainStorage.swift */, - ); - path = KeychainStorage; - sourceTree = SOURCE_ROOT; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - F7C30DF022D60E0D00D05EA7 /* KeychainStorageHostApp */ = { - isa = PBXNativeTarget; - buildConfigurationList = F7C30E0222D60E0E00D05EA7 /* Build configuration list for PBXNativeTarget "KeychainStorageHostApp" */; - buildPhases = ( - F7C30DED22D60E0D00D05EA7 /* Sources */, - F7C30DEE22D60E0D00D05EA7 /* Frameworks */, - F7C30DEF22D60E0D00D05EA7 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = KeychainStorageHostApp; - productName = KeychainStorageHostApp; - productReference = F7C30DF122D60E0D00D05EA7 /* KeychainStorageHostApp.app */; - productType = "com.apple.product-type.application"; - }; - "KeychainStorage::KeychainStorage" /* KeychainStorage */ = { - isa = PBXNativeTarget; - buildConfigurationList = OBJ_31 /* Build configuration list for PBXNativeTarget "KeychainStorage" */; - buildPhases = ( - OBJ_34 /* Sources */, - OBJ_38 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = KeychainStorage; - productName = KeychainStorage; - productReference = "KeychainStorage::KeychainStorage::Product" /* KeychainStorage.framework */; - productType = "com.apple.product-type.framework"; - }; - "KeychainStorage::KeychainStorageTests" /* KeychainStorageTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = OBJ_51 /* Build configuration list for PBXNativeTarget "KeychainStorageTests" */; - buildPhases = ( - OBJ_54 /* Sources */, - OBJ_57 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - OBJ_59 /* PBXTargetDependency */, - F7C30E0422D60EA000D05EA7 /* PBXTargetDependency */, - ); - name = KeychainStorageTests; - productName = KeychainStorageTests; - productReference = "KeychainStorage::KeychainStorageTests::Product" /* KeychainStorageTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - "KeychainStorage::SwiftPMPackageDescription" /* KeychainStoragePackageDescription */ = { - isa = PBXNativeTarget; - buildConfigurationList = OBJ_40 /* Build configuration list for PBXNativeTarget "KeychainStoragePackageDescription" */; - buildPhases = ( - OBJ_43 /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = KeychainStoragePackageDescription; - productName = KeychainStoragePackageDescription; - productType = "com.apple.product-type.framework"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - OBJ_1 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftMigration = 9999; - LastSwiftUpdateCheck = 1020; - LastUpgradeCheck = 9999; - TargetAttributes = { - F7C30DF022D60E0D00D05EA7 = { - CreatedOnToolsVersion = 10.2.1; - ProvisioningStyle = Automatic; - }; - "KeychainStorage::KeychainStorageTests" = { - TestTargetID = F7C30DF022D60E0D00D05EA7; - }; - }; - }; - buildConfigurationList = OBJ_2 /* Build configuration list for PBXProject "KeychainStorage" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - English, - en, - Base, - ); - mainGroup = OBJ_5; - productRefGroup = OBJ_19 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - "KeychainStorage::KeychainStorage" /* KeychainStorage */, - "KeychainStorage::SwiftPMPackageDescription" /* KeychainStoragePackageDescription */, - "KeychainStorage::KeychainStoragePackageTests::ProductTarget" /* KeychainStoragePackageTests */, - "KeychainStorage::KeychainStorageTests" /* KeychainStorageTests */, - F7C30DF022D60E0D00D05EA7 /* KeychainStorageHostApp */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - F7C30DEF22D60E0D00D05EA7 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - F7C30DED22D60E0D00D05EA7 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F7C30DF422D60E0D00D05EA7 /* AppDelegate.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - OBJ_34 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 0; - files = ( - OBJ_35 /* KeyValueStorage.swift in Sources */, - OBJ_36 /* KeychainQueryFactory.swift in Sources */, - OBJ_37 /* KeychainStorage.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - OBJ_43 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 0; - files = ( - OBJ_44 /* Package.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - OBJ_54 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 0; - files = ( - OBJ_55 /* KeychainQueryFactoryTests.swift in Sources */, - OBJ_56 /* KeychainStorageTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - F7C30E0422D60EA000D05EA7 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F7C30DF022D60E0D00D05EA7 /* KeychainStorageHostApp */; - targetProxy = F7C30E0322D60EA000D05EA7 /* PBXContainerItemProxy */; - }; - OBJ_49 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = "KeychainStorage::KeychainStorageTests" /* KeychainStorageTests */; - targetProxy = F792A21B22D608DD00A42B61 /* PBXContainerItemProxy */; - }; - OBJ_59 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = "KeychainStorage::KeychainStorage" /* KeychainStorage */; - targetProxy = F792A21A22D608DB00A42B61 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - F7C30E0022D60E0E00D05EA7 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = KeychainStorageHostApp/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = com.radude89.KeychainStorageHostApp; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - F7C30E0122D60E0E00D05EA7 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - COPY_PHASE_STRIP = NO; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = KeychainStorageHostApp/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.2; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = com.radude89.KeychainStorageHostApp; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - OBJ_3 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_NS_ASSERTIONS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - "SWIFT_PACKAGE=1", - "DEBUG=1", - ); - MACOSX_DEPLOYMENT_TARGET = 10.10; - ONLY_ACTIVE_ARCH = YES; - OTHER_SWIFT_FLAGS = "-DXcode"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) SWIFT_PACKAGE DEBUG"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - USE_HEADERMAP = NO; - }; - name = Debug; - }; - OBJ_32 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ENABLE_TESTABILITY = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PLATFORM_DIR)/Developer/Library/Frameworks", - ); - HEADER_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = KeychainStorage.xcodeproj/KeychainStorage_Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; - MACOSX_DEPLOYMENT_TARGET = 10.10; - OTHER_CFLAGS = "$(inherited)"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited)"; - PRODUCT_BUNDLE_IDENTIFIER = KeychainStorage; - PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; - SWIFT_VERSION = 5.0; - TARGET_NAME = KeychainStorage; - TVOS_DEPLOYMENT_TARGET = 9.0; - WATCHOS_DEPLOYMENT_TARGET = 2.0; - }; - name = Debug; - }; - OBJ_33 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ENABLE_TESTABILITY = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PLATFORM_DIR)/Developer/Library/Frameworks", - ); - HEADER_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = KeychainStorage.xcodeproj/KeychainStorage_Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; - MACOSX_DEPLOYMENT_TARGET = 10.10; - OTHER_CFLAGS = "$(inherited)"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited)"; - PRODUCT_BUNDLE_IDENTIFIER = KeychainStorage; - PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; - SWIFT_VERSION = 5.0; - TARGET_NAME = KeychainStorage; - TVOS_DEPLOYMENT_TARGET = 9.0; - WATCHOS_DEPLOYMENT_TARGET = 2.0; - }; - name = Release; - }; - OBJ_4 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_OPTIMIZATION_LEVEL = s; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - "SWIFT_PACKAGE=1", - ); - MACOSX_DEPLOYMENT_TARGET = 10.10; - OTHER_SWIFT_FLAGS = "-DXcode"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) SWIFT_PACKAGE"; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - USE_HEADERMAP = NO; - }; - name = Release; - }; - OBJ_41 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - LD = /usr/bin/true; - OTHER_SWIFT_FLAGS = "-swift-version 5 -I $(TOOLCHAIN_DIR)/usr/lib/swift/pm/4_2 -target x86_64-apple-macosx10.10 -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk"; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - OBJ_42 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - LD = /usr/bin/true; - OTHER_SWIFT_FLAGS = "-swift-version 5 -I $(TOOLCHAIN_DIR)/usr/lib/swift/pm/4_2 -target x86_64-apple-macosx10.10 -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk"; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; - OBJ_47 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Debug; - }; - OBJ_48 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Release; - }; - OBJ_52 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PLATFORM_DIR)/Developer/Library/Frameworks", - ); - HEADER_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = KeychainStorage.xcodeproj/KeychainStorageTests_Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.10; - OTHER_CFLAGS = "$(inherited)"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited)"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; - SWIFT_VERSION = 5.0; - TARGET_NAME = KeychainStorageTests; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/KeychainStorageHostApp.app/KeychainStorageHostApp"; - TVOS_DEPLOYMENT_TARGET = 9.0; - WATCHOS_DEPLOYMENT_TARGET = 2.0; - }; - name = Debug; - }; - OBJ_53 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PLATFORM_DIR)/Developer/Library/Frameworks", - ); - HEADER_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = KeychainStorage.xcodeproj/KeychainStorageTests_Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.10; - OTHER_CFLAGS = "$(inherited)"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited)"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; - SWIFT_VERSION = 5.0; - TARGET_NAME = KeychainStorageTests; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/KeychainStorageHostApp.app/KeychainStorageHostApp"; - TVOS_DEPLOYMENT_TARGET = 9.0; - WATCHOS_DEPLOYMENT_TARGET = 2.0; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - F7C30E0222D60E0E00D05EA7 /* Build configuration list for PBXNativeTarget "KeychainStorageHostApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - F7C30E0022D60E0E00D05EA7 /* Debug */, - F7C30E0122D60E0E00D05EA7 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - OBJ_2 /* Build configuration list for PBXProject "KeychainStorage" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - OBJ_3 /* Debug */, - OBJ_4 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - OBJ_31 /* Build configuration list for PBXNativeTarget "KeychainStorage" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - OBJ_32 /* Debug */, - OBJ_33 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - OBJ_40 /* Build configuration list for PBXNativeTarget "KeychainStoragePackageDescription" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - OBJ_41 /* Debug */, - OBJ_42 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - OBJ_46 /* Build configuration list for PBXAggregateTarget "KeychainStoragePackageTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - OBJ_47 /* Debug */, - OBJ_48 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - OBJ_51 /* Build configuration list for PBXNativeTarget "KeychainStorageTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - OBJ_52 /* Debug */, - OBJ_53 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = OBJ_1 /* Project object */; -} diff --git a/KeychainStorage.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/KeychainStorage.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/KeychainStorage.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/KeychainStorage.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/KeychainStorage.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index a72dc2b..0000000 --- a/KeychainStorage.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded - - - \ No newline at end of file diff --git a/KeychainStorage.xcodeproj/xcshareddata/xcschemes/KeychainStorage-Package.xcscheme b/KeychainStorage.xcodeproj/xcshareddata/xcschemes/KeychainStorage-Package.xcscheme deleted file mode 100644 index 2e0713e..0000000 --- a/KeychainStorage.xcodeproj/xcshareddata/xcschemes/KeychainStorage-Package.xcscheme +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/KeychainStorage.xcodeproj/xcshareddata/xcschemes/KeychainStorage.xcscheme b/KeychainStorage.xcodeproj/xcshareddata/xcschemes/KeychainStorage.xcscheme deleted file mode 100644 index 0d12dcc..0000000 --- a/KeychainStorage.xcodeproj/xcshareddata/xcschemes/KeychainStorage.xcscheme +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/KeychainStorage/.gitignore b/KeychainStorage/.gitignore new file mode 100644 index 0000000..0023a53 --- /dev/null +++ b/KeychainStorage/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +/.build +/Packages +xcuserdata/ +DerivedData/ +.swiftpm/configuration/registries.json +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +.netrc diff --git a/KeychainStorage/Info.plist b/KeychainStorage/Info.plist deleted file mode 100644 index c701d98..0000000 --- a/KeychainStorage/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.2 - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - - diff --git a/KeychainStorage/KeyValueStorage.swift b/KeychainStorage/KeyValueStorage.swift deleted file mode 100644 index a55c9e7..0000000 --- a/KeychainStorage/KeyValueStorage.swift +++ /dev/null @@ -1,71 +0,0 @@ -// -// KeyValueStorage.swift -// KeychainStorage -// -// Created by Dan, Radu-Ionut (RO - Bucharest) on 25/05/2019. -// Copyright © 2019 radude89. All rights reserved. -// - -import Foundation - -// MARK: - KV Storage - -/// Base protocol for KeyValue storages, e.g. Keychain or UserDefaults -public protocol KeyValueStorage { - - /// Returns the string value of the given key. - /// - /// - Parameter key: The key we want to search the value. - /// - Returns: The value of the given key. - /// - Throws: Can throw errors, for example if data is invalid or if there was a transformation error. - func string(forKey key: String) throws -> String? - - /// Returns the data value of the given key. - /// - /// - Parameter key: The key we want to search the value. - /// - Returns: The value of the given key. - /// - Throws: Can throw errors, for example if data is invalid or if there was a transformation error. - func data(forKey key: String) throws -> Data? - - /// Returns the bool value of the given key. - /// - /// - Parameter key: The key we want to search the value. - /// - Returns: The value of the given key. - /// - Throws: Can throw errors, for example if data is invalid or if there was a transformation error. - func bool(forKey key: String) throws -> Bool? - - /// Sets a string value at a given key. - /// - /// - Parameters: - /// - value: The value we want to store. - /// - key: The key where we want to store the value. - /// - Throws: Can throw errors, for example if data is invalid or if there was a transformation error. - func set(_ value: String, key: String) throws - - /// Sets a data value at a given key. - /// - /// - Parameters: - /// - value: The value we want to store. - /// - key: The key where we want to store the value. - /// - Throws: Can throw errors, for example if data is invalid or if there was a transformation error. - func set(_ value: Data, key: String) throws - - /// Sets a bool value at a given key. - /// - /// - Parameters: - /// - value: The value we want to store. - /// - key: The key where we want to store the value. - /// - Throws: Can throw errors, for example if data is invalid or if there was a transformation error. - func set(_ value: Bool, key: String) throws - - /// Removes the value at a given key. - /// - /// - Parameter key: The key we want to remove the value. - /// - Throws: Can throw errors if the operation was unsuccessful. - func removeValue(forKey key: String) throws - - /// Removes all values from the storage. - /// - /// - Throws: Can throw errors if a value failed to be removed from the storage. - func removeAll() throws -} diff --git a/KeychainStorage/KeychainQueryFactory.swift b/KeychainStorage/KeychainQueryFactory.swift deleted file mode 100644 index 3ec38d3..0000000 --- a/KeychainStorage/KeychainQueryFactory.swift +++ /dev/null @@ -1,114 +0,0 @@ -// -// KeychainQueryFactory.swift -// KeychainStorage -// -// Created by Dan, Radu-Ionut (RO - Bucharest) on 25/05/2019. -// Copyright © 2019 radude89. All rights reserved. -// - -import Foundation -import Security - -// MARK: - KeychainQueryBasicConfiguration - -/// This structure defines a basic configuration for making queries for Keychain items. -struct KeychainBasicQueryConfiguration { - - /// Defines the item class value, kSecClass. - /// Can be a: - /// * generic password item (kSecClassGenericPassword) - /// * Internet password item (kSecClassInternetPassword) - /// * certificate item (kSecClassCertificate) - /// * cryptographic key item (kSecClassKey) - /// * identity item (kSecClassIdentity) - let secClass: String - - /// Defines the matching limit for a Keychain item. - /// Can be either `kSecMatchLimitAll`, where an unlimited number of items can be matched - /// or `kSecMatchLimitOne`, where a single item will be matched. - let matchLimit: String - - /// Determines if data should be returned or not. - let returnData: Bool - - /// Determines if attributes should be returned or not - let returnAttributes: Bool - - /// Default initializer where all parameters are set. - /// - /// - Parameters: - /// - secClass: Sets the item class value. - /// - matchLimit: Sets the match limit of the query. - /// - returnData: Sets the parameter for returning data or not. - /// - returnAttributes: Sets the parameter for returning attributes or not. - init(secClass: String = kSecClassGenericPassword as String, - matchLimit: String = kSecMatchLimitOne as String, - returnData: Bool = true, - returnAttributes: Bool = true) { - self.secClass = secClass - self.matchLimit = matchLimit - self.returnData = returnData - self.returnAttributes = returnAttributes - } -} - -// MARK: - KeychainBasicQueryFactory - -/// Dictionary alias that represents keychain queries -typealias KeychainQuery = [String: Any] - -/// Creates queries for accessing the Keychain -enum KeychainBasicQueryFactory { - - /// Makes a Keychain query based on a service, configuration, account and value. - /// - /// - Parameters: - /// - service: The Keychain item's service. - /// - key: The item's account name. Can be nil. - /// - value: The item's value. Can be nil. - /// - configuration: The configuration of the Keychain query. - /// - Returns: The Keychain query. - static func makeQuery(forService service: String, - key: String? = nil, - value: Data? = nil, - configuration: KeychainBasicQueryConfiguration = KeychainBasicQueryConfiguration()) -> KeychainQuery { - var queryDictionary: [String: Any] = [:] - queryDictionary[kSecAttrService as String] = service - queryDictionary[kSecClass as String] = configuration.secClass - - if let key = key { - queryDictionary[kSecAttrAccount as String] = key - } - - if let value = value { - queryDictionary[kSecValueData as String] = value - } else { - queryDictionary[kSecMatchLimit as String] = configuration.matchLimit - queryDictionary[kSecReturnData as String] = configuration.returnData - queryDictionary[kSecReturnAttributes as String] = configuration.returnAttributes - } - - return queryDictionary - } - - /// Makes a query to delete items from Keychain based on a service, configuration and key. - /// - /// - Parameters: - /// - service: The Keychain item's service. - /// - key: The item's account name. Can be nil. - /// - configuration: The configuration of the Keychain query. - /// - Returns: The Keychain query. - static func makeDeleteQuery(forService service: String, - key: String? = nil, - configuration: KeychainBasicQueryConfiguration = KeychainBasicQueryConfiguration()) -> KeychainQuery { - var queryDictionary: [String: Any] = [:] - queryDictionary[kSecAttrService as String] = service - queryDictionary[kSecClass as String] = configuration.secClass - - if let key = key { - queryDictionary[kSecAttrAccount as String] = key - } - - return queryDictionary - } -} diff --git a/KeychainStorage/KeychainStorage.h b/KeychainStorage/KeychainStorage.h deleted file mode 100644 index e503726..0000000 --- a/KeychainStorage/KeychainStorage.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// KeychainStorage.h -// KeychainStorage -// -// Created by Dan, Radu-Ionut (RO - Bucharest) on 25/05/2019. -// Copyright © 2019 radude89. All rights reserved. -// - -#import - -//! Project version number for KeychainStorage. -FOUNDATION_EXPORT double KeychainStorageVersionNumber; - -//! Project version string for KeychainStorage. -FOUNDATION_EXPORT const unsigned char KeychainStorageVersionString[]; - -// In this header, you should import all the public headers of your framework using statements like #import - - diff --git a/KeychainStorage/Package.swift b/KeychainStorage/Package.swift new file mode 100644 index 0000000..95c4e86 --- /dev/null +++ b/KeychainStorage/Package.swift @@ -0,0 +1,27 @@ +// swift-tools-version: 6.0 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "KeychainStorage", + platforms: [ + .macOS(.v15), .iOS(.v18), .tvOS(.v18) + ], + products: [ + // Products define the executables and libraries a package produces, making them visible to other packages. + .library( + name: "KeychainStorage", + targets: ["KeychainStorage"]), + ], + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products from dependencies. + .target( + name: "KeychainStorage"), + .testTarget( + name: "KeychainStorageTests", + dependencies: ["KeychainStorage"] + ), + ] +) diff --git a/KeychainStorage/Sources/KeychainStorage/KeyValueStorage.swift b/KeychainStorage/Sources/KeychainStorage/KeyValueStorage.swift new file mode 100644 index 0000000..95642a7 --- /dev/null +++ b/KeychainStorage/Sources/KeychainStorage/KeyValueStorage.swift @@ -0,0 +1,64 @@ +import Foundation + +// MARK: - Key-Value Storage + +/// A protocol defining a generic key-value storage interface. +/// Conforming types can implement storage solutions such as Keychain or UserDefaults. +public protocol KeyValueStorage { + + /// Retrieves the string value associated with the specified key. + /// + /// - Parameter key: The key for which to retrieve the value. + /// - Returns: The string value associated with the key, or `nil` if not found. + /// - Throws: Throws an error if the data is invalid or if a transformation error occurs. + func string(forKey key: String) throws -> String? + + /// Retrieves the data value associated with the specified key. + /// + /// - Parameter key: The key for which to retrieve the value. + /// - Returns: The data value associated with the key, or `nil` if not found. + /// - Throws: Throws an error if the data is invalid or if a transformation error occurs. + func data(forKey key: String) throws -> Data? + + /// Retrieves the Boolean value associated with the specified key. + /// + /// - Parameter key: The key for which to retrieve the value. + /// - Returns: The Boolean value associated with the key, or `nil` if not found. + /// - Throws: Throws an error if the data is invalid or if a transformation error occurs. + func bool(forKey key: String) throws -> Bool? + + /// Stores a string value at the specified key. + /// + /// - Parameters: + /// - value: The string value to be stored. + /// - key: The key under which to store the value. + /// - Throws: Throws an error if the data is invalid or if a transformation error occurs. + func set(_ value: String, key: String) throws + + /// Stores a data value at the specified key. + /// + /// - Parameters: + /// - value: The data value to be stored. + /// - key: The key under which to store the value. + /// - Throws: Throws an error if the data is invalid or if a transformation error occurs. + func set(_ value: Data, key: String) throws + + /// Stores a Boolean value at the specified key. + /// + /// - Parameters: + /// - value: The Boolean value to be stored. + /// - key: The key under which to store the value. + /// - Throws: Throws an error if the data is invalid or if a transformation error occurs. + func set(_ value: Bool, key: String) throws + + /// Removes the value associated with the specified key. + /// + /// - Parameter key: The key for which to remove the value. + /// - Throws: Throws an error if the operation is unsuccessful. + func removeValue(forKey key: String) throws + + /// Removes all values from the storage. + /// + /// - Throws: Throws an error if any value fails to be removed from the storage. + func removeAll() throws +} diff --git a/KeychainStorage/Sources/KeychainStorage/KeychainQueryFactory.swift b/KeychainStorage/Sources/KeychainStorage/KeychainQueryFactory.swift new file mode 100644 index 0000000..28e3ec3 --- /dev/null +++ b/KeychainStorage/Sources/KeychainStorage/KeychainQueryFactory.swift @@ -0,0 +1,113 @@ +import Foundation +import Security + +// MARK: - KeychainBasicQueryConfiguration + +/// A structure that defines a basic configuration for querying Keychain items. +struct KeychainBasicQueryConfiguration { + + /// The item class value, represented by `kSecClass`. + /// This can be one of the following: + /// - `kSecClassGenericPassword`: Generic password item. + /// - `kSecClassInternetPassword`: Internet password item. + /// - `kSecClassCertificate`: Certificate item. + /// - `kSecClassKey`: Cryptographic key item. + /// - `kSecClassIdentity`: Identity item. + let secClass: String + + /// The matching limit for a Keychain query. + /// This can be either: + /// - `kSecMatchLimitAll`: Allows an unlimited number of matched items. + /// - `kSecMatchLimitOne`: Only matches a single item. + let matchLimit: String + + /// Indicates whether the associated data should be returned. + let returnData: Bool + + /// Indicates whether the attributes should be returned. + let returnAttributes: Bool + + /// Initializes a new configuration with the specified parameters. + /// + /// - Parameters: + /// - secClass: The item class value. Defaults to `kSecClassGenericPassword`. + /// - matchLimit: The match limit for the query. Defaults to `kSecMatchLimitOne`. + /// - returnData: A flag indicating whether to return data. Defaults to `true`. + /// - returnAttributes: A flag indicating whether to return attributes. Defaults to `true`. + init( + secClass: String = kSecClassGenericPassword as String, + matchLimit: String = kSecMatchLimitOne as String, + returnData: Bool = true, + returnAttributes: Bool = true + ) { + self.secClass = secClass + self.matchLimit = matchLimit + self.returnData = returnData + self.returnAttributes = returnAttributes + } +} + +// MARK: - KeychainBasicQueryFactory + +/// A typealias representing a dictionary for Keychain queries. +typealias KeychainQuery = [String: Any] + +/// A factory for creating Keychain queries. +enum KeychainBasicQueryFactory { + + /// Creates a Keychain query based on the provided service, account key, value, and configuration. + /// + /// - Parameters: + /// - service: The Keychain item's service. + /// - key: The item's account name. Can be `nil`. + /// - value: The item's value. Can be `nil`. + /// - configuration: The configuration settings for the Keychain query. Defaults to a new instance of `KeychainBasicQueryConfiguration`. + /// - Returns: A dictionary representing the Keychain query. + static func makeQuery( + forService service: String, + key: String? = nil, + value: Data? = nil, + configuration: KeychainBasicQueryConfiguration = KeychainBasicQueryConfiguration() + ) -> KeychainQuery { + var queryDictionary: [String: Any] = [:] + queryDictionary[kSecAttrService as String] = service + queryDictionary[kSecClass as String] = configuration.secClass + + if let key = key { + queryDictionary[kSecAttrAccount as String] = key + } + + if let value = value { + queryDictionary[kSecValueData as String] = value + } else { + queryDictionary[kSecMatchLimit as String] = configuration.matchLimit + queryDictionary[kSecReturnData as String] = configuration.returnData + queryDictionary[kSecReturnAttributes as String] = configuration.returnAttributes + } + + return queryDictionary + } + + /// Creates a query for deleting Keychain items based on the provided service, account key, and configuration. + /// + /// - Parameters: + /// - service: The Keychain item's service. + /// - key: The item's account name. Can be `nil`. + /// - configuration: The configuration settings for the Keychain query. Defaults to a new instance of `KeychainBasicQueryConfiguration`. + /// - Returns: A dictionary representing the Keychain delete query. + static func makeDeleteQuery( + forService service: String, + key: String? = nil, + configuration: KeychainBasicQueryConfiguration = KeychainBasicQueryConfiguration() + ) -> KeychainQuery { + var queryDictionary: [String: Any] = [:] + queryDictionary[kSecAttrService as String] = service + queryDictionary[kSecClass as String] = configuration.secClass + + if let key = key { + queryDictionary[kSecAttrAccount as String] = key + } + + return queryDictionary + } +} diff --git a/KeychainStorage/KeychainStorage.swift b/KeychainStorage/Sources/KeychainStorage/KeychainStorage.swift similarity index 56% rename from KeychainStorage/KeychainStorage.swift rename to KeychainStorage/Sources/KeychainStorage/KeychainStorage.swift index faada3c..63bb0e0 100644 --- a/KeychainStorage/KeychainStorage.swift +++ b/KeychainStorage/Sources/KeychainStorage/KeychainStorage.swift @@ -1,20 +1,12 @@ -// -// KeychainStorage.swift -// KeychainStorage -// -// Created by Dan, Radu-Ionut (RO - Bucharest) on 25/05/2019. -// Copyright © 2019 radude89. All rights reserved. -// - import Foundation import Security // MARK: - KeychainStorageError -/// Defines the keychain errors. +/// An enumeration representing errors that can occur while accessing the Keychain. /// -/// - unhandledError: Thrown when a keychain operation failed with a given `OSStatus`. -/// - invalidData: Thrown when the data expected was with an invalid format. +/// - unhandledError: Thrown when a Keychain operation fails with a specific `OSStatus`. +/// - invalidData: Thrown when the data received is in an invalid format. public enum KeychainStorageError: Error { case unhandledError(OSStatus) case invalidData @@ -22,14 +14,14 @@ public enum KeychainStorageError: Error { // MARK: - KeychainStorage -/// This class is a wrapper to the Keychain, defined by a service. -/// All Keychain items are considered generic passwords `kSecClassGenericPassword`. +/// A class that acts as a wrapper for Keychain operations, associated with a specific service. +/// All Keychain items are treated as generic passwords, represented by `kSecClassGenericPassword`. public class KeychainStorage { - /// Defines the service which all Keychain queries will use. + /// The service that will be used for all Keychain queries. private let service: String - /// Base class initializer, where the service variable is set. + /// Initializes a new instance of `KeychainStorage` with the specified service. /// /// - Parameter service: The service that will be used for all Keychain queries. public init(service: String) { @@ -41,19 +33,18 @@ public class KeychainStorage { extension KeychainStorage: KeyValueStorage { - /// Sets a bool value in the Keychain. + /// Stores a Boolean value in the Keychain. /// /// ### Usage Example: ### - /// - /// ```` + /// ```swift /// let storage = KeychainStorage(service: "com.foo") /// try storage.set(true, key: "myKey") - /// ```` + /// ``` /// /// - Parameters: - /// - value: The value to be set in the Keychain. - /// - key: The key we want to put the value. - /// - Throws: Can throw an `unhandledError` with a status. + /// - value: The Boolean value to be stored in the Keychain. + /// - key: The key under which the value will be stored. + /// - Throws: Throws `KeychainStorageError.unhandledError` if the operation fails. public func set(_ value: Bool, key: String) throws { let bytes: [UInt8] = value ? [1] : [0] let data = Data(bytes) @@ -61,24 +52,23 @@ extension KeychainStorage: KeyValueStorage { try set(data, key: key) } - /// Sets a data value in the Keychain. + /// Stores a Data value in the Keychain. /// /// ### Usage Example: ### - /// - /// ```` + /// ```swift /// let data = Data(base64Encoded: "encoded")! /// let storage = KeychainStorage(service: "com.foo") /// try storage.set(data, key: "myKey") - /// ```` + /// ``` /// /// - Parameters: - /// - value: The value to be set in the Keychain. - /// - key: The key we want to put the value. - /// - Throws: Can throw an `unhandledError` with a status. + /// - value: The Data value to be stored in the Keychain. + /// - key: The key under which the value will be stored. + /// - Throws: Throws `KeychainStorageError.unhandledError` if the operation fails. public func set(_ value: Data, key: String) throws { let query = KeychainBasicQueryFactory.makeQuery(forService: service, key: key, value: value) - // Delete anything that's already there, just in case + // Remove any existing item at the specified key to avoid duplication SecItemDelete(query as CFDictionary) let status = SecItemAdd(query as CFDictionary, nil) @@ -88,19 +78,18 @@ extension KeychainStorage: KeyValueStorage { } } - /// Sets a string value in the Keychain. + /// Stores a String value in the Keychain. /// /// ### Usage Example: ### - /// - /// ```` + /// ```swift /// let storage = KeychainStorage(service: "com.foo") /// try storage.set("Super secret value", key: "myKey") - /// ```` + /// ``` /// /// - Parameters: - /// - value: The value to be set in the Keychain. - /// - key: The key we want to put the value. - /// - Throws: Can throw an `invalidData` storage error or an `unhandledError` with a status. + /// - value: The String value to be stored in the Keychain. + /// - key: The key under which the value will be stored. + /// - Throws: Throws `KeychainStorageError.invalidData` if the value cannot be converted to Data or `KeychainStorageError.unhandledError` if the operation fails. public func set(_ value: String, key: String) throws { guard let data = value.data(using: .utf8) else { throw KeychainStorageError.invalidData @@ -109,20 +98,19 @@ extension KeychainStorage: KeyValueStorage { try set(data, key: key) } - /// Returns the string value of the given key. + /// Retrieves the String value associated with the specified key. /// /// ### Usage Example: ### - /// - /// ```` + /// ```swift /// let storage = KeychainStorage(service: "com.foo") /// if let myValue = try? storage.string(forKey: "myKey") { - /// // do something with `myValue` + /// // Use `myValue` /// } - /// ```` + /// ``` /// - /// - Parameter key: The key we want to search the value. - /// - Returns: The value of the given key. - /// - Throws: Can throw errors, for example if data is invalid or if there was a transformation error. + /// - Parameter key: The key for which to retrieve the value. + /// - Returns: The String value associated with the key, or `nil` if not found. + /// - Throws: Throws `KeychainStorageError.invalidData` if the data is invalid or cannot be converted. public func string(forKey key: String) throws -> String? { guard let data = try data(forKey: key) else { return nil @@ -135,20 +123,19 @@ extension KeychainStorage: KeyValueStorage { return value } - /// Returns the data value of the given key. + /// Retrieves the Data value associated with the specified key. /// /// ### Usage Example: ### - /// - /// ```` + /// ```swift /// let storage = KeychainStorage(service: "com.foo") - /// if let myValue = try? data(forKey: "myKey") { - /// // do something with `myValue` + /// if let myValue = try? storage.data(forKey: "myKey") { + /// // Use `myValue` /// } - /// ```` + /// ``` /// - /// - Parameter key: The key we want to search the value. - /// - Returns: The value of the given key. - /// - Throws: Can throw an `unhandledError` with a status. + /// - Parameter key: The key for which to retrieve the value. + /// - Returns: The Data value associated with the key, or `nil` if not found. + /// - Throws: Throws `KeychainStorageError.unhandledError` if the operation fails. public func data(forKey key: String) throws -> Data? { let query = KeychainBasicQueryFactory.makeQuery(forService: service, key: key) var result: AnyObject? @@ -163,27 +150,26 @@ extension KeychainStorage: KeyValueStorage { } if let resultDictionary = result as? [String: Any], - let data = resultDictionary[kSecValueData as String] as? Data { + let data = resultDictionary[kSecValueData as String] as? Data { return data } return nil } - /// Returns the bool value of the given key. + /// Retrieves the Boolean value associated with the specified key. /// /// ### Usage Example: ### - /// - /// ```` + /// ```swift /// let storage = KeychainStorage(service: "com.foo") - /// if let myValue = try? bool(forKey: "myKey") { - /// // do something with `myValue` + /// if let myValue = try? storage.bool(forKey: "myKey") { + /// // Use `myValue` /// } - /// ```` + /// ``` /// - /// - Parameter key: The key we want to search the value. - /// - Returns: The value of the given key. - /// - Throws: Can throw an `unhandledError` with a status. + /// - Parameter key: The key for which to retrieve the value. + /// - Returns: The Boolean value associated with the key, or `nil` if not found. + /// - Throws: Throws `KeychainStorageError.unhandledError` if the operation fails. public func bool(forKey key: String) throws -> Bool? { guard let data = try data(forKey: key) else { return nil @@ -196,10 +182,10 @@ extension KeychainStorage: KeyValueStorage { return nil } - /// Removes the value at a given key. + /// Removes the value associated with the specified key from the Keychain. /// - /// - Parameter key: The key we want to remove the value. - /// - Throws: Can throw errors if the operation was unsuccessful. + /// - Parameter key: The key for which to remove the value. + /// - Throws: Throws `KeychainStorageError.unhandledError` if the operation fails. public func removeValue(forKey key: String) throws { let query = KeychainBasicQueryFactory.makeDeleteQuery(forService: service, key: key) @@ -210,9 +196,9 @@ extension KeychainStorage: KeyValueStorage { } } - /// Removes all values from the storage. + /// Removes all values associated with the service from the Keychain. /// - /// - Throws: Can throw errors if a value failed to be removed from the storage. + /// - Throws: Throws `KeychainStorageError.unhandledError` if the operation fails. public func removeAll() throws { let query = KeychainBasicQueryFactory.makeDeleteQuery(forService: service) diff --git a/KeychainStorageTests/KeychainQueryFactoryTests.swift b/KeychainStorage/Tests/KeychainStorageTests/KeychainQueryFactoryTests.swift similarity index 93% rename from KeychainStorageTests/KeychainQueryFactoryTests.swift rename to KeychainStorage/Tests/KeychainStorageTests/KeychainQueryFactoryTests.swift index 187a08a..7a38af2 100644 --- a/KeychainStorageTests/KeychainQueryFactoryTests.swift +++ b/KeychainStorage/Tests/KeychainStorageTests/KeychainQueryFactoryTests.swift @@ -1,11 +1,3 @@ -// -// KeychainQueryFactoryTests.swift -// KeychainStorageTests -// -// Created by Dan, Radu-Ionut (RO - Bucharest) on 26/05/2019. -// Copyright © 2019 radude89. All rights reserved. -// - import XCTest @testable import KeychainStorage diff --git a/KeychainStorageTests/KeychainStorageTests.swift b/KeychainStorage/Tests/KeychainStorageTests/KeychainStorageTests.swift similarity index 94% rename from KeychainStorageTests/KeychainStorageTests.swift rename to KeychainStorage/Tests/KeychainStorageTests/KeychainStorageTests.swift index 79de3ee..abfe583 100644 --- a/KeychainStorageTests/KeychainStorageTests.swift +++ b/KeychainStorage/Tests/KeychainStorageTests/KeychainStorageTests.swift @@ -1,17 +1,9 @@ -// -// KeychainStorageTests.swift -// KeychainStorageTests -// -// Created by Dan, Radu-Ionut (RO - Bucharest) on 26/05/2019. -// Copyright © 2019 radude89. All rights reserved. -// - import XCTest @testable import KeychainStorage final class KeychainStorageTests: XCTestCase { - var sut: KeychainStorage! + private var sut: KeychainStorage! private let service = "com.test.service" private let key = "test.key" @@ -134,5 +126,5 @@ final class KeychainStorageTests: XCTestCase { XCTFail("Thrown error \(error)") } } - + } diff --git a/KeychainStorageHost/AppDelegate.swift b/KeychainStorageHost/AppDelegate.swift deleted file mode 100644 index f21a037..0000000 --- a/KeychainStorageHost/AppDelegate.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// AppDelegate.swift -// KeychainStorageHost -// -// Created by Dan, Radu-Ionut (RO - Bucharest) on 26/05/2019. -// Copyright © 2019 radude89. All rights reserved. -// - -import UIKit - -@UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - // Override point for customization after application launch. - return true - } - - func applicationWillResignActive(_ application: UIApplication) { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. - } - - func applicationDidEnterBackground(_ application: UIApplication) { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. - } - - func applicationWillEnterForeground(_ application: UIApplication) { - // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. - } - - func applicationDidBecomeActive(_ application: UIApplication) { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. - } - - func applicationWillTerminate(_ application: UIApplication) { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. - } - - -} - diff --git a/KeychainStorageHost/Info.plist b/KeychainStorageHost/Info.plist deleted file mode 100644 index 9a1a6cb..0000000 --- a/KeychainStorageHost/Info.plist +++ /dev/null @@ -1,41 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/KeychainStorageHostApp/AppDelegate.swift b/KeychainStorageHostApp/AppDelegate.swift deleted file mode 100644 index 773621d..0000000 --- a/KeychainStorageHostApp/AppDelegate.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// AppDelegate.swift -// KeychainStorageHostApp -// -// Created by Dan, Radu-Ionut (RO - Bucharest) on 10/07/2019. -// - -import UIKit - -@UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - // Override point for customization after application launch. - return true - } - -} diff --git a/KeychainStorageHostApp/Info.plist b/KeychainStorageHostApp/Info.plist deleted file mode 100644 index e1ab737..0000000 --- a/KeychainStorageHostApp/Info.plist +++ /dev/null @@ -1,37 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/KeychainStorageTests/Info.plist b/KeychainStorageTests/Info.plist deleted file mode 100644 index 6c40a6c..0000000 --- a/KeychainStorageTests/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/Package.swift b/Package.swift deleted file mode 100644 index fe3b85c..0000000 --- a/Package.swift +++ /dev/null @@ -1,30 +0,0 @@ -// swift-tools-version:5.0 -// The swift-tools-version declares the minimum version of Swift required to build this package. - -import PackageDescription - -let package = Package( - name: "KeychainStorage", - products: [ - // Products define the executables and libraries produced by a package, and make them visible to other packages. - .library( - name: "KeychainStorage", - targets: ["KeychainStorage"]), - ], - dependencies: [ - // Dependencies declare other packages that this package depends on. - // .package(url: /* package url */, from: "1.0.0"), - ], - targets: [ - // Targets are the basic building blocks of a package. A target can define a module or a test suite. - // Targets can depend on other targets in this package, and on products in packages which this package depends on. - .target( - name: "KeychainStorage", - dependencies: [], - path: "KeychainStorage"), - .testTarget( - name: "KeychainStorageTests", - dependencies: ["KeychainStorage"], - path: "KeychainStorageTests"), - ] -) diff --git a/README.md b/README.md index 17a6817..976c314 100644 --- a/README.md +++ b/README.md @@ -2,85 +2,59 @@ Keychain Storage

- build - - + + Swift Package Manager - - Carthage - - - Carthage - - iOS - - Twitter: @radude89 - +

-Keychain Storage is a simple Keychain wrapper written in Swift.
-If you ever wanted to save something in Keychain without writing too much code, you are in the right place.
+ +Keychain Storage is a simple Keychain wrapper written in Swift. If you’ve ever wanted to save something in the Keychain without writing excessive code, you’ve come to the right place! ## Requirements -- iOS 12.0+ -- Xcode 10.2+ -- Swift 5+ +- iOS 18.0+ +- Xcode 16.0+ +- Swift 6+ ## Installation -### Cocoa Pods - -[CocoaPods](https://cocoapods.org) is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate Keychain Storage into your Xcode project using CocoaPods, specify it in your `Podfile`: - -```ruby -pod 'KeychainStorage', '~> 1.3.0' -``` - -### Carthage - -[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate KeychainStorage into your Xcode project using Carthage, specify it in your `Cartfile`: - -```ogdl -github "radude89/KeychainStorage" "1.3.0" -``` - ### Swift Package Manager -The [Swift Package Manager](https://swift.org/package-manager/) is a tool for automating the distribution of Swift code and is integrated into the `swift` compiler. +The [Swift Package Manager](https://swift.org/package-manager/) is a tool for automating the distribution of Swift code, integrated into the `swift` compiler. -Once you have your Swift package set up, you can add KeychainStorage as a dependency by adding it to the `dependencies` array of your `Package.swift`. +To add KeychainStorage as a dependency, include it in the `dependencies` array of your `Package.swift` file: ```swift dependencies: [ - .package(url: "https://github.com/radude89/KeychainStorage.git", from: "1.0.0") + .package(url: "https://github.com/radude89/KeychainStorage.git", from: "2.0.0") ] ``` -### Manual +## Manual Installation + +For manual installation, simply drag and drop the following files into your project from the `KeychainStorage` directory: -Just drag and drop into your project the following projects found in `KeychainStorage`: - `KeychainQueryFactory.swift` - `KeychainStorage.swift` - `KeyValueStorage.swift` ## Examples -Make sure you try out the small app, the example project found at: `Example/KeychainStorageExample.xcworkspace`.
Build & run. +Make sure to explore the small app included in the example project found at `Example/KeychainStorageExample.xcworkspace`. Build and run the project to see it in action. -### Saving a value in Keychain +### Saving a Value in the Keychain ```swift import KeychainStorage let storage = KeychainStorage(service: "com.test.service") try? storage.set("secret", key: "myStringKey") - try? storage.set(true, key: "myBoolKey") ``` -### Retrieving a value from Keychain +### Retrieving a Value from the Keychain ```swift import KeychainStorage @@ -88,15 +62,15 @@ import KeychainStorage let storage = KeychainStorage(service: "com.test.service") if let myStringValue = try? storage.string(forKey: "myStringKey") { - // do something with myStringValue + // Do something with myStringValue } if let myBoolValue = try? storage.bool(forKey: "myBoolKey") { - // do something with myBoolValue + // Do something with myBoolValue } ``` -### Deleting a value from Keychain +### Deleting a Value from the Keychain ```swift import KeychainStorage @@ -105,7 +79,7 @@ let storage = KeychainStorage(service: "com.test.service") try? storage.removeValue(forKey: "myStringKey") ``` -### Deleting all values from Keychain +### Deleting All Values from the Keychain ```swift import KeychainStorage @@ -113,6 +87,7 @@ import KeychainStorage let storage = KeychainStorage(service: "com.test.service") try? storage.removeAll() ``` + ## License KeychainStorage is released under the MIT license. [See LICENSE](https://github.com/radude89/KeychainStorage/blob/master/LICENSE) for details.