├── .github
└── workflows
│ └── test.yml
├── .gitignore
├── .swiftpm
└── xcode
│ └── package.xcworkspace
│ └── contents.xcworkspacedata
├── Examples
└── Example-iOS
│ ├── Example-iOS.xcodeproj
│ ├── project.pbxproj
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Example-iOS.xcscheme
│ └── Example-iOS
│ ├── AccountsViewController.swift
│ ├── AppDelegate.swift
│ ├── Base.lproj
│ ├── LaunchScreen.xib
│ └── Main.storyboard
│ ├── Example-iOS.entitlements
│ ├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ └── InputViewController.swift
├── KeychainAccess.podspec
├── KeychainAccess.xcworkspace
├── contents.xcworkspacedata
└── xcshareddata
│ └── IDEWorkspaceChecks.plist
├── LICENSE
├── Lib
├── Configurations
│ ├── Base.xcconfig
│ ├── Debug.xcconfig
│ ├── KeychainAccess.xcconfig
│ ├── Release.xcconfig
│ ├── TestHost.xcconfig
│ └── Tests.xcconfig
├── KeychainAccess.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── KeychainAccess.xcscheme
│ │ └── TestHost.xcscheme
├── KeychainAccess
│ ├── Info.plist
│ ├── Keychain.swift
│ └── KeychainAccess.h
├── KeychainAccessTests
│ ├── EnumTests.swift
│ ├── ErrorTypeTests.swift
│ ├── Info.plist
│ ├── KeychainAccessTests.swift
│ └── SharedCredentialTests.swift
├── TestHost-MacCatalyst
│ ├── KeychainAccessTests-MacCatalyst
│ │ ├── EnumTests.swift
│ │ ├── ErrorTypeTests.swift
│ │ ├── Info.plist
│ │ └── KeychainAccessTests.swift
│ ├── TestHost-MacCatalyst.xcodeproj
│ │ ├── project.pbxproj
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── TestHost-MacCatalyst.xcscheme
│ └── TestHost-MacCatalyst
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ ├── SceneDelegate.swift
│ │ ├── TestHost-MacCatalyst.entitlements
│ │ └── ViewController.swift
└── TestHost
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ └── TestHost.entitlements
├── Package.swift
├── Package@swift-5.3.swift
├── README.md
└── Sources
└── Keychain.swift
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 | on:
3 | pull_request:
4 | branches: [master]
5 | push:
6 | branches: [master]
7 | workflow_dispatch:
8 |
9 | jobs:
10 | test:
11 | name: ${{ matrix.command }} on ${{ matrix.platform }} (xcode ${{ matrix.xcode }}, ${{ matrix.macos }})
12 | runs-on: ${{ matrix.macos }}
13 | strategy:
14 | fail-fast: false
15 | matrix:
16 | macos: ["macos-11", "macos-12", "macos-13"]
17 | xcode: ["11.7", "12.5.1", "13.2.1", "14.2", "14.3.1", "15.0.1"]
18 | platform: ["ios"]
19 | command: ["test"]
20 | exclude:
21 | - macos: "macos-11"
22 | xcode: "14.2"
23 | - macos: "macos-11"
24 | xcode: "14.3.1"
25 | - macos: "macos-11"
26 | xcode: "15.0.1"
27 | - macos: "macos-12"
28 | xcode: "11.7"
29 | - macos: "macos-12"
30 | xcode: "12.5.1"
31 | - macos: "macos-12"
32 | xcode: "13.2.1"
33 | - macos: "macos-12"
34 | xcode: "14.3.1"
35 | - macos: "macos-12"
36 | xcode: "15.0.1"
37 | - macos: "macos-13"
38 | xcode: "11.7"
39 | - macos: "macos-13"
40 | xcode: "12.5.1"
41 | - macos: "macos-13"
42 | xcode: "13.2.1"
43 | - macos: "macos-13"
44 | xcode: "14.2"
45 | steps:
46 | - uses: actions/checkout@v4
47 | - uses: maxim-lobanov/setup-xcode@v1.2.3
48 | with:
49 | xcode-version: ${{ matrix.xcode }}
50 | - name: Install the Apple certificate and provisioning profile
51 | env:
52 | BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
53 | P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
54 | BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
55 | KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
56 | run: |
57 | # create variables
58 | CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
59 | PP_PATH=$RUNNER_TEMP/build_pp.provisionprofile
60 | KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
61 |
62 | # import certificate and provisioning profile from secrets
63 | echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
64 | echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
65 |
66 | # create temporary keychain
67 | security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
68 | security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
69 | security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
70 |
71 | # import certificate to keychain
72 | security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
73 | security list-keychain -d user -s $KEYCHAIN_PATH
74 |
75 | # apply provisioning profile
76 | mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
77 | cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
78 | - name: Test
79 | if: ${{ matrix.xcode=='11.7' && matrix.platform=='ios' }}
80 | run: |
81 | set -ex
82 | xcodebuild test -workspace KeychainAccess.xcworkspace -scheme KeychainAccess -destination 'platform=iOS Simulator,OS=13.7,name=iPhone 11 Pro' -only-testing:KeychainAccessTests -resultBundlePath TestResults.xcresult
83 | - name: Test
84 | if: ${{ matrix.xcode=='12.5.1' && matrix.platform=='ios' }}
85 | run: |
86 | set -ex
87 | xcodebuild test -workspace KeychainAccess.xcworkspace -scheme KeychainAccess -destination 'platform=iOS Simulator,OS=14.5,name=iPhone 12 Pro' -only-testing:KeychainAccessTests -resultBundlePath TestResults.xcresult
88 | - name: Test
89 | if: ${{ matrix.xcode=='13.2.1' && matrix.platform=='ios' }}
90 | run: |
91 | set -ex
92 | xcodebuild test -workspace KeychainAccess.xcworkspace -scheme KeychainAccess -destination 'platform=iOS Simulator,OS=15.2,name=iPhone 13 Pro' -only-testing:KeychainAccessTests -resultBundlePath TestResults.xcresult
93 | - name: Test
94 | if: ${{ matrix.xcode=='14.2' && matrix.platform=='ios' }}
95 | run: |
96 | set -ex
97 | xcodebuild test -workspace KeychainAccess.xcworkspace -scheme KeychainAccess -destination 'platform=iOS Simulator,OS=16.2,name=iPhone 14 Pro' -only-testing:KeychainAccessTests -resultBundlePath TestResults.xcresult
98 | - name: Test
99 | if: ${{ matrix.xcode=='14.3.1' && matrix.platform=='ios' }}
100 | run: |
101 | set -ex
102 | xcodebuild test -workspace KeychainAccess.xcworkspace -scheme KeychainAccess -destination 'platform=iOS Simulator,OS=16.4,name=iPhone 14 Pro' -only-testing:KeychainAccessTests -resultBundlePath TestResults1.xcresult
103 | xcodebuild test -workspace KeychainAccess.xcworkspace -scheme KeychainAccess -destination 'platform=iOS Simulator,OS=17.0.1,name=iPhone 14 Pro' -only-testing:KeychainAccessTests -resultBundlePath TestResults2.xcresult
104 | xcrun xcresulttool merge TestResults1.xcresult TestResults2.xcresult --output-path TestResults.xcresult
105 | - name: Test
106 | if: ${{ matrix.xcode=='15.0.1' && matrix.platform=='ios' }}
107 | run: |
108 | set -ex
109 | xcodebuild test -workspace KeychainAccess.xcworkspace -scheme KeychainAccess -destination 'platform=iOS Simulator,OS=17.0.1,name=iPhone 15 Pro' -only-testing:KeychainAccessTests -resultBundlePath TestResults.xcresult
110 | - uses: kishikawakatsumi/xcresulttool@v1
111 | with:
112 | path: TestResults.xcresult
113 | title: "KeychainAccess test report"
114 | if: always()
115 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### https://raw.github.com/github/gitignore/2a4de265d37eca626309d8e115218d18985b5435/Swift.gitignore
2 |
3 | # Xcode
4 | #
5 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
6 |
7 | ## User settings
8 | xcuserdata/
9 |
10 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
11 | *.xcscmblueprint
12 | *.xccheckout
13 |
14 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
15 | build/
16 | DerivedData/
17 | *.moved-aside
18 | *.pbxuser
19 | !default.pbxuser
20 | *.mode1v3
21 | !default.mode1v3
22 | *.mode2v3
23 | !default.mode2v3
24 | *.perspectivev3
25 | !default.perspectivev3
26 |
27 | ## Obj-C/Swift specific
28 | *.hmap
29 |
30 | ## App packaging
31 | *.ipa
32 | *.dSYM.zip
33 | *.dSYM
34 |
35 | ## Playgrounds
36 | timeline.xctimeline
37 | playground.xcworkspace
38 |
39 | # Swift Package Manager
40 | #
41 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
42 | # Packages/
43 | # Package.pins
44 | # Package.resolved
45 | # *.xcodeproj
46 | #
47 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
48 | # hence it is not needed unless you have added a package configuration file to your project
49 | # .swiftpm
50 |
51 | .build/
52 |
53 | # CocoaPods
54 | #
55 | # We recommend against adding the Pods directory to your .gitignore. However
56 | # you should judge for yourself, the pros and cons are mentioned at:
57 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
58 | #
59 | # Pods/
60 | #
61 | # Add this line if you want to avoid checking in source code from the Xcode workspace
62 | # *.xcworkspace
63 |
64 | # Carthage
65 | #
66 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
67 | # Carthage/Checkouts
68 |
69 | Carthage/Build/
70 |
71 | # Accio dependency management
72 | Dependencies/
73 | .accio/
74 |
75 | # fastlane
76 | #
77 | # It is recommended to not store the screenshots in the git repo.
78 | # Instead, use fastlane to re-generate the screenshots whenever they are needed.
79 | # For more information about the recommended setup visit:
80 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
81 |
82 | fastlane/report.xml
83 | fastlane/Preview.html
84 | fastlane/screenshots/**/*.png
85 | fastlane/test_output
86 |
87 | # Code Injection
88 | #
89 | # After new code Injection tools there's a generated folder /iOSInjectionProject
90 | # https://github.com/johnno1962/injectionforxcode
91 |
92 | iOSInjectionProject/
93 |
94 |
95 | ### https://raw.github.com/github/gitignore/2a4de265d37eca626309d8e115218d18985b5435/Global/macOS.gitignore
96 |
97 | # General
98 | .DS_Store
99 | .AppleDouble
100 | .LSOverride
101 |
102 | # Icon must end with two \r
103 | Icon
104 |
105 | # Thumbnails
106 | ._*
107 |
108 | # Files that might appear in the root of a volume
109 | .DocumentRevisions-V100
110 | .fseventsd
111 | .Spotlight-V100
112 | .TemporaryItems
113 | .Trashes
114 | .VolumeIcon.icns
115 | .com.apple.timemachine.donotpresent
116 |
117 | # Directories potentially created on remote AFP share
118 | .AppleDB
119 | .AppleDesktop
120 | Network Trash Folder
121 | Temporary Items
122 | .apdisk
123 |
124 |
125 | ### https://raw.github.com/github/gitignore/2a4de265d37eca626309d8e115218d18985b5435/Ruby.gitignore
126 |
127 | *.gem
128 | *.rbc
129 | /.config
130 | /coverage/
131 | /InstalledFiles
132 | /pkg/
133 | /spec/reports/
134 | /spec/examples.txt
135 | /test/tmp/
136 | /test/version_tmp/
137 | /tmp/
138 |
139 | # Used by dotenv library to load environment variables.
140 | # .env
141 |
142 | # Ignore Byebug command history file.
143 | .byebug_history
144 |
145 | ## Specific to RubyMotion:
146 | .dat*
147 | .repl_history
148 | build/
149 | *.bridgesupport
150 | build-iPhoneOS/
151 | build-iPhoneSimulator/
152 |
153 | ## Specific to RubyMotion (use of CocoaPods):
154 | #
155 | # We recommend against adding the Pods directory to your .gitignore. However
156 | # you should judge for yourself, the pros and cons are mentioned at:
157 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
158 | #
159 | # vendor/Pods/
160 |
161 | ## Documentation cache and generated files:
162 | /.yardoc/
163 | /_yardoc/
164 | /doc/
165 | /rdoc/
166 |
167 | ## Environment normalization:
168 | /.bundle/
169 | /vendor/bundle
170 | /lib/bundler/man/
171 |
172 | # for a library or gem, you might want to ignore these files since the code is
173 | # intended to run in multiple environments; otherwise, check them in:
174 | # Gemfile.lock
175 | # .ruby-version
176 | # .ruby-gemset
177 |
178 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
179 | .rvmrc
180 |
181 | # Used by RuboCop. Remote config files pulled in from inherit_from directive.
182 | # .rubocop-https?--*
183 |
184 |
185 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/Example-iOS.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 14DAEE961A51E1BE0070B77E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14DAEE951A51E1BE0070B77E /* AppDelegate.swift */; };
11 | 14DAEE9B1A51E1BE0070B77E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 14DAEE991A51E1BE0070B77E /* Main.storyboard */; };
12 | 14DAEE9D1A51E1BE0070B77E /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 14DAEE9C1A51E1BE0070B77E /* Images.xcassets */; };
13 | 14DAEEA01A51E1BE0070B77E /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 14DAEE9E1A51E1BE0070B77E /* LaunchScreen.xib */; };
14 | 14DAEEB71A51E2690070B77E /* AccountsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14DAEEB51A51E2690070B77E /* AccountsViewController.swift */; };
15 | 14DAEEB81A51E2690070B77E /* InputViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14DAEEB61A51E2690070B77E /* InputViewController.swift */; };
16 | 14DAEEC91A51E2D00070B77E /* KeychainAccess.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 14DAEEC11A51E2A60070B77E /* KeychainAccess.framework */; };
17 | 14DAEECB1A51E2E10070B77E /* KeychainAccess.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 14DAEEC11A51E2A60070B77E /* KeychainAccess.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
18 | /* End PBXBuildFile section */
19 |
20 | /* Begin PBXContainerItemProxy section */
21 | 1470425D1D6FFA97005A4C6E /* PBXContainerItemProxy */ = {
22 | isa = PBXContainerItemProxy;
23 | containerPortal = 14DAEEB91A51E2A60070B77E /* KeychainAccess.xcodeproj */;
24 | proxyType = 2;
25 | remoteGlobalIDString = 14A630151D3293C700809B3F;
26 | remoteInfo = TestHost;
27 | };
28 | 14DAEEC01A51E2A60070B77E /* PBXContainerItemProxy */ = {
29 | isa = PBXContainerItemProxy;
30 | containerPortal = 14DAEEB91A51E2A60070B77E /* KeychainAccess.xcodeproj */;
31 | proxyType = 2;
32 | remoteGlobalIDString = 140F195C1A49D79400B0016A;
33 | remoteInfo = "KeychainAccess-iOS";
34 | };
35 | 14DAEEC21A51E2A60070B77E /* PBXContainerItemProxy */ = {
36 | isa = PBXContainerItemProxy;
37 | containerPortal = 14DAEEB91A51E2A60070B77E /* KeychainAccess.xcodeproj */;
38 | proxyType = 2;
39 | remoteGlobalIDString = 140F19671A49D79500B0016A;
40 | remoteInfo = "KeychainAccess-iOSTests";
41 | };
42 | /* End PBXContainerItemProxy section */
43 |
44 | /* Begin PBXCopyFilesBuildPhase section */
45 | 14DAEECA1A51E2D70070B77E /* CopyFiles */ = {
46 | isa = PBXCopyFilesBuildPhase;
47 | buildActionMask = 2147483647;
48 | dstPath = "";
49 | dstSubfolderSpec = 10;
50 | files = (
51 | 14DAEECB1A51E2E10070B77E /* KeychainAccess.framework in CopyFiles */,
52 | );
53 | runOnlyForDeploymentPostprocessing = 0;
54 | };
55 | /* End PBXCopyFilesBuildPhase section */
56 |
57 | /* Begin PBXFileReference section */
58 | 145652E11D898BB9006E8D0E /* Example-iOS.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = "Example-iOS.entitlements"; sourceTree = ""; };
59 | 14DAEE901A51E1BE0070B77E /* Example-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
60 | 14DAEE941A51E1BE0070B77E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
61 | 14DAEE951A51E1BE0070B77E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
62 | 14DAEE9A1A51E1BE0070B77E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
63 | 14DAEE9C1A51E1BE0070B77E /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
64 | 14DAEE9F1A51E1BE0070B77E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
65 | 14DAEEB51A51E2690070B77E /* AccountsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountsViewController.swift; sourceTree = ""; };
66 | 14DAEEB61A51E2690070B77E /* InputViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputViewController.swift; sourceTree = ""; };
67 | 14DAEEB91A51E2A60070B77E /* KeychainAccess.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = KeychainAccess.xcodeproj; path = ../../Lib/KeychainAccess.xcodeproj; sourceTree = ""; };
68 | /* End PBXFileReference section */
69 |
70 | /* Begin PBXFrameworksBuildPhase section */
71 | 14DAEE8D1A51E1BE0070B77E /* Frameworks */ = {
72 | isa = PBXFrameworksBuildPhase;
73 | buildActionMask = 2147483647;
74 | files = (
75 | 14DAEEC91A51E2D00070B77E /* KeychainAccess.framework in Frameworks */,
76 | );
77 | runOnlyForDeploymentPostprocessing = 0;
78 | };
79 | /* End PBXFrameworksBuildPhase section */
80 |
81 | /* Begin PBXGroup section */
82 | 14DAEE871A51E1BE0070B77E = {
83 | isa = PBXGroup;
84 | children = (
85 | 14DAEE921A51E1BE0070B77E /* Example-iOS */,
86 | 14DAEE911A51E1BE0070B77E /* Products */,
87 | 14DAEEB91A51E2A60070B77E /* KeychainAccess.xcodeproj */,
88 | );
89 | sourceTree = "";
90 | };
91 | 14DAEE911A51E1BE0070B77E /* Products */ = {
92 | isa = PBXGroup;
93 | children = (
94 | 14DAEE901A51E1BE0070B77E /* Example-iOS.app */,
95 | );
96 | name = Products;
97 | sourceTree = "";
98 | };
99 | 14DAEE921A51E1BE0070B77E /* Example-iOS */ = {
100 | isa = PBXGroup;
101 | children = (
102 | 14DAEE951A51E1BE0070B77E /* AppDelegate.swift */,
103 | 14DAEEB51A51E2690070B77E /* AccountsViewController.swift */,
104 | 14DAEEB61A51E2690070B77E /* InputViewController.swift */,
105 | 14DAEE991A51E1BE0070B77E /* Main.storyboard */,
106 | 14DAEE9E1A51E1BE0070B77E /* LaunchScreen.xib */,
107 | 14DAEE9C1A51E1BE0070B77E /* Images.xcassets */,
108 | 14DAEE931A51E1BE0070B77E /* Supporting Files */,
109 | );
110 | path = "Example-iOS";
111 | sourceTree = "";
112 | };
113 | 14DAEE931A51E1BE0070B77E /* Supporting Files */ = {
114 | isa = PBXGroup;
115 | children = (
116 | 14DAEE941A51E1BE0070B77E /* Info.plist */,
117 | 145652E11D898BB9006E8D0E /* Example-iOS.entitlements */,
118 | );
119 | name = "Supporting Files";
120 | sourceTree = "";
121 | };
122 | 14DAEEBA1A51E2A60070B77E /* Products */ = {
123 | isa = PBXGroup;
124 | children = (
125 | 14DAEEC11A51E2A60070B77E /* KeychainAccess.framework */,
126 | 14DAEEC31A51E2A60070B77E /* KeychainAccessTests.xctest */,
127 | 1470425E1D6FFA97005A4C6E /* TestHost.app */,
128 | );
129 | name = Products;
130 | sourceTree = "";
131 | };
132 | /* End PBXGroup section */
133 |
134 | /* Begin PBXNativeTarget section */
135 | 14DAEE8F1A51E1BE0070B77E /* Example-iOS */ = {
136 | isa = PBXNativeTarget;
137 | buildConfigurationList = 14DAEEAF1A51E1BE0070B77E /* Build configuration list for PBXNativeTarget "Example-iOS" */;
138 | buildPhases = (
139 | 14DAEE8C1A51E1BE0070B77E /* Sources */,
140 | 14DAEE8D1A51E1BE0070B77E /* Frameworks */,
141 | 14DAEE8E1A51E1BE0070B77E /* Resources */,
142 | 14DAEECA1A51E2D70070B77E /* CopyFiles */,
143 | );
144 | buildRules = (
145 | );
146 | dependencies = (
147 | );
148 | name = "Example-iOS";
149 | productName = "Example-iOS";
150 | productReference = 14DAEE901A51E1BE0070B77E /* Example-iOS.app */;
151 | productType = "com.apple.product-type.application";
152 | };
153 | /* End PBXNativeTarget section */
154 |
155 | /* Begin PBXProject section */
156 | 14DAEE881A51E1BE0070B77E /* Project object */ = {
157 | isa = PBXProject;
158 | attributes = {
159 | LastSwiftUpdateCheck = 0700;
160 | LastUpgradeCheck = 1200;
161 | ORGANIZATIONNAME = "kishikawa katsumi";
162 | TargetAttributes = {
163 | 14DAEE8F1A51E1BE0070B77E = {
164 | CreatedOnToolsVersion = 6.2;
165 | DevelopmentTeam = 27AEDK3C9F;
166 | LastSwiftMigration = 1100;
167 | };
168 | };
169 | };
170 | buildConfigurationList = 14DAEE8B1A51E1BE0070B77E /* Build configuration list for PBXProject "Example-iOS" */;
171 | compatibilityVersion = "Xcode 3.2";
172 | developmentRegion = en;
173 | hasScannedForEncodings = 0;
174 | knownRegions = (
175 | en,
176 | Base,
177 | );
178 | mainGroup = 14DAEE871A51E1BE0070B77E;
179 | productRefGroup = 14DAEE911A51E1BE0070B77E /* Products */;
180 | projectDirPath = "";
181 | projectReferences = (
182 | {
183 | ProductGroup = 14DAEEBA1A51E2A60070B77E /* Products */;
184 | ProjectRef = 14DAEEB91A51E2A60070B77E /* KeychainAccess.xcodeproj */;
185 | },
186 | );
187 | projectRoot = "";
188 | targets = (
189 | 14DAEE8F1A51E1BE0070B77E /* Example-iOS */,
190 | );
191 | };
192 | /* End PBXProject section */
193 |
194 | /* Begin PBXReferenceProxy section */
195 | 1470425E1D6FFA97005A4C6E /* TestHost.app */ = {
196 | isa = PBXReferenceProxy;
197 | fileType = wrapper.application;
198 | path = TestHost.app;
199 | remoteRef = 1470425D1D6FFA97005A4C6E /* PBXContainerItemProxy */;
200 | sourceTree = BUILT_PRODUCTS_DIR;
201 | };
202 | 14DAEEC11A51E2A60070B77E /* KeychainAccess.framework */ = {
203 | isa = PBXReferenceProxy;
204 | fileType = wrapper.framework;
205 | path = KeychainAccess.framework;
206 | remoteRef = 14DAEEC01A51E2A60070B77E /* PBXContainerItemProxy */;
207 | sourceTree = BUILT_PRODUCTS_DIR;
208 | };
209 | 14DAEEC31A51E2A60070B77E /* KeychainAccessTests.xctest */ = {
210 | isa = PBXReferenceProxy;
211 | fileType = wrapper.cfbundle;
212 | path = KeychainAccessTests.xctest;
213 | remoteRef = 14DAEEC21A51E2A60070B77E /* PBXContainerItemProxy */;
214 | sourceTree = BUILT_PRODUCTS_DIR;
215 | };
216 | /* End PBXReferenceProxy section */
217 |
218 | /* Begin PBXResourcesBuildPhase section */
219 | 14DAEE8E1A51E1BE0070B77E /* Resources */ = {
220 | isa = PBXResourcesBuildPhase;
221 | buildActionMask = 2147483647;
222 | files = (
223 | 14DAEE9B1A51E1BE0070B77E /* Main.storyboard in Resources */,
224 | 14DAEEA01A51E1BE0070B77E /* LaunchScreen.xib in Resources */,
225 | 14DAEE9D1A51E1BE0070B77E /* Images.xcassets in Resources */,
226 | );
227 | runOnlyForDeploymentPostprocessing = 0;
228 | };
229 | /* End PBXResourcesBuildPhase section */
230 |
231 | /* Begin PBXSourcesBuildPhase section */
232 | 14DAEE8C1A51E1BE0070B77E /* Sources */ = {
233 | isa = PBXSourcesBuildPhase;
234 | buildActionMask = 2147483647;
235 | files = (
236 | 14DAEEB81A51E2690070B77E /* InputViewController.swift in Sources */,
237 | 14DAEEB71A51E2690070B77E /* AccountsViewController.swift in Sources */,
238 | 14DAEE961A51E1BE0070B77E /* AppDelegate.swift in Sources */,
239 | );
240 | runOnlyForDeploymentPostprocessing = 0;
241 | };
242 | /* End PBXSourcesBuildPhase section */
243 |
244 | /* Begin PBXVariantGroup section */
245 | 14DAEE991A51E1BE0070B77E /* Main.storyboard */ = {
246 | isa = PBXVariantGroup;
247 | children = (
248 | 14DAEE9A1A51E1BE0070B77E /* Base */,
249 | );
250 | name = Main.storyboard;
251 | sourceTree = "";
252 | };
253 | 14DAEE9E1A51E1BE0070B77E /* LaunchScreen.xib */ = {
254 | isa = PBXVariantGroup;
255 | children = (
256 | 14DAEE9F1A51E1BE0070B77E /* Base */,
257 | );
258 | name = LaunchScreen.xib;
259 | sourceTree = "";
260 | };
261 | /* End PBXVariantGroup section */
262 |
263 | /* Begin XCBuildConfiguration section */
264 | 14DAEEAD1A51E1BE0070B77E /* Debug */ = {
265 | isa = XCBuildConfiguration;
266 | buildSettings = {
267 | ALWAYS_SEARCH_USER_PATHS = NO;
268 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
269 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
270 | CLANG_CXX_LIBRARY = "libc++";
271 | CLANG_ENABLE_MODULES = YES;
272 | CLANG_ENABLE_OBJC_ARC = YES;
273 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
274 | CLANG_WARN_BOOL_CONVERSION = YES;
275 | CLANG_WARN_COMMA = YES;
276 | CLANG_WARN_CONSTANT_CONVERSION = YES;
277 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
278 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
279 | CLANG_WARN_EMPTY_BODY = YES;
280 | CLANG_WARN_ENUM_CONVERSION = YES;
281 | CLANG_WARN_INFINITE_RECURSION = YES;
282 | CLANG_WARN_INT_CONVERSION = YES;
283 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
284 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
285 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
286 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
287 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
288 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
289 | CLANG_WARN_STRICT_PROTOTYPES = YES;
290 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
291 | CLANG_WARN_UNREACHABLE_CODE = YES;
292 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
293 | CODE_SIGN_ENTITLEMENTS = "Example-iOS/Example-iOS.entitlements";
294 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
295 | COPY_PHASE_STRIP = NO;
296 | ENABLE_STRICT_OBJC_MSGSEND = YES;
297 | ENABLE_TESTABILITY = YES;
298 | GCC_C_LANGUAGE_STANDARD = gnu99;
299 | GCC_DYNAMIC_NO_PIC = NO;
300 | GCC_NO_COMMON_BLOCKS = YES;
301 | GCC_OPTIMIZATION_LEVEL = 0;
302 | GCC_PREPROCESSOR_DEFINITIONS = (
303 | "DEBUG=1",
304 | "$(inherited)",
305 | );
306 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
307 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
308 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
309 | GCC_WARN_UNDECLARED_SELECTOR = YES;
310 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
311 | GCC_WARN_UNUSED_FUNCTION = YES;
312 | GCC_WARN_UNUSED_VARIABLE = YES;
313 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
314 | MTL_ENABLE_DEBUG_INFO = YES;
315 | ONLY_ACTIVE_ARCH = YES;
316 | SDKROOT = iphoneos;
317 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
318 | SWIFT_VERSION = 4.1;
319 | };
320 | name = Debug;
321 | };
322 | 14DAEEAE1A51E1BE0070B77E /* Release */ = {
323 | isa = XCBuildConfiguration;
324 | buildSettings = {
325 | ALWAYS_SEARCH_USER_PATHS = NO;
326 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
327 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
328 | CLANG_CXX_LIBRARY = "libc++";
329 | CLANG_ENABLE_MODULES = YES;
330 | CLANG_ENABLE_OBJC_ARC = YES;
331 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
332 | CLANG_WARN_BOOL_CONVERSION = YES;
333 | CLANG_WARN_COMMA = YES;
334 | CLANG_WARN_CONSTANT_CONVERSION = YES;
335 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
336 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
337 | CLANG_WARN_EMPTY_BODY = YES;
338 | CLANG_WARN_ENUM_CONVERSION = YES;
339 | CLANG_WARN_INFINITE_RECURSION = YES;
340 | CLANG_WARN_INT_CONVERSION = YES;
341 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
342 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
343 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
344 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
345 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
346 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
347 | CLANG_WARN_STRICT_PROTOTYPES = YES;
348 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
349 | CLANG_WARN_UNREACHABLE_CODE = YES;
350 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
351 | CODE_SIGN_ENTITLEMENTS = "Example-iOS/Example-iOS.entitlements";
352 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
353 | COPY_PHASE_STRIP = YES;
354 | ENABLE_NS_ASSERTIONS = NO;
355 | ENABLE_STRICT_OBJC_MSGSEND = YES;
356 | GCC_C_LANGUAGE_STANDARD = gnu99;
357 | GCC_NO_COMMON_BLOCKS = YES;
358 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
359 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
360 | GCC_WARN_UNDECLARED_SELECTOR = YES;
361 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
362 | GCC_WARN_UNUSED_FUNCTION = YES;
363 | GCC_WARN_UNUSED_VARIABLE = YES;
364 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
365 | MTL_ENABLE_DEBUG_INFO = NO;
366 | SDKROOT = iphoneos;
367 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
368 | SWIFT_VERSION = 4.1;
369 | VALIDATE_PRODUCT = YES;
370 | };
371 | name = Release;
372 | };
373 | 14DAEEB01A51E1BE0070B77E /* Debug */ = {
374 | isa = XCBuildConfiguration;
375 | buildSettings = {
376 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
377 | DEVELOPMENT_TEAM = 27AEDK3C9F;
378 | INFOPLIST_FILE = "Example-iOS/Info.plist";
379 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
380 | PRODUCT_BUNDLE_IDENTIFIER = "com.kishikawakatsumi.$(PRODUCT_NAME:rfc1034identifier)";
381 | PRODUCT_NAME = "$(TARGET_NAME)";
382 | SWIFT_VERSION = 5.0;
383 | };
384 | name = Debug;
385 | };
386 | 14DAEEB11A51E1BE0070B77E /* Release */ = {
387 | isa = XCBuildConfiguration;
388 | buildSettings = {
389 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
390 | DEVELOPMENT_TEAM = 27AEDK3C9F;
391 | INFOPLIST_FILE = "Example-iOS/Info.plist";
392 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
393 | PRODUCT_BUNDLE_IDENTIFIER = "com.kishikawakatsumi.$(PRODUCT_NAME:rfc1034identifier)";
394 | PRODUCT_NAME = "$(TARGET_NAME)";
395 | SWIFT_VERSION = 5.0;
396 | };
397 | name = Release;
398 | };
399 | /* End XCBuildConfiguration section */
400 |
401 | /* Begin XCConfigurationList section */
402 | 14DAEE8B1A51E1BE0070B77E /* Build configuration list for PBXProject "Example-iOS" */ = {
403 | isa = XCConfigurationList;
404 | buildConfigurations = (
405 | 14DAEEAD1A51E1BE0070B77E /* Debug */,
406 | 14DAEEAE1A51E1BE0070B77E /* Release */,
407 | );
408 | defaultConfigurationIsVisible = 0;
409 | defaultConfigurationName = Release;
410 | };
411 | 14DAEEAF1A51E1BE0070B77E /* Build configuration list for PBXNativeTarget "Example-iOS" */ = {
412 | isa = XCConfigurationList;
413 | buildConfigurations = (
414 | 14DAEEB01A51E1BE0070B77E /* Debug */,
415 | 14DAEEB11A51E1BE0070B77E /* Release */,
416 | );
417 | defaultConfigurationIsVisible = 0;
418 | defaultConfigurationName = Release;
419 | };
420 | /* End XCConfigurationList section */
421 | };
422 | rootObject = 14DAEE881A51E1BE0070B77E /* Project object */;
423 | }
424 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/Example-iOS.xcodeproj/xcshareddata/xcschemes/Example-iOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
51 |
52 |
53 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
76 |
78 |
84 |
85 |
86 |
87 |
93 |
95 |
101 |
102 |
103 |
104 |
106 |
107 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/Example-iOS/AccountsViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AccountsViewController.swift
3 | // Example
4 | //
5 | // Created by kishikawa katsumi on 2014/12/25.
6 | // Copyright (c) 2014 kishikawa katsumi. All rights reserved.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy
9 | // of this software and associated documentation files (the "Software"), to deal
10 | // in the Software without restriction, including without limitation the rights
11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | // copies of the Software, and to permit persons to whom the Software is
13 | // furnished to do so, subject to the following conditions:
14 | //
15 | // The above copyright notice and this permission notice shall be included in
16 | // all copies or substantial portions of the Software.
17 | //
18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | // THE SOFTWARE.
25 |
26 | import UIKit
27 | import KeychainAccess
28 |
29 | class AccountsViewController: UITableViewController {
30 | var itemsGroupedByService: [String: [[String: Any]]]?
31 |
32 | override func viewDidLoad() {
33 | super.viewDidLoad()
34 | }
35 |
36 | override func viewWillAppear(_ animated: Bool) {
37 | super.viewWillAppear(animated)
38 |
39 | reloadData()
40 | tableView.reloadData()
41 | }
42 |
43 | override func didReceiveMemoryWarning() {
44 | super.didReceiveMemoryWarning()
45 | }
46 |
47 | // MARK:
48 |
49 | override func numberOfSections(in tableView: UITableView) -> Int {
50 | if itemsGroupedByService != nil {
51 | let services = Array(itemsGroupedByService!.keys)
52 | return services.count
53 | }
54 | return 0
55 | }
56 |
57 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
58 | let services = Array(itemsGroupedByService!.keys)
59 | let service = services[section]
60 |
61 | let items = Keychain(service: service).allItems()
62 | return items.count
63 | }
64 |
65 | override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
66 | let services = Array(itemsGroupedByService!.keys)
67 | return services[section]
68 | }
69 |
70 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
71 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
72 |
73 | let services = Array(itemsGroupedByService!.keys)
74 | let service = services[indexPath.section]
75 |
76 | let items = Keychain(service: service).allItems()
77 | let item = items[indexPath.row]
78 |
79 | cell.textLabel?.text = item["key"] as? String
80 | cell.detailTextLabel?.text = item["value"] as? String
81 |
82 | return cell
83 | }
84 |
85 | #if swift(>=4.2)
86 | override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
87 | let services = Array(itemsGroupedByService!.keys)
88 | let service = services[indexPath.section]
89 |
90 | let keychain = Keychain(service: service)
91 | let items = keychain.allItems()
92 |
93 | let item = items[indexPath.row]
94 | let key = item["key"] as! String
95 |
96 | keychain[key] = nil
97 |
98 | if items.count == 1 {
99 | reloadData()
100 | tableView.deleteSections(IndexSet(integer: indexPath.section), with: .automatic)
101 | } else {
102 | tableView.deleteRows(at: [indexPath], with: .automatic)
103 | }
104 | }
105 | #else
106 | override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
107 | let services = Array(itemsGroupedByService!.keys)
108 | let service = services[indexPath.section]
109 |
110 | let keychain = Keychain(service: service)
111 | let items = keychain.allItems()
112 |
113 | let item = items[indexPath.row]
114 | let key = item["key"] as! String
115 |
116 | keychain[key] = nil
117 |
118 | if items.count == 1 {
119 | reloadData()
120 | tableView.deleteSections(IndexSet(integer: indexPath.section), with: .automatic)
121 | } else {
122 | tableView.deleteRows(at: [indexPath], with: .automatic)
123 | }
124 | }
125 | #endif
126 |
127 | // MARK:
128 |
129 | func reloadData() {
130 | let items = Keychain.allItems(.genericPassword)
131 | itemsGroupedByService = groupBy(items) { item -> String in
132 | if let service = item["service"] as? String {
133 | return service
134 | }
135 | return ""
136 | }
137 | }
138 | }
139 |
140 | private func groupBy(_ xs: C, key: (C.Iterator.Element) -> K) -> [K:[C.Iterator.Element]] {
141 | var gs: [K:[C.Iterator.Element]] = [:]
142 | for x in xs {
143 | let k = key(x)
144 | var ys = gs[k] ?? []
145 | ys.append(x)
146 | gs.updateValue(ys, forKey: k)
147 | }
148 | return gs
149 | }
150 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/Example-iOS/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Example
4 | //
5 | // Created by kishikawa katsumi on 2014/12/25.
6 | // Copyright (c) 2014 kishikawa katsumi. All rights reserved.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy
9 | // of this software and associated documentation files (the "Software"), to deal
10 | // in the Software without restriction, including without limitation the rights
11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | // copies of the Software, and to permit persons to whom the Software is
13 | // furnished to do so, subject to the following conditions:
14 | //
15 | // The above copyright notice and this permission notice shall be included in
16 | // all copies or substantial portions of the Software.
17 | //
18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | // THE SOFTWARE.
25 |
26 | import UIKit
27 |
28 | @UIApplicationMain
29 | class AppDelegate: UIResponder, UIApplicationDelegate {
30 | var window: UIWindow?
31 |
32 | #if swift(>=4.2)
33 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
34 | return true
35 | }
36 | #else
37 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
38 | return true
39 | }
40 | #endif
41 | }
42 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/Example-iOS/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/Example-iOS/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
33 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/Example-iOS/Example-iOS.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | keychain-access-groups
6 |
7 | $(AppIdentifierPrefix)com.kishikawakatsumi.Example-iOS
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/Example-iOS/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ios-marketing",
45 | "size" : "1024x1024",
46 | "scale" : "1x"
47 | }
48 | ],
49 | "info" : {
50 | "version" : 1,
51 | "author" : "xcode"
52 | }
53 | }
--------------------------------------------------------------------------------
/Examples/Example-iOS/Example-iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Examples/Example-iOS/Example-iOS/InputViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InputViewController.swift
3 | // Example
4 | //
5 | // Created by kishikawa katsumi on 2014/12/26.
6 | // Copyright (c) 2014 kishikawa katsumi. All rights reserved.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy
9 | // of this software and associated documentation files (the "Software"), to deal
10 | // in the Software without restriction, including without limitation the rights
11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | // copies of the Software, and to permit persons to whom the Software is
13 | // furnished to do so, subject to the following conditions:
14 | //
15 | // The above copyright notice and this permission notice shall be included in
16 | // all copies or substantial portions of the Software.
17 | //
18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | // THE SOFTWARE.
25 |
26 | import UIKit
27 | import KeychainAccess
28 |
29 | class InputViewController: UITableViewController {
30 |
31 | @IBOutlet weak var saveButton: UIBarButtonItem!
32 | @IBOutlet weak var cancelButton: UIBarButtonItem!
33 |
34 | @IBOutlet weak var usernameField: UITextField!
35 | @IBOutlet weak var passwordField: UITextField!
36 | @IBOutlet weak var serviceField: UITextField!
37 |
38 | override func viewDidLoad() {
39 | super.viewDidLoad()
40 |
41 | tableView.rowHeight = 44.0
42 | tableView.estimatedRowHeight = 44.0
43 | }
44 |
45 | override func didReceiveMemoryWarning() {
46 | super.didReceiveMemoryWarning()
47 | }
48 |
49 | // MARK:
50 |
51 | @IBAction func cancelAction(sender: UIBarButtonItem) {
52 | dismiss(animated: true, completion: nil)
53 | }
54 |
55 | @IBAction func saveAction(sender: UIBarButtonItem) {
56 | let keychain: Keychain
57 | if let service = serviceField.text, !service.isEmpty {
58 | keychain = Keychain(service: service)
59 | } else {
60 | keychain = Keychain()
61 | }
62 | keychain[usernameField.text!] = passwordField.text
63 |
64 | dismiss(animated: true, completion: nil)
65 | }
66 |
67 | @IBAction func editingChanged(sender: UITextField) {
68 | switch (usernameField.text, passwordField.text) {
69 | case let (username?, password?):
70 | saveButton.isEnabled = !username.isEmpty && !password.isEmpty
71 | case (_?, nil):
72 | saveButton.isEnabled = false
73 | case (nil, _?):
74 | saveButton.isEnabled = false
75 | case (nil, nil):
76 | saveButton.isEnabled = false
77 | }
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/KeychainAccess.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'KeychainAccess'
3 | s.version = '4.2.2'
4 | s.summary = 'KeychainAccess is a simple Swift wrapper for Keychain that works on iOS and macOS.'
5 | s.description = <<-DESC
6 | KeychainAccess is a simple Swift wrapper for Keychain that works on iOS and macOS.
7 | Makes using Keychain APIs exremely easy and much more palatable to use in Swift.
8 |
9 | Features
10 | - Simple interface
11 | - Support access group
12 | - Support accessibility
13 | - Support iCloud sharing
14 | - **Support TouchID and Keychain integration (iOS 8+)**
15 | - **Support Shared Web Credentials (iOS 8+)**
16 | - Works on both iOS & macOS
17 | - watchOS and tvOS are also supported
18 | DESC
19 | s.homepage = 'https://github.com/kishikawakatsumi/KeychainAccess'
20 | s.screenshots = 'https://raw.githubusercontent.com/kishikawakatsumi/KeychainAccess/master/Screenshots/01.png'
21 | s.license = 'MIT'
22 | s.author = { 'kishikawa katsumi' => 'kishikawakatsumi@mac.com' }
23 | s.source = { :git => 'https://github.com/kishikawakatsumi/KeychainAccess.git', :tag => "v#{s.version}" }
24 | s.social_media_url = 'https://twitter.com/k_katsumi'
25 |
26 | s.requires_arc = true
27 | s.source_files = 'Lib/KeychainAccess/*.swift'
28 |
29 | s.swift_version = '5.1'
30 |
31 | s.ios.deployment_target = '9.0'
32 | s.osx.deployment_target = '10.9'
33 | s.watchos.deployment_target = '3.0'
34 | s.tvos.deployment_target = '9.0'
35 | end
36 |
--------------------------------------------------------------------------------
/KeychainAccess.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/KeychainAccess.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 kishikawa katsumi
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/Lib/Configurations/Base.xcconfig:
--------------------------------------------------------------------------------
1 | ALWAYS_SEARCH_USER_PATHS = NO;
2 | CLANG_ANALYZER_NONNULL = YES
3 | CLANG_CXX_LANGUAGE_STANDARD = gnu++0x;
4 | CLANG_CXX_LIBRARY = libc++;
5 | CLANG_ENABLE_MODULES = YES;
6 | CLANG_ENABLE_OBJC_ARC = YES;
7 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
8 | CLANG_WARN_BOOL_CONVERSION = YES;
9 | CLANG_WARN_COMMA = YES;
10 | CLANG_WARN_CONSTANT_CONVERSION = YES;
11 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
12 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
13 | CLANG_WARN_EMPTY_BODY = YES;
14 | CLANG_WARN_ENUM_CONVERSION = YES;
15 | CLANG_WARN_INFINITE_RECURSION = YES;
16 | CLANG_WARN_INT_CONVERSION = YES;
17 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
18 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
19 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
20 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
21 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
22 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
23 | CLANG_WARN_STRICT_PROTOTYPES = YES;
24 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
25 | CLANG_WARN_UNREACHABLE_CODE = YES;
26 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
27 | CURRENT_PROJECT_VERSION = 1;
28 | ENABLE_STRICT_OBJC_MSGSEND = YES;
29 | GCC_C_LANGUAGE_STANDARD = gnu99;
30 | GCC_NO_COMMON_BLOCKS = YES;
31 | GCC_DYNAMIC_NO_PIC = NO;
32 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
33 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
34 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
35 | GCC_WARN_UNDECLARED_SELECTOR = YES;
36 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
37 | GCC_WARN_UNUSED_FUNCTION = YES;
38 | GCC_WARN_UNUSED_VARIABLE = YES;
39 | VERSIONING_SYSTEM = "apple-generic";
40 | VERSION_INFO_PREFIX = "";
41 |
42 | CODE_SIGN_IDENTITY = ;
43 | DEVELOPMENT_TEAM = ;
44 |
45 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
46 | WATCHOS_DEPLOYMENT_TARGET = 3.0;
47 | TVOS_DEPLOYMENT_TARGET = 9.0;
48 | MACOSX_DEPLOYMENT_TARGET = 10.9;
49 |
50 | SWIFT_VERSION = 5.0;
51 |
--------------------------------------------------------------------------------
/Lib/Configurations/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Base.xcconfig"
2 |
3 | BITCODE_GENERATION_MODE = marker;
4 | MTL_ENABLE_DEBUG_INFO = YES;
5 | COPY_PHASE_STRIP = NO;
6 | ENABLE_TESTABILITY = YES;
7 | GCC_OPTIMIZATION_LEVEL = 0;
8 | ONLY_ACTIVE_ARCH = YES;
9 | SWIFT_OPTIMIZATION_LEVEL = -Onone;
10 |
11 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DEBUG=1;
12 |
--------------------------------------------------------------------------------
/Lib/Configurations/KeychainAccess.xcconfig:
--------------------------------------------------------------------------------
1 | SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator watchos watchsimulator appletvos appletvsimulator;
2 | TARGETED_DEVICE_FAMILY = 1,2,3,4;
3 | SUPPORTS_MACCATALYST = YES;
4 | DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = YES;
5 |
6 | COMBINE_HIDPI_IMAGES = YES;
7 | PRODUCT_BUNDLE_IDENTIFIER = com.kishikawakatsumi.$(PLATFORM_NAME).$(PRODUCT_NAME:rfc1034identifier);
8 | PRODUCT_NAME = $(PROJECT_NAME);
9 | APPLICATION_EXTENSION_API_ONLY = YES;
10 | INFOPLIST_FILE = KeychainAccess/Info.plist;
11 | SKIP_INSTALL = YES;
12 |
13 | BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
14 | DEFINES_MODULE = YES;
15 | DYLIB_COMPATIBILITY_VERSION = 1;
16 | DYLIB_CURRENT_VERSION = 1;
17 | DYLIB_INSTALL_NAME_BASE = @rpath;
18 |
19 | ENABLE_BITCODE[sdk=iphone*] = YES;
20 | ENABLE_BITCODE[sdk=watch*] = YES;
21 | ENABLE_BITCODE[sdk=appletv*] = YES;
22 |
23 | LD_RUNPATH_SEARCH_PATHS[sdk=iphone*] = $(inherited) @executable_path/Frameworks @loader_path/Frameworks;
24 | LD_RUNPATH_SEARCH_PATHS[sdk=watch*] = $(inherited) @executable_path/Frameworks @loader_path/Frameworks;
25 | LD_RUNPATH_SEARCH_PATHS[sdk=appletv*] = $(inherited) @executable_path/Frameworks @loader_path/Frameworks;
26 | LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = $(inherited) @executable_path/../Frameworks @loader_path/../Frameworks;
27 |
--------------------------------------------------------------------------------
/Lib/Configurations/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Base.xcconfig"
2 |
3 | BITCODE_GENERATION_MODE = bitcode;
4 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
5 | ENABLE_NS_ASSERTIONS = NO;
6 | MTL_ENABLE_DEBUG_INFO = NO;
7 | VALIDATE_PRODUCT = YES;
8 | SWIFT_COMPILATION_MODE = wholemodule;
9 | SWIFT_OPTIMIZATION_LEVEL = -Owholemodule;
10 |
--------------------------------------------------------------------------------
/Lib/Configurations/TestHost.xcconfig:
--------------------------------------------------------------------------------
1 | SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator appletvos appletvsimulator;
2 | TARGETED_DEVICE_FAMILY = 1,2,3;
3 | SUPPORTS_MACCATALYST = YES;
4 |
5 | COMBINE_HIDPI_IMAGES = YES;
6 | COPY_PHASE_STRIP = NO;
7 | INFOPLIST_FILE = TestHost/Info.plist;
8 | PRODUCT_NAME = $(TARGET_NAME);
9 | CLANG_MODULES_AUTOLINK = NO;
10 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
11 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
12 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
13 |
14 | PRODUCT_BUNDLE_IDENTIFIER = com.kishikawakatsumi.KeychainAccess.TestHost;
15 |
16 | CODE_SIGN_ENTITLEMENTS = TestHost/TestHost.entitlements;
17 |
18 | CODE_SIGN_IDENTITY[sdk=iphone*] = iPhone Developer;
19 | CODE_SIGN_IDENTITY[sdk=macosx*] = Developer ID Application;
20 | PROVISIONING_PROFILE_SPECIFIER[sdk=iphone*] = iOS Development;
21 | PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*] = KeychainAccess Tests;
22 |
23 | DEVELOPMENT_TEAM = 27AEDK3C9F;
24 |
25 | PRINCIPAL_CLASS[sdk=iphone*] = UIApplication;
26 | PRINCIPAL_CLASS[sdk=appletv*] = UIApplication;
27 | PRINCIPAL_CLASS[sdk=macosx*] = NSApplication;
28 |
29 | LD_RUNPATH_SEARCH_PATHS[sdk=iphone*] = $(inherited) @executable_path/Frameworks @loader_path/Frameworks;
30 | LD_RUNPATH_SEARCH_PATHS[sdk=watch*] = $(inherited) @executable_path/Frameworks @loader_path/Frameworks;
31 | LD_RUNPATH_SEARCH_PATHS[sdk=appletv*] = $(inherited) @executable_path/Frameworks @loader_path/Frameworks;
32 | LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = $(inherited) @executable_path/../Frameworks @loader_path/../Frameworks;
33 |
--------------------------------------------------------------------------------
/Lib/Configurations/Tests.xcconfig:
--------------------------------------------------------------------------------
1 | SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator appletvos appletvsimulator;
2 | TARGETED_DEVICE_FAMILY = 1,2;
3 | SUPPORTS_MACCATALYST = YES;
4 |
5 | COMBINE_HIDPI_IMAGES = YES;
6 | PRODUCT_BUNDLE_IDENTIFIER = com.kishikawakatsumi.$(PRODUCT_NAME:rfc1034identifier);
7 | PRODUCT_NAME = $(TARGET_NAME);
8 | APPLICATION_EXTENSION_API_ONLY = NO;
9 | INFOPLIST_FILE = KeychainAccessTests/Info.plist;
10 |
11 | LD_RUNPATH_SEARCH_PATHS[sdk=iphone*] = $(inherited) @executable_path/Frameworks @loader_path/Frameworks;
12 | LD_RUNPATH_SEARCH_PATHS[sdk=watch*] = $(inherited) @executable_path/Frameworks @loader_path/Frameworks;
13 | LD_RUNPATH_SEARCH_PATHS[sdk=appletv*] = $(inherited) @executable_path/Frameworks @loader_path/Frameworks;
14 | LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = $(inherited) @executable_path/../Frameworks @loader_path/../Frameworks;
15 |
16 | TEST_HOST[sdk=iphone*] = $(BUILT_PRODUCTS_DIR)/TestHost.app/TestHost;
17 | TEST_HOST[sdk=appletv*] = $(BUILT_PRODUCTS_DIR)/TestHost.app/TestHost;
18 | TEST_HOST[sdk=macosx*] = $(BUILT_PRODUCTS_DIR)/TestHost.app/Contents/MacOS/TestHost;
19 |
20 | EXCLUDED_SOURCE_FILE_NAMES[sdk=watch*] = *;
21 | EXCLUDED_SOURCE_FILE_NAMES[sdk=appletv*] = SharedCredentialTests.swift;
22 | EXCLUDED_SOURCE_FILE_NAMES[sdk=macosx*] = SharedCredentialTests.swift;
23 |
24 | DEVELOPMENT_TEAM = 27AEDK3C9F;
25 |
--------------------------------------------------------------------------------
/Lib/KeychainAccess.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 140F19621A49D79400B0016A /* KeychainAccess.h in Headers */ = {isa = PBXBuildFile; fileRef = 140F19611A49D79400B0016A /* KeychainAccess.h */; settings = {ATTRIBUTES = (Public, ); }; };
11 | 140F196F1A49D79500B0016A /* KeychainAccessTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 140F196E1A49D79500B0016A /* KeychainAccessTests.swift */; };
12 | 140F197B1A49D89200B0016A /* Keychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 140F197A1A49D89200B0016A /* Keychain.swift */; };
13 | 142EDA851BCB505F00A32149 /* ErrorTypeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 142EDA841BCB505F00A32149 /* ErrorTypeTests.swift */; };
14 | 142EDB041BCBB0DD00A32149 /* SharedCredentialTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 142EDB031BCBB0DD00A32149 /* SharedCredentialTests.swift */; };
15 | 148F9D4A1BCB4118006EDF48 /* EnumTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 148F9D491BCB4118006EDF48 /* EnumTests.swift */; };
16 | 14A630181D3293C700809B3F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14A630171D3293C700809B3F /* AppDelegate.swift */; };
17 | 14A6301F1D3293C700809B3F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 14A6301E1D3293C700809B3F /* Assets.xcassets */; };
18 | 14C3A6781D32BF9C00349459 /* KeychainAccess.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 140F195C1A49D79400B0016A /* KeychainAccess.framework */; };
19 | 14C3A6791D32BF9C00349459 /* KeychainAccess.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 140F195C1A49D79400B0016A /* KeychainAccess.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20 | /* End PBXBuildFile section */
21 |
22 | /* Begin PBXContainerItemProxy section */
23 | 140F19691A49D79500B0016A /* PBXContainerItemProxy */ = {
24 | isa = PBXContainerItemProxy;
25 | containerPortal = 140F19531A49D79400B0016A /* Project object */;
26 | proxyType = 1;
27 | remoteGlobalIDString = 140F195B1A49D79400B0016A;
28 | remoteInfo = KeychainAccess;
29 | };
30 | 14C3A67A1D32BF9C00349459 /* PBXContainerItemProxy */ = {
31 | isa = PBXContainerItemProxy;
32 | containerPortal = 140F19531A49D79400B0016A /* Project object */;
33 | proxyType = 1;
34 | remoteGlobalIDString = 140F195B1A49D79400B0016A;
35 | remoteInfo = KeychainAccess;
36 | };
37 | 14F0C1991D32A160007DCDDB /* PBXContainerItemProxy */ = {
38 | isa = PBXContainerItemProxy;
39 | containerPortal = 140F19531A49D79400B0016A /* Project object */;
40 | proxyType = 1;
41 | remoteGlobalIDString = 14A630141D3293C700809B3F;
42 | remoteInfo = TestHost;
43 | };
44 | /* End PBXContainerItemProxy section */
45 |
46 | /* Begin PBXCopyFilesBuildPhase section */
47 | 14C3A67C1D32BF9D00349459 /* Embed Frameworks */ = {
48 | isa = PBXCopyFilesBuildPhase;
49 | buildActionMask = 2147483647;
50 | dstPath = "";
51 | dstSubfolderSpec = 10;
52 | files = (
53 | 14C3A6791D32BF9C00349459 /* KeychainAccess.framework in Embed Frameworks */,
54 | );
55 | name = "Embed Frameworks";
56 | runOnlyForDeploymentPostprocessing = 0;
57 | };
58 | /* End PBXCopyFilesBuildPhase section */
59 |
60 | /* Begin PBXFileReference section */
61 | 140F195C1A49D79400B0016A /* KeychainAccess.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = KeychainAccess.framework; sourceTree = BUILT_PRODUCTS_DIR; };
62 | 140F19601A49D79400B0016A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
63 | 140F19611A49D79400B0016A /* KeychainAccess.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeychainAccess.h; sourceTree = ""; };
64 | 140F19671A49D79500B0016A /* KeychainAccessTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KeychainAccessTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
65 | 140F196D1A49D79500B0016A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
66 | 140F196E1A49D79500B0016A /* KeychainAccessTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainAccessTests.swift; sourceTree = ""; };
67 | 140F197A1A49D89200B0016A /* Keychain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Keychain.swift; sourceTree = ""; };
68 | 142EDA841BCB505F00A32149 /* ErrorTypeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ErrorTypeTests.swift; sourceTree = ""; };
69 | 142EDB031BCBB0DD00A32149 /* SharedCredentialTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SharedCredentialTests.swift; sourceTree = ""; };
70 | 148E44E51BF9EDCB004FFEC1 /* Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Base.xcconfig; path = Configurations/Base.xcconfig; sourceTree = ""; };
71 | 148E44E61BF9EDCB004FFEC1 /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Configurations/Debug.xcconfig; sourceTree = ""; };
72 | 148E44E71BF9EDCB004FFEC1 /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Configurations/Release.xcconfig; sourceTree = ""; };
73 | 148E44E91BF9EDE4004FFEC1 /* Tests.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Tests.xcconfig; path = Configurations/Tests.xcconfig; sourceTree = ""; };
74 | 148E44EB1BF9EEB3004FFEC1 /* KeychainAccess.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = KeychainAccess.xcconfig; path = Configurations/KeychainAccess.xcconfig; sourceTree = ""; };
75 | 148F9D491BCB4118006EDF48 /* EnumTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnumTests.swift; sourceTree = ""; };
76 | 14A630151D3293C700809B3F /* TestHost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestHost.app; sourceTree = BUILT_PRODUCTS_DIR; };
77 | 14A630171D3293C700809B3F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
78 | 14A6301E1D3293C700809B3F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
79 | 14A630231D3293C700809B3F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
80 | 14F0C1961D3295C4007DCDDB /* TestHost.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = TestHost.entitlements; sourceTree = ""; };
81 | 14F0C1981D329832007DCDDB /* TestHost.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = TestHost.xcconfig; path = Configurations/TestHost.xcconfig; sourceTree = ""; };
82 | /* End PBXFileReference section */
83 |
84 | /* Begin PBXFrameworksBuildPhase section */
85 | 140F19581A49D79400B0016A /* Frameworks */ = {
86 | isa = PBXFrameworksBuildPhase;
87 | buildActionMask = 2147483647;
88 | files = (
89 | );
90 | runOnlyForDeploymentPostprocessing = 0;
91 | };
92 | 140F19641A49D79500B0016A /* Frameworks */ = {
93 | isa = PBXFrameworksBuildPhase;
94 | buildActionMask = 2147483647;
95 | files = (
96 | );
97 | runOnlyForDeploymentPostprocessing = 0;
98 | };
99 | 14A630121D3293C700809B3F /* Frameworks */ = {
100 | isa = PBXFrameworksBuildPhase;
101 | buildActionMask = 2147483647;
102 | files = (
103 | 14C3A6781D32BF9C00349459 /* KeychainAccess.framework in Frameworks */,
104 | );
105 | runOnlyForDeploymentPostprocessing = 0;
106 | };
107 | /* End PBXFrameworksBuildPhase section */
108 |
109 | /* Begin PBXGroup section */
110 | 140F19521A49D79400B0016A = {
111 | isa = PBXGroup;
112 | children = (
113 | 140F195E1A49D79400B0016A /* KeychainAccess */,
114 | 140F196B1A49D79500B0016A /* KeychainAccessTests */,
115 | 148E44E41BF9ED6D004FFEC1 /* Cofigurations */,
116 | 14A630161D3293C700809B3F /* TestHost */,
117 | 140F195D1A49D79400B0016A /* Products */,
118 | );
119 | sourceTree = "";
120 | };
121 | 140F195D1A49D79400B0016A /* Products */ = {
122 | isa = PBXGroup;
123 | children = (
124 | 140F195C1A49D79400B0016A /* KeychainAccess.framework */,
125 | 140F19671A49D79500B0016A /* KeychainAccessTests.xctest */,
126 | 14A630151D3293C700809B3F /* TestHost.app */,
127 | );
128 | name = Products;
129 | sourceTree = "";
130 | };
131 | 140F195E1A49D79400B0016A /* KeychainAccess */ = {
132 | isa = PBXGroup;
133 | children = (
134 | 140F19611A49D79400B0016A /* KeychainAccess.h */,
135 | 140F197A1A49D89200B0016A /* Keychain.swift */,
136 | 140F195F1A49D79400B0016A /* Supporting Files */,
137 | );
138 | path = KeychainAccess;
139 | sourceTree = "";
140 | };
141 | 140F195F1A49D79400B0016A /* Supporting Files */ = {
142 | isa = PBXGroup;
143 | children = (
144 | 140F19601A49D79400B0016A /* Info.plist */,
145 | );
146 | name = "Supporting Files";
147 | sourceTree = "";
148 | };
149 | 140F196B1A49D79500B0016A /* KeychainAccessTests */ = {
150 | isa = PBXGroup;
151 | children = (
152 | 140F196E1A49D79500B0016A /* KeychainAccessTests.swift */,
153 | 148F9D491BCB4118006EDF48 /* EnumTests.swift */,
154 | 142EDA841BCB505F00A32149 /* ErrorTypeTests.swift */,
155 | 142EDB031BCBB0DD00A32149 /* SharedCredentialTests.swift */,
156 | 140F196C1A49D79500B0016A /* Supporting Files */,
157 | );
158 | path = KeychainAccessTests;
159 | sourceTree = "";
160 | };
161 | 140F196C1A49D79500B0016A /* Supporting Files */ = {
162 | isa = PBXGroup;
163 | children = (
164 | 140F196D1A49D79500B0016A /* Info.plist */,
165 | );
166 | name = "Supporting Files";
167 | sourceTree = "";
168 | };
169 | 148E44E41BF9ED6D004FFEC1 /* Cofigurations */ = {
170 | isa = PBXGroup;
171 | children = (
172 | 148E44E51BF9EDCB004FFEC1 /* Base.xcconfig */,
173 | 148E44E61BF9EDCB004FFEC1 /* Debug.xcconfig */,
174 | 148E44E71BF9EDCB004FFEC1 /* Release.xcconfig */,
175 | 148E44EB1BF9EEB3004FFEC1 /* KeychainAccess.xcconfig */,
176 | 148E44E91BF9EDE4004FFEC1 /* Tests.xcconfig */,
177 | 14F0C1981D329832007DCDDB /* TestHost.xcconfig */,
178 | );
179 | name = Cofigurations;
180 | sourceTree = "";
181 | };
182 | 14A630161D3293C700809B3F /* TestHost */ = {
183 | isa = PBXGroup;
184 | children = (
185 | 14A630171D3293C700809B3F /* AppDelegate.swift */,
186 | 14A6301E1D3293C700809B3F /* Assets.xcassets */,
187 | 14A630231D3293C700809B3F /* Info.plist */,
188 | 14F0C1961D3295C4007DCDDB /* TestHost.entitlements */,
189 | );
190 | path = TestHost;
191 | sourceTree = "";
192 | };
193 | /* End PBXGroup section */
194 |
195 | /* Begin PBXHeadersBuildPhase section */
196 | 140F19591A49D79400B0016A /* Headers */ = {
197 | isa = PBXHeadersBuildPhase;
198 | buildActionMask = 2147483647;
199 | files = (
200 | 140F19621A49D79400B0016A /* KeychainAccess.h in Headers */,
201 | );
202 | runOnlyForDeploymentPostprocessing = 0;
203 | };
204 | /* End PBXHeadersBuildPhase section */
205 |
206 | /* Begin PBXNativeTarget section */
207 | 140F195B1A49D79400B0016A /* KeychainAccess */ = {
208 | isa = PBXNativeTarget;
209 | buildConfigurationList = 140F19721A49D79500B0016A /* Build configuration list for PBXNativeTarget "KeychainAccess" */;
210 | buildPhases = (
211 | 140F19571A49D79400B0016A /* Sources */,
212 | 140F19581A49D79400B0016A /* Frameworks */,
213 | 140F19591A49D79400B0016A /* Headers */,
214 | 140F195A1A49D79400B0016A /* Resources */,
215 | );
216 | buildRules = (
217 | );
218 | dependencies = (
219 | );
220 | name = KeychainAccess;
221 | productName = KeychainAccess;
222 | productReference = 140F195C1A49D79400B0016A /* KeychainAccess.framework */;
223 | productType = "com.apple.product-type.framework";
224 | };
225 | 140F19661A49D79500B0016A /* KeychainAccessTests */ = {
226 | isa = PBXNativeTarget;
227 | buildConfigurationList = 140F19751A49D79500B0016A /* Build configuration list for PBXNativeTarget "KeychainAccessTests" */;
228 | buildPhases = (
229 | 140F19631A49D79500B0016A /* Sources */,
230 | 140F19641A49D79500B0016A /* Frameworks */,
231 | 140F19651A49D79500B0016A /* Resources */,
232 | );
233 | buildRules = (
234 | );
235 | dependencies = (
236 | 140F196A1A49D79500B0016A /* PBXTargetDependency */,
237 | 14F0C19A1D32A160007DCDDB /* PBXTargetDependency */,
238 | );
239 | name = KeychainAccessTests;
240 | productName = KeychainAccessTests;
241 | productReference = 140F19671A49D79500B0016A /* KeychainAccessTests.xctest */;
242 | productType = "com.apple.product-type.bundle.unit-test";
243 | };
244 | 14A630141D3293C700809B3F /* TestHost */ = {
245 | isa = PBXNativeTarget;
246 | buildConfigurationList = 14A630241D3293C700809B3F /* Build configuration list for PBXNativeTarget "TestHost" */;
247 | buildPhases = (
248 | 14A630111D3293C700809B3F /* Sources */,
249 | 14A630121D3293C700809B3F /* Frameworks */,
250 | 14A630131D3293C700809B3F /* Resources */,
251 | 14C3A67C1D32BF9D00349459 /* Embed Frameworks */,
252 | );
253 | buildRules = (
254 | );
255 | dependencies = (
256 | 14C3A67B1D32BF9C00349459 /* PBXTargetDependency */,
257 | );
258 | name = TestHost;
259 | productName = TestHost;
260 | productReference = 14A630151D3293C700809B3F /* TestHost.app */;
261 | productType = "com.apple.product-type.application";
262 | };
263 | /* End PBXNativeTarget section */
264 |
265 | /* Begin PBXProject section */
266 | 140F19531A49D79400B0016A /* Project object */ = {
267 | isa = PBXProject;
268 | attributes = {
269 | LastSwiftUpdateCheck = 0730;
270 | LastUpgradeCheck = 1200;
271 | ORGANIZATIONNAME = "kishikawa katsumi";
272 | TargetAttributes = {
273 | 140F195B1A49D79400B0016A = {
274 | CreatedOnToolsVersion = 6.1.1;
275 | DevelopmentTeam = 27AEDK3C9F;
276 | LastSwiftMigration = 1020;
277 | ProvisioningStyle = Automatic;
278 | };
279 | 140F19661A49D79500B0016A = {
280 | CreatedOnToolsVersion = 6.1.1;
281 | DevelopmentTeam = 27AEDK3C9F;
282 | LastSwiftMigration = 1020;
283 | ProvisioningStyle = Automatic;
284 | TestTargetID = 14A62FFC1D32922C00809B3F;
285 | };
286 | 14A630141D3293C700809B3F = {
287 | CreatedOnToolsVersion = 7.3.1;
288 | DevelopmentTeam = 27AEDK3C9F;
289 | LastSwiftMigration = 1020;
290 | SystemCapabilities = {
291 | com.apple.Keychain = {
292 | enabled = 1;
293 | };
294 | };
295 | };
296 | };
297 | };
298 | buildConfigurationList = 140F19561A49D79400B0016A /* Build configuration list for PBXProject "KeychainAccess" */;
299 | compatibilityVersion = "Xcode 3.2";
300 | developmentRegion = en;
301 | hasScannedForEncodings = 0;
302 | knownRegions = (
303 | en,
304 | Base,
305 | );
306 | mainGroup = 140F19521A49D79400B0016A;
307 | productRefGroup = 140F195D1A49D79400B0016A /* Products */;
308 | projectDirPath = "";
309 | projectRoot = "";
310 | targets = (
311 | 140F195B1A49D79400B0016A /* KeychainAccess */,
312 | 140F19661A49D79500B0016A /* KeychainAccessTests */,
313 | 14A630141D3293C700809B3F /* TestHost */,
314 | );
315 | };
316 | /* End PBXProject section */
317 |
318 | /* Begin PBXResourcesBuildPhase section */
319 | 140F195A1A49D79400B0016A /* Resources */ = {
320 | isa = PBXResourcesBuildPhase;
321 | buildActionMask = 2147483647;
322 | files = (
323 | );
324 | runOnlyForDeploymentPostprocessing = 0;
325 | };
326 | 140F19651A49D79500B0016A /* Resources */ = {
327 | isa = PBXResourcesBuildPhase;
328 | buildActionMask = 2147483647;
329 | files = (
330 | );
331 | runOnlyForDeploymentPostprocessing = 0;
332 | };
333 | 14A630131D3293C700809B3F /* Resources */ = {
334 | isa = PBXResourcesBuildPhase;
335 | buildActionMask = 2147483647;
336 | files = (
337 | 14A6301F1D3293C700809B3F /* Assets.xcassets in Resources */,
338 | );
339 | runOnlyForDeploymentPostprocessing = 0;
340 | };
341 | /* End PBXResourcesBuildPhase section */
342 |
343 | /* Begin PBXSourcesBuildPhase section */
344 | 140F19571A49D79400B0016A /* Sources */ = {
345 | isa = PBXSourcesBuildPhase;
346 | buildActionMask = 2147483647;
347 | files = (
348 | 140F197B1A49D89200B0016A /* Keychain.swift in Sources */,
349 | );
350 | runOnlyForDeploymentPostprocessing = 0;
351 | };
352 | 140F19631A49D79500B0016A /* Sources */ = {
353 | isa = PBXSourcesBuildPhase;
354 | buildActionMask = 2147483647;
355 | files = (
356 | 140F196F1A49D79500B0016A /* KeychainAccessTests.swift in Sources */,
357 | 148F9D4A1BCB4118006EDF48 /* EnumTests.swift in Sources */,
358 | 142EDA851BCB505F00A32149 /* ErrorTypeTests.swift in Sources */,
359 | 142EDB041BCBB0DD00A32149 /* SharedCredentialTests.swift in Sources */,
360 | );
361 | runOnlyForDeploymentPostprocessing = 0;
362 | };
363 | 14A630111D3293C700809B3F /* Sources */ = {
364 | isa = PBXSourcesBuildPhase;
365 | buildActionMask = 2147483647;
366 | files = (
367 | 14A630181D3293C700809B3F /* AppDelegate.swift in Sources */,
368 | );
369 | runOnlyForDeploymentPostprocessing = 0;
370 | };
371 | /* End PBXSourcesBuildPhase section */
372 |
373 | /* Begin PBXTargetDependency section */
374 | 140F196A1A49D79500B0016A /* PBXTargetDependency */ = {
375 | isa = PBXTargetDependency;
376 | target = 140F195B1A49D79400B0016A /* KeychainAccess */;
377 | targetProxy = 140F19691A49D79500B0016A /* PBXContainerItemProxy */;
378 | };
379 | 14C3A67B1D32BF9C00349459 /* PBXTargetDependency */ = {
380 | isa = PBXTargetDependency;
381 | target = 140F195B1A49D79400B0016A /* KeychainAccess */;
382 | targetProxy = 14C3A67A1D32BF9C00349459 /* PBXContainerItemProxy */;
383 | };
384 | 14F0C19A1D32A160007DCDDB /* PBXTargetDependency */ = {
385 | isa = PBXTargetDependency;
386 | target = 14A630141D3293C700809B3F /* TestHost */;
387 | targetProxy = 14F0C1991D32A160007DCDDB /* PBXContainerItemProxy */;
388 | };
389 | /* End PBXTargetDependency section */
390 |
391 | /* Begin XCBuildConfiguration section */
392 | 140F19701A49D79500B0016A /* Debug */ = {
393 | isa = XCBuildConfiguration;
394 | baseConfigurationReference = 148E44E61BF9EDCB004FFEC1 /* Debug.xcconfig */;
395 | buildSettings = {
396 | };
397 | name = Debug;
398 | };
399 | 140F19711A49D79500B0016A /* Release */ = {
400 | isa = XCBuildConfiguration;
401 | baseConfigurationReference = 148E44E71BF9EDCB004FFEC1 /* Release.xcconfig */;
402 | buildSettings = {
403 | };
404 | name = Release;
405 | };
406 | 140F19731A49D79500B0016A /* Debug */ = {
407 | isa = XCBuildConfiguration;
408 | baseConfigurationReference = 148E44EB1BF9EEB3004FFEC1 /* KeychainAccess.xcconfig */;
409 | buildSettings = {
410 | };
411 | name = Debug;
412 | };
413 | 140F19741A49D79500B0016A /* Release */ = {
414 | isa = XCBuildConfiguration;
415 | baseConfigurationReference = 148E44EB1BF9EEB3004FFEC1 /* KeychainAccess.xcconfig */;
416 | buildSettings = {
417 | };
418 | name = Release;
419 | };
420 | 140F19761A49D79500B0016A /* Debug */ = {
421 | isa = XCBuildConfiguration;
422 | baseConfigurationReference = 148E44E91BF9EDE4004FFEC1 /* Tests.xcconfig */;
423 | buildSettings = {
424 | };
425 | name = Debug;
426 | };
427 | 140F19771A49D79500B0016A /* Release */ = {
428 | isa = XCBuildConfiguration;
429 | baseConfigurationReference = 148E44E91BF9EDE4004FFEC1 /* Tests.xcconfig */;
430 | buildSettings = {
431 | };
432 | name = Release;
433 | };
434 | 14A630251D3293C700809B3F /* Debug */ = {
435 | isa = XCBuildConfiguration;
436 | baseConfigurationReference = 14F0C1981D329832007DCDDB /* TestHost.xcconfig */;
437 | buildSettings = {
438 | };
439 | name = Debug;
440 | };
441 | 14A630261D3293C700809B3F /* Release */ = {
442 | isa = XCBuildConfiguration;
443 | baseConfigurationReference = 14F0C1981D329832007DCDDB /* TestHost.xcconfig */;
444 | buildSettings = {
445 | };
446 | name = Release;
447 | };
448 | /* End XCBuildConfiguration section */
449 |
450 | /* Begin XCConfigurationList section */
451 | 140F19561A49D79400B0016A /* Build configuration list for PBXProject "KeychainAccess" */ = {
452 | isa = XCConfigurationList;
453 | buildConfigurations = (
454 | 140F19701A49D79500B0016A /* Debug */,
455 | 140F19711A49D79500B0016A /* Release */,
456 | );
457 | defaultConfigurationIsVisible = 0;
458 | defaultConfigurationName = Release;
459 | };
460 | 140F19721A49D79500B0016A /* Build configuration list for PBXNativeTarget "KeychainAccess" */ = {
461 | isa = XCConfigurationList;
462 | buildConfigurations = (
463 | 140F19731A49D79500B0016A /* Debug */,
464 | 140F19741A49D79500B0016A /* Release */,
465 | );
466 | defaultConfigurationIsVisible = 0;
467 | defaultConfigurationName = Release;
468 | };
469 | 140F19751A49D79500B0016A /* Build configuration list for PBXNativeTarget "KeychainAccessTests" */ = {
470 | isa = XCConfigurationList;
471 | buildConfigurations = (
472 | 140F19761A49D79500B0016A /* Debug */,
473 | 140F19771A49D79500B0016A /* Release */,
474 | );
475 | defaultConfigurationIsVisible = 0;
476 | defaultConfigurationName = Release;
477 | };
478 | 14A630241D3293C700809B3F /* Build configuration list for PBXNativeTarget "TestHost" */ = {
479 | isa = XCConfigurationList;
480 | buildConfigurations = (
481 | 14A630251D3293C700809B3F /* Debug */,
482 | 14A630261D3293C700809B3F /* Release */,
483 | );
484 | defaultConfigurationIsVisible = 0;
485 | defaultConfigurationName = Release;
486 | };
487 | /* End XCConfigurationList section */
488 | };
489 | rootObject = 140F19531A49D79400B0016A /* Project object */;
490 | }
491 |
--------------------------------------------------------------------------------
/Lib/KeychainAccess.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Lib/KeychainAccess.xcodeproj/xcshareddata/xcschemes/KeychainAccess.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
51 |
52 |
53 |
54 |
56 |
62 |
63 |
64 |
66 |
72 |
73 |
74 |
75 |
76 |
86 |
87 |
93 |
94 |
95 |
96 |
102 |
103 |
109 |
110 |
111 |
112 |
114 |
115 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/Lib/KeychainAccess.xcodeproj/xcshareddata/xcschemes/TestHost.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
52 |
54 |
60 |
61 |
62 |
63 |
69 |
71 |
77 |
78 |
79 |
80 |
82 |
83 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/Lib/KeychainAccess/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 4.2.2
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Lib/KeychainAccess/KeychainAccess.h:
--------------------------------------------------------------------------------
1 | //
2 | // KeychainAccess.h
3 | // KeychainAccess
4 | //
5 | // Created by kishikawa katsumi on 2014/12/24.
6 | // Copyright (c) 2014 kishikawa katsumi. All rights reserved.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy
9 | // of this software and associated documentation files (the "Software"), to deal
10 | // in the Software without restriction, including without limitation the rights
11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | // copies of the Software, and to permit persons to whom the Software is
13 | // furnished to do so, subject to the following conditions:
14 | //
15 | // The above copyright notice and this permission notice shall be included in
16 | // all copies or substantial portions of the Software.
17 | //
18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | // THE SOFTWARE.
25 |
26 | #import
27 |
28 | FOUNDATION_EXPORT double KeychainAccessVersionNumber;
29 | FOUNDATION_EXPORT const unsigned char KeychainAccessVersionString[];
30 |
--------------------------------------------------------------------------------
/Lib/KeychainAccessTests/EnumTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EnumTests.swift
3 | // KeychainAccessTests
4 | //
5 | // Created by kishikawa katsumi on 10/12/15.
6 | // Copyright © 2015 kishikawa katsumi. All rights reserved.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy
9 | // of this software and associated documentation files (the "Software"), to deal
10 | // in the Software without restriction, including without limitation the rights
11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | // copies of the Software, and to permit persons to whom the Software is
13 | // furnished to do so, subject to the following conditions:
14 | //
15 | // The above copyright notice and this permission notice shall be included in
16 | // all copies or substantial portions of the Software.
17 | //
18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | // THE SOFTWARE.
25 |
26 | import XCTest
27 | import KeychainAccess
28 |
29 | class EnumTests: XCTestCase {
30 | override func setUp() {
31 | super.setUp()
32 | }
33 |
34 | override func tearDown() {
35 | super.tearDown()
36 | }
37 |
38 | func testItemClass() {
39 | do {
40 | let itemClass = ItemClass(rawValue: kSecClassGenericPassword as String)
41 | XCTAssertEqual(itemClass, .genericPassword)
42 | XCTAssertEqual(itemClass?.description, "GenericPassword")
43 | }
44 | do {
45 | let itemClass = ItemClass(rawValue: kSecClassInternetPassword as String)
46 | XCTAssertEqual(itemClass, .internetPassword)
47 | XCTAssertEqual(itemClass?.description, "InternetPassword")
48 | }
49 | do {
50 | let itemClass = ItemClass(rawValue: kSecClassCertificate as String)
51 | XCTAssertNil(itemClass)
52 | }
53 | do {
54 | let itemClass = ItemClass(rawValue: kSecClassKey as String)
55 | XCTAssertNil(itemClass)
56 | }
57 | do {
58 | let itemClass = ItemClass(rawValue: kSecClassIdentity as String)
59 | XCTAssertNil(itemClass)
60 | }
61 | }
62 |
63 | func testProtocolType() {
64 | do {
65 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolFTP as String)
66 | XCTAssertEqual(protocolType, .ftp)
67 | XCTAssertEqual(protocolType?.description, "FTP")
68 | }
69 | do {
70 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolFTPAccount as String)
71 | XCTAssertEqual(protocolType, .ftpAccount)
72 | XCTAssertEqual(protocolType?.description, "FTPAccount")
73 | }
74 | do {
75 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolHTTP as String)
76 | XCTAssertEqual(protocolType, .http)
77 | XCTAssertEqual(protocolType?.description, "HTTP")
78 | }
79 | do {
80 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolIRC as String)
81 | XCTAssertEqual(protocolType, .irc)
82 | XCTAssertEqual(protocolType?.description, "IRC")
83 | }
84 | do {
85 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolNNTP as String)
86 | XCTAssertEqual(protocolType, .nntp)
87 | XCTAssertEqual(protocolType?.description, "NNTP")
88 | }
89 | do {
90 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolPOP3 as String)
91 | XCTAssertEqual(protocolType, .pop3)
92 | XCTAssertEqual(protocolType?.description, "POP3")
93 | }
94 | do {
95 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolSMTP as String)
96 | XCTAssertEqual(protocolType, .smtp)
97 | XCTAssertEqual(protocolType?.description, "SMTP")
98 | }
99 | do {
100 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolSOCKS as String)
101 | XCTAssertEqual(protocolType, .socks)
102 | XCTAssertEqual(protocolType?.description, "SOCKS")
103 | }
104 | do {
105 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolIMAP as String)
106 | XCTAssertEqual(protocolType, .imap)
107 | XCTAssertEqual(protocolType?.description, "IMAP")
108 | }
109 | do {
110 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolLDAP as String)
111 | XCTAssertEqual(protocolType, .ldap)
112 | XCTAssertEqual(protocolType?.description, "LDAP")
113 | }
114 | do {
115 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolAppleTalk as String)
116 | XCTAssertEqual(protocolType, .appleTalk)
117 | XCTAssertEqual(protocolType?.description, "AppleTalk")
118 | }
119 | do {
120 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolAFP as String)
121 | XCTAssertEqual(protocolType, .afp)
122 | XCTAssertEqual(protocolType?.description, "AFP")
123 | }
124 | do {
125 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolTelnet as String)
126 | XCTAssertEqual(protocolType, .telnet)
127 | XCTAssertEqual(protocolType?.description, "Telnet")
128 | }
129 | do {
130 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolSSH as String)
131 | XCTAssertEqual(protocolType, .ssh)
132 | XCTAssertEqual(protocolType?.description, "SSH")
133 | }
134 | do {
135 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolFTPS as String)
136 | XCTAssertEqual(protocolType, .ftps)
137 | XCTAssertEqual(protocolType?.description, "FTPS")
138 | }
139 | do {
140 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolHTTPS as String)
141 | XCTAssertEqual(protocolType, .https)
142 | XCTAssertEqual(protocolType?.description, "HTTPS")
143 | }
144 | do {
145 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolHTTPProxy as String)
146 | XCTAssertEqual(protocolType, .httpProxy)
147 | XCTAssertEqual(protocolType?.description, "HTTPProxy")
148 | }
149 | do {
150 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolHTTPSProxy as String)
151 | XCTAssertEqual(protocolType, .httpsProxy)
152 | XCTAssertEqual(protocolType?.description, "HTTPSProxy")
153 | }
154 | do {
155 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolFTPProxy as String)
156 | XCTAssertEqual(protocolType, .ftpProxy)
157 | XCTAssertEqual(protocolType?.description, "FTPProxy")
158 | }
159 | do {
160 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolSMB as String)
161 | XCTAssertEqual(protocolType, .smb)
162 | XCTAssertEqual(protocolType?.description, "SMB")
163 | }
164 | do {
165 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolRTSP as String)
166 | XCTAssertEqual(protocolType, .rtsp)
167 | XCTAssertEqual(protocolType?.description, "RTSP")
168 | }
169 | do {
170 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolRTSPProxy as String)
171 | XCTAssertEqual(protocolType, .rtspProxy)
172 | XCTAssertEqual(protocolType?.description, "RTSPProxy")
173 | }
174 | do {
175 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolDAAP as String)
176 | XCTAssertEqual(protocolType, .daap)
177 | XCTAssertEqual(protocolType?.description, "DAAP")
178 | }
179 | do {
180 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolEPPC as String)
181 | XCTAssertEqual(protocolType, .eppc)
182 | XCTAssertEqual(protocolType?.description, "EPPC")
183 | }
184 | do {
185 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolIPP as String)
186 | XCTAssertEqual(protocolType, .ipp)
187 | XCTAssertEqual(protocolType?.description, "IPP")
188 | }
189 | do {
190 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolNNTPS as String)
191 | XCTAssertEqual(protocolType, .nntps)
192 | XCTAssertEqual(protocolType?.description, "NNTPS")
193 | }
194 | do {
195 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolLDAPS as String)
196 | XCTAssertEqual(protocolType, .ldaps)
197 | XCTAssertEqual(protocolType?.description, "LDAPS")
198 | }
199 | do {
200 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolTelnetS as String)
201 | XCTAssertEqual(protocolType, .telnetS)
202 | XCTAssertEqual(protocolType?.description, "TelnetS")
203 | }
204 | do {
205 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolIMAPS as String)
206 | XCTAssertEqual(protocolType, .imaps)
207 | XCTAssertEqual(protocolType?.description, "IMAPS")
208 | }
209 | do {
210 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolIRCS as String)
211 | XCTAssertEqual(protocolType, .ircs)
212 | XCTAssertEqual(protocolType?.description, "IRCS")
213 | }
214 | do {
215 | let protocolType = ProtocolType(rawValue: kSecAttrProtocolPOP3S as String)
216 | XCTAssertEqual(protocolType, .pop3S)
217 | XCTAssertEqual(protocolType?.description, "POP3S")
218 | }
219 | }
220 |
221 | func testAuthenticationType() {
222 | do {
223 | let authenticationType = AuthenticationType(rawValue: kSecAttrAuthenticationTypeNTLM as String)
224 | XCTAssertEqual(authenticationType, .ntlm)
225 | XCTAssertEqual(authenticationType?.description, "NTLM")
226 | }
227 | do {
228 | let authenticationType = AuthenticationType(rawValue: kSecAttrAuthenticationTypeMSN as String)
229 | XCTAssertEqual(authenticationType, .msn)
230 | XCTAssertEqual(authenticationType?.description, "MSN")
231 | }
232 | do {
233 | let authenticationType = AuthenticationType(rawValue: kSecAttrAuthenticationTypeDPA as String)
234 | XCTAssertEqual(authenticationType, .dpa)
235 | XCTAssertEqual(authenticationType?.description, "DPA")
236 | }
237 | do {
238 | let authenticationType = AuthenticationType(rawValue: kSecAttrAuthenticationTypeRPA as String)
239 | XCTAssertEqual(authenticationType, .rpa)
240 | XCTAssertEqual(authenticationType?.description, "RPA")
241 | }
242 | do {
243 | let authenticationType = AuthenticationType(rawValue: kSecAttrAuthenticationTypeHTTPBasic as String)
244 | XCTAssertEqual(authenticationType, .httpBasic)
245 | XCTAssertEqual(authenticationType?.description, "HTTPBasic")
246 | }
247 | do {
248 | let authenticationType = AuthenticationType(rawValue: kSecAttrAuthenticationTypeHTTPDigest as String)
249 | XCTAssertEqual(authenticationType, .httpDigest)
250 | XCTAssertEqual(authenticationType?.description, "HTTPDigest")
251 | }
252 | do {
253 | let authenticationType = AuthenticationType(rawValue: kSecAttrAuthenticationTypeHTMLForm as String)
254 | XCTAssertEqual(authenticationType, .htmlForm)
255 | XCTAssertEqual(authenticationType?.description, "HTMLForm")
256 | }
257 | do {
258 | let authenticationType = AuthenticationType(rawValue: kSecAttrAuthenticationTypeDefault as String)
259 | XCTAssertEqual(authenticationType, .default)
260 | XCTAssertEqual(authenticationType?.description, "Default")
261 | }
262 | }
263 |
264 | func testAccessibility() {
265 | guard #available(macOS 10.10, *) else {
266 | return
267 | }
268 | do {
269 | let accessibility = Accessibility(rawValue: kSecAttrAccessibleWhenUnlocked as String)
270 | XCTAssertEqual(accessibility, .whenUnlocked)
271 | XCTAssertEqual(accessibility?.description, "WhenUnlocked")
272 | }
273 | do {
274 | let accessibility = Accessibility(rawValue: kSecAttrAccessibleAfterFirstUnlock as String)
275 | XCTAssertEqual(accessibility, .afterFirstUnlock)
276 | XCTAssertEqual(accessibility?.description, "AfterFirstUnlock")
277 | }
278 | #if !targetEnvironment(macCatalyst)
279 | do {
280 | let accessibility = Accessibility(rawValue: kSecAttrAccessibleAlways as String)
281 | XCTAssertEqual(accessibility, .always)
282 | XCTAssertEqual(accessibility?.description, "Always")
283 | }
284 | #endif
285 | do {
286 | let accessibility = Accessibility(rawValue: kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly as String)
287 | XCTAssertEqual(accessibility, .whenPasscodeSetThisDeviceOnly)
288 | XCTAssertEqual(accessibility?.description, "WhenPasscodeSetThisDeviceOnly")
289 | }
290 | do {
291 | let accessibility = Accessibility(rawValue: kSecAttrAccessibleWhenUnlockedThisDeviceOnly as String)
292 | XCTAssertEqual(accessibility, .whenUnlockedThisDeviceOnly)
293 | XCTAssertEqual(accessibility?.description, "WhenUnlockedThisDeviceOnly")
294 | }
295 | do {
296 | let accessibility = Accessibility(rawValue: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly as String)
297 | XCTAssertEqual(accessibility, .afterFirstUnlockThisDeviceOnly)
298 | XCTAssertEqual(accessibility?.description, "AfterFirstUnlockThisDeviceOnly")
299 | }
300 | #if !targetEnvironment(macCatalyst)
301 | do {
302 | let accessibility = Accessibility(rawValue: kSecAttrAccessibleAlwaysThisDeviceOnly as String)
303 | XCTAssertEqual(accessibility, .alwaysThisDeviceOnly)
304 | XCTAssertEqual(accessibility?.description, "AlwaysThisDeviceOnly")
305 | }
306 | #endif
307 | }
308 | }
309 |
--------------------------------------------------------------------------------
/Lib/KeychainAccessTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Lib/KeychainAccessTests/SharedCredentialTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SharedCredentialTests.swift
3 | // KeychainAccessTests
4 | //
5 | // Created by kishikawa katsumi on 10/12/15.
6 | // Copyright © 2015 kishikawa katsumi. All rights reserved.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy
9 | // of this software and associated documentation files (the "Software"), to deal
10 | // in the Software without restriction, including without limitation the rights
11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | // copies of the Software, and to permit persons to whom the Software is
13 | // furnished to do so, subject to the following conditions:
14 | //
15 | // The above copyright notice and this permission notice shall be included in
16 | // all copies or substantial portions of the Software.
17 | //
18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | // THE SOFTWARE.
25 |
26 | import XCTest
27 | import KeychainAccess
28 |
29 | class SharedCredentialTests: XCTestCase {
30 | override func setUp() {
31 | super.setUp()
32 | }
33 |
34 | override func tearDown() {
35 | super.tearDown()
36 | }
37 |
38 | func testGetSharedPassword() {
39 | do {
40 | let expectation = self.expectation(description: "getSharedPassword")
41 |
42 | let keychain = Keychain(server: "https://kishikawakatsumi.com", protocolType: .https)
43 |
44 | keychain.getSharedPassword("kishikawakatsumi") { (password, error) -> () in
45 | XCTAssertNil(password)
46 | XCTAssertNotNil(error)
47 | expectation.fulfill()
48 | }
49 |
50 | waitForExpectations(timeout: 10.0, handler: nil)
51 | }
52 | do {
53 | let expectation = self.expectation(description: "getSharedPassword")
54 |
55 | let keychain = Keychain(server: "https://kishikawakatsumi.com", protocolType: .https)
56 |
57 | keychain.getSharedPassword { (account, password, error) -> () in
58 | XCTAssertNil(account)
59 | XCTAssertNil(password)
60 | XCTAssertNotNil(error)
61 | expectation.fulfill()
62 | }
63 |
64 | waitForExpectations(timeout: 10.0, handler: nil)
65 | }
66 |
67 | }
68 |
69 | func testGeneratePassword() {
70 | do {
71 | var passwords = Set()
72 | for _ in 0...100_000 {
73 | let password = Keychain.generatePassword()
74 |
75 | #if swift(>=4.2)
76 | XCTAssertEqual(password.count, "xxx-xxx-xxx-xxx".count)
77 | #else
78 | XCTAssertEqual(password.characters.count, "xxx-xxx-xxx-xxx".characters.count)
79 | #endif
80 | XCTAssertFalse(passwords.contains(password))
81 |
82 | passwords.insert(password)
83 | }
84 | }
85 | }
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/Lib/TestHost-MacCatalyst/KeychainAccessTests-MacCatalyst/EnumTests.swift:
--------------------------------------------------------------------------------
1 | ../../KeychainAccessTests/EnumTests.swift
--------------------------------------------------------------------------------
/Lib/TestHost-MacCatalyst/KeychainAccessTests-MacCatalyst/ErrorTypeTests.swift:
--------------------------------------------------------------------------------
1 | ../../KeychainAccessTests/ErrorTypeTests.swift
--------------------------------------------------------------------------------
/Lib/TestHost-MacCatalyst/KeychainAccessTests-MacCatalyst/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Lib/TestHost-MacCatalyst/KeychainAccessTests-MacCatalyst/KeychainAccessTests.swift:
--------------------------------------------------------------------------------
1 | ../../KeychainAccessTests/KeychainAccessTests.swift
--------------------------------------------------------------------------------
/Lib/TestHost-MacCatalyst/TestHost-MacCatalyst.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 14A98C4F235D284F00BBB893 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14A98C4E235D284F00BBB893 /* AppDelegate.swift */; };
11 | 14A98C51235D284F00BBB893 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14A98C50235D284F00BBB893 /* SceneDelegate.swift */; };
12 | 14A98C53235D284F00BBB893 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14A98C52235D284F00BBB893 /* ViewController.swift */; };
13 | 14A98C56235D284F00BBB893 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 14A98C54235D284F00BBB893 /* Main.storyboard */; };
14 | 14A98C58235D285000BBB893 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 14A98C57235D285000BBB893 /* Assets.xcassets */; };
15 | 14A98C5B235D285000BBB893 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 14A98C59235D285000BBB893 /* LaunchScreen.storyboard */; };
16 | 14A98C65235D286B00BBB893 /* KeychainAccess.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 14A98C64235D286B00BBB893 /* KeychainAccess.framework */; };
17 | 14A98C66235D286B00BBB893 /* KeychainAccess.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 14A98C64235D286B00BBB893 /* KeychainAccess.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
18 | 14A98C88235D2AFA00BBB893 /* ErrorTypeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14A98C84235D2AFA00BBB893 /* ErrorTypeTests.swift */; };
19 | 14A98C8A235D2AFA00BBB893 /* KeychainAccessTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14A98C86235D2AFA00BBB893 /* KeychainAccessTests.swift */; };
20 | 14A98C8B235D2AFA00BBB893 /* EnumTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14A98C87235D2AFA00BBB893 /* EnumTests.swift */; };
21 | /* End PBXBuildFile section */
22 |
23 | /* Begin PBXContainerItemProxy section */
24 | 14A98C82235D293300BBB893 /* PBXContainerItemProxy */ = {
25 | isa = PBXContainerItemProxy;
26 | containerPortal = 14A98C43235D284F00BBB893 /* Project object */;
27 | proxyType = 1;
28 | remoteGlobalIDString = 14A98C4A235D284F00BBB893;
29 | remoteInfo = "TestHost-MacCatalyst";
30 | };
31 | /* End PBXContainerItemProxy section */
32 |
33 | /* Begin PBXCopyFilesBuildPhase section */
34 | 14A98C67235D286B00BBB893 /* Embed Frameworks */ = {
35 | isa = PBXCopyFilesBuildPhase;
36 | buildActionMask = 2147483647;
37 | dstPath = "";
38 | dstSubfolderSpec = 10;
39 | files = (
40 | 14A98C66235D286B00BBB893 /* KeychainAccess.framework in Embed Frameworks */,
41 | );
42 | name = "Embed Frameworks";
43 | runOnlyForDeploymentPostprocessing = 0;
44 | };
45 | /* End PBXCopyFilesBuildPhase section */
46 |
47 | /* Begin PBXFileReference section */
48 | 14A98C4B235D284F00BBB893 /* TestHost-MacCatalyst.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TestHost-MacCatalyst.app"; sourceTree = BUILT_PRODUCTS_DIR; };
49 | 14A98C4E235D284F00BBB893 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
50 | 14A98C50235D284F00BBB893 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
51 | 14A98C52235D284F00BBB893 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
52 | 14A98C55235D284F00BBB893 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
53 | 14A98C57235D285000BBB893 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
54 | 14A98C5A235D285000BBB893 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
55 | 14A98C5C235D285000BBB893 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
56 | 14A98C62235D286500BBB893 /* TestHost-MacCatalyst.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "TestHost-MacCatalyst.entitlements"; sourceTree = ""; };
57 | 14A98C64235D286B00BBB893 /* KeychainAccess.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = KeychainAccess.framework; sourceTree = BUILT_PRODUCTS_DIR; };
58 | 14A98C7A235D292000BBB893 /* KeychainAccessTests-MacCatalyst.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "KeychainAccessTests-MacCatalyst.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
59 | 14A98C7E235D292000BBB893 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
60 | 14A98C84235D2AFA00BBB893 /* ErrorTypeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ErrorTypeTests.swift; sourceTree = ""; };
61 | 14A98C86235D2AFA00BBB893 /* KeychainAccessTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeychainAccessTests.swift; sourceTree = ""; };
62 | 14A98C87235D2AFA00BBB893 /* EnumTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnumTests.swift; sourceTree = ""; };
63 | /* End PBXFileReference section */
64 |
65 | /* Begin PBXFrameworksBuildPhase section */
66 | 14A98C48235D284F00BBB893 /* Frameworks */ = {
67 | isa = PBXFrameworksBuildPhase;
68 | buildActionMask = 2147483647;
69 | files = (
70 | 14A98C65235D286B00BBB893 /* KeychainAccess.framework in Frameworks */,
71 | );
72 | runOnlyForDeploymentPostprocessing = 0;
73 | };
74 | 14A98C77235D292000BBB893 /* Frameworks */ = {
75 | isa = PBXFrameworksBuildPhase;
76 | buildActionMask = 2147483647;
77 | files = (
78 | );
79 | runOnlyForDeploymentPostprocessing = 0;
80 | };
81 | /* End PBXFrameworksBuildPhase section */
82 |
83 | /* Begin PBXGroup section */
84 | 14A98C42235D284F00BBB893 = {
85 | isa = PBXGroup;
86 | children = (
87 | 14A98C4D235D284F00BBB893 /* TestHost-MacCatalyst */,
88 | 14A98C7B235D292000BBB893 /* KeychainAccessTests-MacCatalyst */,
89 | 14A98C4C235D284F00BBB893 /* Products */,
90 | 14A98C63235D286B00BBB893 /* Frameworks */,
91 | );
92 | sourceTree = "";
93 | };
94 | 14A98C4C235D284F00BBB893 /* Products */ = {
95 | isa = PBXGroup;
96 | children = (
97 | 14A98C4B235D284F00BBB893 /* TestHost-MacCatalyst.app */,
98 | 14A98C7A235D292000BBB893 /* KeychainAccessTests-MacCatalyst.xctest */,
99 | );
100 | name = Products;
101 | sourceTree = "";
102 | };
103 | 14A98C4D235D284F00BBB893 /* TestHost-MacCatalyst */ = {
104 | isa = PBXGroup;
105 | children = (
106 | 14A98C4E235D284F00BBB893 /* AppDelegate.swift */,
107 | 14A98C50235D284F00BBB893 /* SceneDelegate.swift */,
108 | 14A98C52235D284F00BBB893 /* ViewController.swift */,
109 | 14A98C54235D284F00BBB893 /* Main.storyboard */,
110 | 14A98C59235D285000BBB893 /* LaunchScreen.storyboard */,
111 | 14A98C57235D285000BBB893 /* Assets.xcassets */,
112 | 14A98C5C235D285000BBB893 /* Info.plist */,
113 | 14A98C62235D286500BBB893 /* TestHost-MacCatalyst.entitlements */,
114 | );
115 | path = "TestHost-MacCatalyst";
116 | sourceTree = "";
117 | };
118 | 14A98C63235D286B00BBB893 /* Frameworks */ = {
119 | isa = PBXGroup;
120 | children = (
121 | 14A98C64235D286B00BBB893 /* KeychainAccess.framework */,
122 | );
123 | name = Frameworks;
124 | sourceTree = "";
125 | };
126 | 14A98C7B235D292000BBB893 /* KeychainAccessTests-MacCatalyst */ = {
127 | isa = PBXGroup;
128 | children = (
129 | 14A98C86235D2AFA00BBB893 /* KeychainAccessTests.swift */,
130 | 14A98C87235D2AFA00BBB893 /* EnumTests.swift */,
131 | 14A98C84235D2AFA00BBB893 /* ErrorTypeTests.swift */,
132 | 14A98C7E235D292000BBB893 /* Info.plist */,
133 | );
134 | path = "KeychainAccessTests-MacCatalyst";
135 | sourceTree = "";
136 | };
137 | /* End PBXGroup section */
138 |
139 | /* Begin PBXNativeTarget section */
140 | 14A98C4A235D284F00BBB893 /* TestHost-MacCatalyst */ = {
141 | isa = PBXNativeTarget;
142 | buildConfigurationList = 14A98C5F235D285000BBB893 /* Build configuration list for PBXNativeTarget "TestHost-MacCatalyst" */;
143 | buildPhases = (
144 | 14A98C47235D284F00BBB893 /* Sources */,
145 | 14A98C48235D284F00BBB893 /* Frameworks */,
146 | 14A98C49235D284F00BBB893 /* Resources */,
147 | 14A98C67235D286B00BBB893 /* Embed Frameworks */,
148 | );
149 | buildRules = (
150 | );
151 | dependencies = (
152 | );
153 | name = "TestHost-MacCatalyst";
154 | productName = "TestHost-MacCatalyst";
155 | productReference = 14A98C4B235D284F00BBB893 /* TestHost-MacCatalyst.app */;
156 | productType = "com.apple.product-type.application";
157 | };
158 | 14A98C79235D292000BBB893 /* KeychainAccessTests-MacCatalyst */ = {
159 | isa = PBXNativeTarget;
160 | buildConfigurationList = 14A98C7F235D292000BBB893 /* Build configuration list for PBXNativeTarget "KeychainAccessTests-MacCatalyst" */;
161 | buildPhases = (
162 | 14A98C76235D292000BBB893 /* Sources */,
163 | 14A98C77235D292000BBB893 /* Frameworks */,
164 | 14A98C78235D292000BBB893 /* Resources */,
165 | );
166 | buildRules = (
167 | );
168 | dependencies = (
169 | 14A98C83235D293300BBB893 /* PBXTargetDependency */,
170 | );
171 | name = "KeychainAccessTests-MacCatalyst";
172 | productName = "KeychainAccessTests-MacCatalyst";
173 | productReference = 14A98C7A235D292000BBB893 /* KeychainAccessTests-MacCatalyst.xctest */;
174 | productType = "com.apple.product-type.bundle.unit-test";
175 | };
176 | /* End PBXNativeTarget section */
177 |
178 | /* Begin PBXProject section */
179 | 14A98C43235D284F00BBB893 /* Project object */ = {
180 | isa = PBXProject;
181 | attributes = {
182 | LastSwiftUpdateCheck = 1100;
183 | LastUpgradeCheck = 1200;
184 | ORGANIZATIONNAME = "Kishikawa Katsumi";
185 | TargetAttributes = {
186 | 14A98C4A235D284F00BBB893 = {
187 | CreatedOnToolsVersion = 11.0;
188 | };
189 | 14A98C79235D292000BBB893 = {
190 | CreatedOnToolsVersion = 11.0;
191 | LastSwiftMigration = 1100;
192 | TestTargetID = 14A98C4A235D284F00BBB893;
193 | };
194 | };
195 | };
196 | buildConfigurationList = 14A98C46235D284F00BBB893 /* Build configuration list for PBXProject "TestHost-MacCatalyst" */;
197 | compatibilityVersion = "Xcode 9.3";
198 | developmentRegion = en;
199 | hasScannedForEncodings = 0;
200 | knownRegions = (
201 | en,
202 | Base,
203 | );
204 | mainGroup = 14A98C42235D284F00BBB893;
205 | productRefGroup = 14A98C4C235D284F00BBB893 /* Products */;
206 | projectDirPath = "";
207 | projectRoot = "";
208 | targets = (
209 | 14A98C4A235D284F00BBB893 /* TestHost-MacCatalyst */,
210 | 14A98C79235D292000BBB893 /* KeychainAccessTests-MacCatalyst */,
211 | );
212 | };
213 | /* End PBXProject section */
214 |
215 | /* Begin PBXResourcesBuildPhase section */
216 | 14A98C49235D284F00BBB893 /* Resources */ = {
217 | isa = PBXResourcesBuildPhase;
218 | buildActionMask = 2147483647;
219 | files = (
220 | 14A98C5B235D285000BBB893 /* LaunchScreen.storyboard in Resources */,
221 | 14A98C58235D285000BBB893 /* Assets.xcassets in Resources */,
222 | 14A98C56235D284F00BBB893 /* Main.storyboard in Resources */,
223 | );
224 | runOnlyForDeploymentPostprocessing = 0;
225 | };
226 | 14A98C78235D292000BBB893 /* Resources */ = {
227 | isa = PBXResourcesBuildPhase;
228 | buildActionMask = 2147483647;
229 | files = (
230 | );
231 | runOnlyForDeploymentPostprocessing = 0;
232 | };
233 | /* End PBXResourcesBuildPhase section */
234 |
235 | /* Begin PBXSourcesBuildPhase section */
236 | 14A98C47235D284F00BBB893 /* Sources */ = {
237 | isa = PBXSourcesBuildPhase;
238 | buildActionMask = 2147483647;
239 | files = (
240 | 14A98C53235D284F00BBB893 /* ViewController.swift in Sources */,
241 | 14A98C4F235D284F00BBB893 /* AppDelegate.swift in Sources */,
242 | 14A98C51235D284F00BBB893 /* SceneDelegate.swift in Sources */,
243 | );
244 | runOnlyForDeploymentPostprocessing = 0;
245 | };
246 | 14A98C76235D292000BBB893 /* Sources */ = {
247 | isa = PBXSourcesBuildPhase;
248 | buildActionMask = 2147483647;
249 | files = (
250 | 14A98C88235D2AFA00BBB893 /* ErrorTypeTests.swift in Sources */,
251 | 14A98C8B235D2AFA00BBB893 /* EnumTests.swift in Sources */,
252 | 14A98C8A235D2AFA00BBB893 /* KeychainAccessTests.swift in Sources */,
253 | );
254 | runOnlyForDeploymentPostprocessing = 0;
255 | };
256 | /* End PBXSourcesBuildPhase section */
257 |
258 | /* Begin PBXTargetDependency section */
259 | 14A98C83235D293300BBB893 /* PBXTargetDependency */ = {
260 | isa = PBXTargetDependency;
261 | target = 14A98C4A235D284F00BBB893 /* TestHost-MacCatalyst */;
262 | targetProxy = 14A98C82235D293300BBB893 /* PBXContainerItemProxy */;
263 | };
264 | /* End PBXTargetDependency section */
265 |
266 | /* Begin PBXVariantGroup section */
267 | 14A98C54235D284F00BBB893 /* Main.storyboard */ = {
268 | isa = PBXVariantGroup;
269 | children = (
270 | 14A98C55235D284F00BBB893 /* Base */,
271 | );
272 | name = Main.storyboard;
273 | sourceTree = "";
274 | };
275 | 14A98C59235D285000BBB893 /* LaunchScreen.storyboard */ = {
276 | isa = PBXVariantGroup;
277 | children = (
278 | 14A98C5A235D285000BBB893 /* Base */,
279 | );
280 | name = LaunchScreen.storyboard;
281 | sourceTree = "";
282 | };
283 | /* End PBXVariantGroup section */
284 |
285 | /* Begin XCBuildConfiguration section */
286 | 14A98C5D235D285000BBB893 /* Debug */ = {
287 | isa = XCBuildConfiguration;
288 | buildSettings = {
289 | ALWAYS_SEARCH_USER_PATHS = NO;
290 | CLANG_ANALYZER_NONNULL = YES;
291 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
292 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
293 | CLANG_CXX_LIBRARY = "libc++";
294 | CLANG_ENABLE_MODULES = YES;
295 | CLANG_ENABLE_OBJC_ARC = YES;
296 | CLANG_ENABLE_OBJC_WEAK = YES;
297 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
298 | CLANG_WARN_BOOL_CONVERSION = YES;
299 | CLANG_WARN_COMMA = YES;
300 | CLANG_WARN_CONSTANT_CONVERSION = YES;
301 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
302 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
303 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
304 | CLANG_WARN_EMPTY_BODY = YES;
305 | CLANG_WARN_ENUM_CONVERSION = YES;
306 | CLANG_WARN_INFINITE_RECURSION = YES;
307 | CLANG_WARN_INT_CONVERSION = YES;
308 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
309 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
310 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
311 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
312 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
313 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
314 | CLANG_WARN_STRICT_PROTOTYPES = YES;
315 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
316 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
317 | CLANG_WARN_UNREACHABLE_CODE = YES;
318 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
319 | COPY_PHASE_STRIP = NO;
320 | DEBUG_INFORMATION_FORMAT = dwarf;
321 | ENABLE_STRICT_OBJC_MSGSEND = YES;
322 | ENABLE_TESTABILITY = YES;
323 | GCC_C_LANGUAGE_STANDARD = gnu11;
324 | GCC_DYNAMIC_NO_PIC = NO;
325 | GCC_NO_COMMON_BLOCKS = YES;
326 | GCC_OPTIMIZATION_LEVEL = 0;
327 | GCC_PREPROCESSOR_DEFINITIONS = (
328 | "DEBUG=1",
329 | "$(inherited)",
330 | );
331 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
332 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
333 | GCC_WARN_UNDECLARED_SELECTOR = YES;
334 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
335 | GCC_WARN_UNUSED_FUNCTION = YES;
336 | GCC_WARN_UNUSED_VARIABLE = YES;
337 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
338 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
339 | MTL_FAST_MATH = YES;
340 | ONLY_ACTIVE_ARCH = YES;
341 | SDKROOT = iphoneos;
342 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
343 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
344 | };
345 | name = Debug;
346 | };
347 | 14A98C5E235D285000BBB893 /* Release */ = {
348 | isa = XCBuildConfiguration;
349 | buildSettings = {
350 | ALWAYS_SEARCH_USER_PATHS = NO;
351 | CLANG_ANALYZER_NONNULL = YES;
352 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
353 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
354 | CLANG_CXX_LIBRARY = "libc++";
355 | CLANG_ENABLE_MODULES = YES;
356 | CLANG_ENABLE_OBJC_ARC = YES;
357 | CLANG_ENABLE_OBJC_WEAK = YES;
358 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
359 | CLANG_WARN_BOOL_CONVERSION = YES;
360 | CLANG_WARN_COMMA = YES;
361 | CLANG_WARN_CONSTANT_CONVERSION = YES;
362 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
363 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
364 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
365 | CLANG_WARN_EMPTY_BODY = YES;
366 | CLANG_WARN_ENUM_CONVERSION = YES;
367 | CLANG_WARN_INFINITE_RECURSION = YES;
368 | CLANG_WARN_INT_CONVERSION = YES;
369 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
370 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
371 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
372 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
373 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
374 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
375 | CLANG_WARN_STRICT_PROTOTYPES = YES;
376 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
377 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
378 | CLANG_WARN_UNREACHABLE_CODE = YES;
379 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
380 | COPY_PHASE_STRIP = NO;
381 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
382 | ENABLE_NS_ASSERTIONS = NO;
383 | ENABLE_STRICT_OBJC_MSGSEND = YES;
384 | GCC_C_LANGUAGE_STANDARD = gnu11;
385 | GCC_NO_COMMON_BLOCKS = YES;
386 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
387 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
388 | GCC_WARN_UNDECLARED_SELECTOR = YES;
389 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
390 | GCC_WARN_UNUSED_FUNCTION = YES;
391 | GCC_WARN_UNUSED_VARIABLE = YES;
392 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
393 | MTL_ENABLE_DEBUG_INFO = NO;
394 | MTL_FAST_MATH = YES;
395 | SDKROOT = iphoneos;
396 | SWIFT_COMPILATION_MODE = wholemodule;
397 | SWIFT_OPTIMIZATION_LEVEL = "-O";
398 | VALIDATE_PRODUCT = YES;
399 | };
400 | name = Release;
401 | };
402 | 14A98C60235D285000BBB893 /* Debug */ = {
403 | isa = XCBuildConfiguration;
404 | buildSettings = {
405 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
406 | CODE_SIGN_ENTITLEMENTS = "TestHost-MacCatalyst/TestHost-MacCatalyst.entitlements";
407 | CODE_SIGN_STYLE = Automatic;
408 | DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = YES;
409 | DEVELOPMENT_TEAM = 27AEDK3C9F;
410 | INFOPLIST_FILE = "TestHost-MacCatalyst/Info.plist";
411 | LD_RUNPATH_SEARCH_PATHS = (
412 | "$(inherited)",
413 | "@executable_path/Frameworks",
414 | );
415 | PRODUCT_BUNDLE_IDENTIFIER = "com.kishikawakatsumi.KeychainAccess.TestHost-MacCatalyst";
416 | PRODUCT_NAME = "$(TARGET_NAME)";
417 | SUPPORTS_MACCATALYST = YES;
418 | SWIFT_VERSION = 5.0;
419 | TARGETED_DEVICE_FAMILY = "1,2";
420 | };
421 | name = Debug;
422 | };
423 | 14A98C61235D285000BBB893 /* Release */ = {
424 | isa = XCBuildConfiguration;
425 | buildSettings = {
426 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
427 | CODE_SIGN_ENTITLEMENTS = "TestHost-MacCatalyst/TestHost-MacCatalyst.entitlements";
428 | CODE_SIGN_STYLE = Automatic;
429 | DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = YES;
430 | DEVELOPMENT_TEAM = 27AEDK3C9F;
431 | INFOPLIST_FILE = "TestHost-MacCatalyst/Info.plist";
432 | LD_RUNPATH_SEARCH_PATHS = (
433 | "$(inherited)",
434 | "@executable_path/Frameworks",
435 | );
436 | PRODUCT_BUNDLE_IDENTIFIER = "com.kishikawakatsumi.KeychainAccess.TestHost-MacCatalyst";
437 | PRODUCT_NAME = "$(TARGET_NAME)";
438 | SUPPORTS_MACCATALYST = YES;
439 | SWIFT_VERSION = 5.0;
440 | TARGETED_DEVICE_FAMILY = "1,2";
441 | };
442 | name = Release;
443 | };
444 | 14A98C80235D292000BBB893 /* Debug */ = {
445 | isa = XCBuildConfiguration;
446 | buildSettings = {
447 | CLANG_ENABLE_MODULES = YES;
448 | CODE_SIGN_STYLE = Automatic;
449 | DEVELOPMENT_TEAM = 27AEDK3C9F;
450 | INFOPLIST_FILE = "KeychainAccessTests-MacCatalyst/Info.plist";
451 | LD_RUNPATH_SEARCH_PATHS = (
452 | "$(inherited)",
453 | "@executable_path/Frameworks",
454 | "@loader_path/Frameworks",
455 | );
456 | PRODUCT_BUNDLE_IDENTIFIER = "com.kishikawakatsumi.KeychainAccessTests-MacCatalyst";
457 | PRODUCT_NAME = "$(TARGET_NAME)";
458 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
459 | SWIFT_VERSION = 5.0;
460 | TARGETED_DEVICE_FAMILY = "1,2";
461 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TestHost-MacCatalyst.app/TestHost-MacCatalyst";
462 | };
463 | name = Debug;
464 | };
465 | 14A98C81235D292000BBB893 /* Release */ = {
466 | isa = XCBuildConfiguration;
467 | buildSettings = {
468 | CLANG_ENABLE_MODULES = YES;
469 | CODE_SIGN_STYLE = Automatic;
470 | DEVELOPMENT_TEAM = 27AEDK3C9F;
471 | INFOPLIST_FILE = "KeychainAccessTests-MacCatalyst/Info.plist";
472 | LD_RUNPATH_SEARCH_PATHS = (
473 | "$(inherited)",
474 | "@executable_path/Frameworks",
475 | "@loader_path/Frameworks",
476 | );
477 | PRODUCT_BUNDLE_IDENTIFIER = "com.kishikawakatsumi.KeychainAccessTests-MacCatalyst";
478 | PRODUCT_NAME = "$(TARGET_NAME)";
479 | SWIFT_VERSION = 5.0;
480 | TARGETED_DEVICE_FAMILY = "1,2";
481 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TestHost-MacCatalyst.app/TestHost-MacCatalyst";
482 | };
483 | name = Release;
484 | };
485 | /* End XCBuildConfiguration section */
486 |
487 | /* Begin XCConfigurationList section */
488 | 14A98C46235D284F00BBB893 /* Build configuration list for PBXProject "TestHost-MacCatalyst" */ = {
489 | isa = XCConfigurationList;
490 | buildConfigurations = (
491 | 14A98C5D235D285000BBB893 /* Debug */,
492 | 14A98C5E235D285000BBB893 /* Release */,
493 | );
494 | defaultConfigurationIsVisible = 0;
495 | defaultConfigurationName = Release;
496 | };
497 | 14A98C5F235D285000BBB893 /* Build configuration list for PBXNativeTarget "TestHost-MacCatalyst" */ = {
498 | isa = XCConfigurationList;
499 | buildConfigurations = (
500 | 14A98C60235D285000BBB893 /* Debug */,
501 | 14A98C61235D285000BBB893 /* Release */,
502 | );
503 | defaultConfigurationIsVisible = 0;
504 | defaultConfigurationName = Release;
505 | };
506 | 14A98C7F235D292000BBB893 /* Build configuration list for PBXNativeTarget "KeychainAccessTests-MacCatalyst" */ = {
507 | isa = XCConfigurationList;
508 | buildConfigurations = (
509 | 14A98C80235D292000BBB893 /* Debug */,
510 | 14A98C81235D292000BBB893 /* Release */,
511 | );
512 | defaultConfigurationIsVisible = 0;
513 | defaultConfigurationName = Release;
514 | };
515 | /* End XCConfigurationList section */
516 | };
517 | rootObject = 14A98C43235D284F00BBB893 /* Project object */;
518 | }
519 |
--------------------------------------------------------------------------------
/Lib/TestHost-MacCatalyst/TestHost-MacCatalyst.xcodeproj/xcshareddata/xcschemes/TestHost-MacCatalyst.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
60 |
62 |
68 |
69 |
70 |
71 |
73 |
74 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/Lib/TestHost-MacCatalyst/TestHost-MacCatalyst/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // TestHost-MacCatalyst
4 | //
5 | // Created by Kishikawa Katsumi on 2019/10/21.
6 | // Copyright © 2019 Kishikawa Katsumi. All rights reserved.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy
9 | // of this software and associated documentation files (the "Software"), to deal
10 | // in the Software without restriction, including without limitation the rights
11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | // copies of the Software, and to permit persons to whom the Software is
13 | // furnished to do so, subject to the following conditions:
14 | //
15 | // The above copyright notice and this permission notice shall be included in
16 | // all copies or substantial portions of the Software.
17 | //
18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | // THE SOFTWARE.
25 |
26 | import UIKit
27 |
28 | @UIApplicationMain
29 | class AppDelegate: UIResponder, UIApplicationDelegate {
30 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
31 | return true
32 | }
33 |
34 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
35 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Lib/TestHost-MacCatalyst/TestHost-MacCatalyst/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Lib/TestHost-MacCatalyst/TestHost-MacCatalyst/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Lib/TestHost-MacCatalyst/TestHost-MacCatalyst/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Lib/TestHost-MacCatalyst/TestHost-MacCatalyst/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Lib/TestHost-MacCatalyst/TestHost-MacCatalyst/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 | UISceneStoryboardFile
37 | Main
38 |
39 |
40 |
41 |
42 | UILaunchStoryboardName
43 | LaunchScreen
44 | UIMainStoryboardFile
45 | Main
46 | UIRequiredDeviceCapabilities
47 |
48 | armv7
49 |
50 | UISupportedInterfaceOrientations
51 |
52 | UIInterfaceOrientationPortrait
53 | UIInterfaceOrientationLandscapeLeft
54 | UIInterfaceOrientationLandscapeRight
55 |
56 | UISupportedInterfaceOrientations~ipad
57 |
58 | UIInterfaceOrientationPortrait
59 | UIInterfaceOrientationPortraitUpsideDown
60 | UIInterfaceOrientationLandscapeLeft
61 | UIInterfaceOrientationLandscapeRight
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/Lib/TestHost-MacCatalyst/TestHost-MacCatalyst/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // TestHost-MacCatalyst
4 | //
5 | // Created by Kishikawa Katsumi on 2019/10/21.
6 | // Copyright © 2019 Kishikawa Katsumi. All rights reserved.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy
9 | // of this software and associated documentation files (the "Software"), to deal
10 | // in the Software without restriction, including without limitation the rights
11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | // copies of the Software, and to permit persons to whom the Software is
13 | // furnished to do so, subject to the following conditions:
14 | //
15 | // The above copyright notice and this permission notice shall be included in
16 | // all copies or substantial portions of the Software.
17 | //
18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | // THE SOFTWARE.
25 |
26 | import UIKit
27 |
28 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
29 | var window: UIWindow?
30 | }
31 |
--------------------------------------------------------------------------------
/Lib/TestHost-MacCatalyst/TestHost-MacCatalyst/TestHost-MacCatalyst.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.network.client
8 |
9 | keychain-access-groups
10 |
11 | $(AppIdentifierPrefix)com.kishikawakatsumi.KeychainAccess.TestHost-MacCatalyst
12 | $(AppIdentifierPrefix)shared
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Lib/TestHost-MacCatalyst/TestHost-MacCatalyst/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // TestHost-MacCatalyst
4 | //
5 | // Created by Kishikawa Katsumi on 2019/10/21.
6 | // Copyright © 2019 Kishikawa Katsumi. All rights reserved.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy
9 | // of this software and associated documentation files (the "Software"), to deal
10 | // in the Software without restriction, including without limitation the rights
11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | // copies of the Software, and to permit persons to whom the Software is
13 | // furnished to do so, subject to the following conditions:
14 | //
15 | // The above copyright notice and this permission notice shall be included in
16 | // all copies or substantial portions of the Software.
17 | //
18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | // THE SOFTWARE.
25 |
26 | import UIKit
27 |
28 | class ViewController: UIViewController {
29 | override func viewDidLoad() {
30 | super.viewDidLoad()
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Lib/TestHost/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // TestHost
4 | //
5 | // Created by kishikawa katsumi on 7/10/16.
6 | // Copyright © 2016 kishikawa katsumi. All rights reserved.
7 | //
8 | // Permission is hereby granted, free of charge, to any person obtaining a copy
9 | // of this software and associated documentation files (the "Software"), to deal
10 | // in the Software without restriction, including without limitation the rights
11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | // copies of the Software, and to permit persons to whom the Software is
13 | // furnished to do so, subject to the following conditions:
14 | //
15 | // The above copyright notice and this permission notice shall be included in
16 | // all copies or substantial portions of the Software.
17 | //
18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | // THE SOFTWARE.
25 |
26 | #if os(macOS)
27 | import Cocoa
28 |
29 | @NSApplicationMain
30 | class AppDelegate: NSObject, NSApplicationDelegate {
31 | @IBOutlet weak var window: NSWindow!
32 | func applicationDidFinishLaunching(aNotification: NSNotification) {}
33 | }
34 | #else
35 | import UIKit
36 |
37 | @UIApplicationMain
38 | class AppDelegate: UIResponder, UIApplicationDelegate {
39 | var window: UIWindow?
40 |
41 | #if swift(>=4.2)
42 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
43 | return true
44 | }
45 | #else
46 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
47 | return true
48 | }
49 | #endif
50 | }
51 | #endif
52 |
--------------------------------------------------------------------------------
/Lib/TestHost/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | }
88 | ],
89 | "info" : {
90 | "version" : 1,
91 | "author" : "xcode"
92 | }
93 | }
--------------------------------------------------------------------------------
/Lib/TestHost/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UIRequiredDeviceCapabilities
26 |
27 | armv7
28 |
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIRequiresFullScreen
43 |
44 | NSPrincipalClass
45 | $(PRINCIPAL_CLASS)
46 |
47 |
48 |
--------------------------------------------------------------------------------
/Lib/TestHost/TestHost.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | keychain-access-groups
6 |
7 | $(AppIdentifierPrefix)com.kishikawakatsumi.KeychainAccess.TestHost
8 | $(AppIdentifierPrefix)shared
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.0
2 |
3 | // Package.swift
4 | // KeychainAccess
5 | //
6 | // Created by kishikawa katsumi on 2015/12/4.
7 | // Copyright (c) 2015 kishikawa katsumi. All rights reserved.
8 | //
9 |
10 | import PackageDescription
11 |
12 | let package = Package(
13 | name: "KeychainAccess",
14 | platforms: [
15 | .macOS(.v10_10), .iOS(.v8), .tvOS(.v9), .watchOS(.v2)
16 | ],
17 | products: [
18 | .library(name: "KeychainAccess", targets: ["KeychainAccess"])
19 | ],
20 | targets: [
21 | .target(
22 | name: "KeychainAccess",
23 | path: "Lib/KeychainAccess",
24 | linkerSettings: [.unsafeFlags(["-Xlinker", "-no_application_extension"])])
25 | ]
26 | )
27 |
--------------------------------------------------------------------------------
/Package@swift-5.3.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.3
2 |
3 | // Package.swift
4 | // KeychainAccess
5 | //
6 | // Created by kishikawa katsumi on 2015/12/4.
7 | // Copyright (c) 2015 kishikawa katsumi. All rights reserved.
8 | //
9 |
10 | import PackageDescription
11 |
12 | let package = Package(
13 | name: "KeychainAccess",
14 | platforms: [
15 | .macOS(.v10_10), .iOS(.v9), .tvOS(.v9), .watchOS(.v2)
16 | ],
17 | products: [
18 | .library(name: "KeychainAccess", targets: ["KeychainAccess"])
19 | ],
20 | targets: [
21 | .target(
22 | name: "KeychainAccess",
23 | path: "Lib/KeychainAccess",
24 | exclude: ["Info.plist"],
25 | linkerSettings: [.unsafeFlags(["-Xlinker", "-no_application_extension"])]
26 | )
27 | ]
28 | )
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # KeychainAccess
2 |
3 | [](https://travis-ci.com/kishikawakatsumi/KeychainAccess)
4 | [](https://github.com/Carthage/Carthage)
5 | [](https://swift.org/package-manager)
6 | [](http://cocoadocs.org/docsets/KeychainAccess)
7 | [](http://cocoadocs.org/docsets/KeychainAccess)
8 |
9 | KeychainAccess is a simple Swift wrapper for Keychain that works on iOS and macOS. Makes using Keychain APIs extremely easy and much more palatable to use in Swift.
10 |
11 |
12 |
13 |
14 | ## :bulb: Features
15 |
16 | - Simple interface
17 | - Support access group
18 | - [Support accessibility](#accessibility)
19 | - [Support iCloud sharing](#icloud_sharing)
20 | - **[Support TouchID and Keychain integration (iOS 8+)](#touch_id_integration)**
21 | - **[Support Shared Web Credentials (iOS 8+)](#shared_web_credentials)**
22 | - [Works on both iOS & macOS](#requirements)
23 | - [watchOS and tvOS are supported](#requirements)
24 | - **[Mac Catalyst is supported](#requirements)**
25 | - **[Swift 3, 4 and 5 compatible](#requirements)**
26 |
27 | ## :book: Usage
28 |
29 | ##### :eyes: See also:
30 |
31 | - [:link: iOS Example Project](https://github.com/kishikawakatsumi/KeychainAccess/tree/master/Examples/Example-iOS)
32 |
33 | ### :key: Basics
34 |
35 | #### Saving Application Password
36 |
37 | ```swift
38 | let keychain = Keychain(service: "com.example.github-token")
39 | keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef"
40 | ```
41 |
42 | #### Saving Internet Password
43 |
44 | ```swift
45 | let keychain = Keychain(server: "https://github.com", protocolType: .https)
46 | keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef"
47 | ```
48 |
49 | ### :key: Instantiation
50 |
51 | #### Create Keychain for Application Password
52 |
53 | ```swift
54 | let keychain = Keychain(service: "com.example.github-token")
55 | ```
56 |
57 | ```swift
58 | let keychain = Keychain(service: "com.example.github-token", accessGroup: "12ABCD3E4F.shared")
59 | ```
60 |
61 | #### Create Keychain for Internet Password
62 |
63 | ```swift
64 | let keychain = Keychain(server: "https://github.com", protocolType: .https)
65 | ```
66 |
67 | ```swift
68 | let keychain = Keychain(server: "https://github.com", protocolType: .https, authenticationType: .htmlForm)
69 | ```
70 |
71 | ### :key: Adding an item
72 |
73 | #### subscripting
74 |
75 | ##### for String
76 |
77 | ```swift
78 | keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef"
79 | ```
80 |
81 | ```swift
82 | keychain[string: "kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef"
83 | ```
84 |
85 | ##### for NSData
86 |
87 | ```swift
88 | keychain[data: "secret"] = NSData(contentsOfFile: "secret.bin")
89 | ```
90 |
91 | #### set method
92 |
93 | ```swift
94 | keychain.set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi")
95 | ```
96 |
97 | #### error handling
98 |
99 | ```swift
100 | do {
101 | try keychain.set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi")
102 | }
103 | catch let error {
104 | print(error)
105 | }
106 | ```
107 |
108 | ### :key: Obtaining an item
109 |
110 | #### subscripting
111 |
112 | ##### for String (If the value is NSData, attempt to convert to String)
113 |
114 | ```swift
115 | let token = keychain["kishikawakatsumi"]
116 | ```
117 |
118 | ```swift
119 | let token = keychain[string: "kishikawakatsumi"]
120 | ```
121 |
122 | ##### for NSData
123 |
124 | ```swift
125 | let secretData = keychain[data: "secret"]
126 | ```
127 |
128 | #### get methods
129 |
130 | ##### as String
131 |
132 | ```swift
133 | let token = try? keychain.get("kishikawakatsumi")
134 | ```
135 |
136 | ```swift
137 | let token = try? keychain.getString("kishikawakatsumi")
138 | ```
139 |
140 | ##### as NSData
141 |
142 | ```swift
143 | let data = try? keychain.getData("kishikawakatsumi")
144 | ```
145 |
146 | ### :key: Removing an item
147 |
148 | #### subscripting
149 |
150 | ```swift
151 | keychain["kishikawakatsumi"] = nil
152 | ```
153 |
154 | #### remove method
155 |
156 | ```swift
157 | do {
158 | try keychain.remove("kishikawakatsumi")
159 | } catch let error {
160 | print("error: \(error)")
161 | }
162 | ```
163 |
164 | ### :key: Set Label and Comment
165 |
166 | ```swift
167 | let keychain = Keychain(server: "https://github.com", protocolType: .https)
168 | do {
169 | try keychain
170 | .label("github.com (kishikawakatsumi)")
171 | .comment("github access token")
172 | .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi")
173 | } catch let error {
174 | print("error: \(error)")
175 | }
176 | ```
177 |
178 | ### :key: Obtaining Other Attributes
179 |
180 | #### PersistentRef
181 |
182 | ```swift
183 | let keychain = Keychain()
184 | let persistentRef = keychain[attributes: "kishikawakatsumi"]?.persistentRef
185 | ...
186 | ```
187 |
188 | #### Creation Date
189 |
190 | ```swift
191 | let keychain = Keychain()
192 | let creationDate = keychain[attributes: "kishikawakatsumi"]?.creationDate
193 | ...
194 | ```
195 |
196 | #### All Attributes
197 |
198 | ```swift
199 | let keychain = Keychain()
200 | do {
201 | let attributes = try keychain.get("kishikawakatsumi") { $0 }
202 | print(attributes?.comment)
203 | print(attributes?.label)
204 | print(attributes?.creator)
205 | ...
206 | } catch let error {
207 | print("error: \(error)")
208 | }
209 | ```
210 |
211 | ##### subscripting
212 |
213 | ```swift
214 | let keychain = Keychain()
215 | if let attributes = keychain[attributes: "kishikawakatsumi"] {
216 | print(attributes.comment)
217 | print(attributes.label)
218 | print(attributes.creator)
219 | }
220 | ```
221 |
222 | ### :key: Configuration (Accessibility, Sharing, iCloud Sync)
223 |
224 | **Provides fluent interfaces**
225 |
226 | ```swift
227 | let keychain = Keychain(service: "com.example.github-token")
228 | .label("github.com (kishikawakatsumi)")
229 | .synchronizable(true)
230 | .accessibility(.afterFirstUnlock)
231 | ```
232 |
233 | #### Accessibility
234 |
235 | ##### Default accessibility matches background application (=kSecAttrAccessibleAfterFirstUnlock)
236 |
237 | ```swift
238 | let keychain = Keychain(service: "com.example.github-token")
239 | ```
240 |
241 | ##### For background application
242 |
243 | ###### Creating instance
244 |
245 | ```swift
246 | let keychain = Keychain(service: "com.example.github-token")
247 | .accessibility(.afterFirstUnlock)
248 |
249 | keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef"
250 | ```
251 |
252 | ###### One-shot
253 |
254 | ```swift
255 | let keychain = Keychain(service: "com.example.github-token")
256 |
257 | do {
258 | try keychain
259 | .accessibility(.afterFirstUnlock)
260 | .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi")
261 | } catch let error {
262 | print("error: \(error)")
263 | }
264 | ```
265 |
266 | ##### For foreground application
267 |
268 | ###### Creating instance
269 |
270 | ```swift
271 | let keychain = Keychain(service: "com.example.github-token")
272 | .accessibility(.whenUnlocked)
273 |
274 | keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef"
275 | ```
276 |
277 | ###### One-shot
278 |
279 | ```swift
280 | let keychain = Keychain(service: "com.example.github-token")
281 |
282 | do {
283 | try keychain
284 | .accessibility(.whenUnlocked)
285 | .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi")
286 | } catch let error {
287 | print("error: \(error)")
288 | }
289 | ```
290 |
291 | #### :couple: Sharing Keychain items
292 |
293 | ```swift
294 | let keychain = Keychain(service: "com.example.github-token", accessGroup: "12ABCD3E4F.shared")
295 | ```
296 |
297 | #### :arrows_counterclockwise: Synchronizing Keychain items with iCloud
298 |
299 | ###### Creating instance
300 |
301 | ```swift
302 | let keychain = Keychain(service: "com.example.github-token")
303 | .synchronizable(true)
304 |
305 | keychain["kishikawakatsumi"] = "01234567-89ab-cdef-0123-456789abcdef"
306 | ```
307 |
308 | ###### One-shot
309 |
310 | ```swift
311 | let keychain = Keychain(service: "com.example.github-token")
312 |
313 | do {
314 | try keychain
315 | .synchronizable(true)
316 | .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi")
317 | } catch let error {
318 | print("error: \(error)")
319 | }
320 | ```
321 |
322 | ### :cyclone: Touch ID (Face ID) integration
323 |
324 | **Any Operation that require authentication must be run in the background thread.**
325 | **If you run in the main thread, UI thread will lock for the system to try to display the authentication dialog.**
326 |
327 | **To use Face ID, add `NSFaceIDUsageDescription` key to your `Info.plist`**
328 |
329 | #### :closed_lock_with_key: Adding a Touch ID (Face ID) protected item
330 |
331 | If you want to store the Touch ID protected Keychain item, specify `accessibility` and `authenticationPolicy` attributes.
332 |
333 | ```swift
334 | let keychain = Keychain(service: "com.example.github-token")
335 |
336 | DispatchQueue.global().async {
337 | do {
338 | // Should be the secret invalidated when passcode is removed? If not then use `.WhenUnlocked`
339 | try keychain
340 | .accessibility(.whenPasscodeSetThisDeviceOnly, authenticationPolicy: [.biometryAny])
341 | .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi")
342 | } catch let error {
343 | // Error handling if needed...
344 | }
345 | }
346 | ```
347 |
348 | #### :closed_lock_with_key: Updating a Touch ID (Face ID) protected item
349 |
350 | The same way as when adding.
351 |
352 | **Do not run in the main thread if there is a possibility that the item you are trying to add already exists, and protected.**
353 | **Because updating protected items requires authentication.**
354 |
355 | Additionally, you want to show custom authentication prompt message when updating, specify an `authenticationPrompt` attribute.
356 | If the item not protected, the `authenticationPrompt` parameter just be ignored.
357 |
358 | ```swift
359 | let keychain = Keychain(service: "com.example.github-token")
360 |
361 | DispatchQueue.global().async {
362 | do {
363 | // Should be the secret invalidated when passcode is removed? If not then use `.WhenUnlocked`
364 | try keychain
365 | .accessibility(.whenPasscodeSetThisDeviceOnly, authenticationPolicy: [.biometryAny])
366 | .authenticationPrompt("Authenticate to update your access token")
367 | .set("01234567-89ab-cdef-0123-456789abcdef", key: "kishikawakatsumi")
368 | } catch let error {
369 | // Error handling if needed...
370 | }
371 | }
372 | ```
373 |
374 | #### :closed_lock_with_key: Obtaining a Touch ID (Face ID) protected item
375 |
376 | The same way as when you get a normal item. It will be displayed automatically Touch ID or passcode authentication If the item you try to get is protected.
377 | If you want to show custom authentication prompt message, specify an `authenticationPrompt` attribute.
378 | If the item not protected, the `authenticationPrompt` parameter just be ignored.
379 |
380 | ```swift
381 | let keychain = Keychain(service: "com.example.github-token")
382 |
383 | DispatchQueue.global().async {
384 | do {
385 | let password = try keychain
386 | .authenticationPrompt("Authenticate to login to server")
387 | .get("kishikawakatsumi")
388 |
389 | print("password: \(password)")
390 | } catch let error {
391 | // Error handling if needed...
392 | }
393 | }
394 | ```
395 |
396 | #### :closed_lock_with_key: Removing a Touch ID (Face ID) protected item
397 |
398 | The same way as when you remove a normal item.
399 | There is no way to show Touch ID or passcode authentication when removing Keychain items.
400 |
401 | ```swift
402 | let keychain = Keychain(service: "com.example.github-token")
403 |
404 | do {
405 | try keychain.remove("kishikawakatsumi")
406 | } catch let error {
407 | // Error handling if needed...
408 | }
409 | ```
410 |
411 | ### :key: Shared Web Credentials
412 |
413 | > Shared web credentials is a programming interface that enables native iOS apps to share credentials with their website counterparts. For example, a user may log in to a website in Safari, entering a user name and password, and save those credentials using the iCloud Keychain. Later, the user may run a native app from the same developer, and instead of the app requiring the user to reenter a user name and password, shared web credentials gives it access to the credentials that were entered earlier in Safari. The user can also create new accounts, update passwords, or delete her account from within the app. These changes are then saved and used by Safari.
414 | >
415 |
416 | ```swift
417 | let keychain = Keychain(server: "https://www.kishikawakatsumi.com", protocolType: .HTTPS)
418 |
419 | let username = "kishikawakatsumi@mac.com"
420 |
421 | // First, check the credential in the app's Keychain
422 | if let password = try? keychain.get(username) {
423 | // If found password in the Keychain,
424 | // then log into the server
425 | } else {
426 | // If not found password in the Keychain,
427 | // try to read from Shared Web Credentials
428 | keychain.getSharedPassword(username) { (password, error) -> () in
429 | if password != nil {
430 | // If found password in the Shared Web Credentials,
431 | // then log into the server
432 | // and save the password to the Keychain
433 |
434 | keychain[username] = password
435 | } else {
436 | // If not found password either in the Keychain also Shared Web Credentials,
437 | // prompt for username and password
438 |
439 | // Log into server
440 |
441 | // If the login is successful,
442 | // save the credentials to both the Keychain and the Shared Web Credentials.
443 |
444 | keychain[username] = inputPassword
445 | keychain.setSharedPassword(inputPassword, account: username)
446 | }
447 | }
448 | }
449 | ```
450 |
451 | #### Request all associated domain's credentials
452 |
453 | ```swift
454 | Keychain.requestSharedWebCredential { (credentials, error) -> () in
455 |
456 | }
457 | ```
458 |
459 | #### Generate strong random password
460 |
461 | Generate strong random password that is in the same format used by Safari autofill (xxx-xxx-xxx-xxx).
462 |
463 | ```swift
464 | let password = Keychain.generatePassword() // => Nhu-GKm-s3n-pMx
465 | ```
466 |
467 | #### How to set up Shared Web Credentials
468 |
469 | > 1. Add a com.apple.developer.associated-domains entitlement to your app. This entitlement must include all the domains with which you want to share credentials.
470 | >
471 | > 2. Add an apple-app-site-association file to your website. This file must include application identifiers for all the apps with which the site wants to share credentials, and it must be properly signed.
472 | >
473 | > 3. When the app is installed, the system downloads and verifies the site association file for each of its associated domains. If the verification is successful, the app is associated with the domain.
474 |
475 | **More details:**
476 |
477 |
478 | ### :mag: Debugging
479 |
480 | #### Display all stored items if print keychain object
481 |
482 | ```swift
483 | let keychain = Keychain(server: "https://github.com", protocolType: .https)
484 | print("\(keychain)")
485 | ```
486 |
487 | ```
488 | =>
489 | [
490 | [authenticationType: default, key: kishikawakatsumi, server: github.com, class: internetPassword, protocol: https]
491 | [authenticationType: default, key: hirohamada, server: github.com, class: internetPassword, protocol: https]
492 | [authenticationType: default, key: honeylemon, server: github.com, class: internetPassword, protocol: https]
493 | ]
494 | ```
495 |
496 | #### Obtaining all stored keys
497 |
498 | ```swift
499 | let keychain = Keychain(server: "https://github.com", protocolType: .https)
500 |
501 | let keys = keychain.allKeys()
502 | for key in keys {
503 | print("key: \(key)")
504 | }
505 | ```
506 |
507 | ```
508 | =>
509 | key: kishikawakatsumi
510 | key: hirohamada
511 | key: honeylemon
512 | ```
513 |
514 | #### Obtaining all stored items
515 |
516 | ```swift
517 | let keychain = Keychain(server: "https://github.com", protocolType: .https)
518 |
519 | let items = keychain.allItems()
520 | for item in items {
521 | print("item: \(item)")
522 | }
523 | ```
524 |
525 | ```
526 | =>
527 | item: [authenticationType: Default, key: kishikawakatsumi, server: github.com, class: InternetPassword, protocol: https]
528 | item: [authenticationType: Default, key: hirohamada, server: github.com, class: InternetPassword, protocol: https]
529 | item: [authenticationType: Default, key: honeylemon, server: github.com, class: InternetPassword, protocol: https]
530 | ```
531 |
532 | ## Keychain sharing capability
533 |
534 | If you encounter the error below, you need to add an `Keychain.entitlements`.
535 |
536 | ```
537 | OSStatus error:[-34018] Internal error when a required entitlement isn't present, client has neither application-identifier nor keychain-access-groups entitlements.
538 | ```
539 |
540 |
541 |
542 |
543 |
544 | ## Requirements
545 |
546 | | | OS | Swift |
547 | | ---------- | ---------------------------------------------------------- | ------------------ |
548 | | **v1.1.x** | iOS 7+, macOS 10.9+ | 1.1 |
549 | | **v1.2.x** | iOS 7+, macOS 10.9+ | 1.2 |
550 | | **v2.0.x** | iOS 7+, macOS 10.9+, watchOS 2+ | 2.0 |
551 | | **v2.1.x** | iOS 7+, macOS 10.9+, watchOS 2+ | 2.0 |
552 | | **v2.2.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 2.0, 2.1 |
553 | | **v2.3.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 2.0, 2.1, 2.2 |
554 | | **v2.4.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 2.2, 2.3 |
555 | | **v3.0.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 3.x |
556 | | **v3.1.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 4.0, 4.1, 4.2 |
557 | | **v3.2.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 4.0, 4.1, 4.2, 5.0 |
558 | | **v4.0.x** | iOS 8+, macOS 10.9+, watchOS 2+, tvOS 9+ | 4.0, 4.1, 4.2, 5.1 |
559 | | **v4.1.x** | iOS 8+, macOS 10.9+, watchOS 3+, tvOS 9+, Mac Catalyst 13+ | 4.0, 4.1, 4.2, 5.1 |
560 |
561 | ## Installation
562 |
563 | ### CocoaPods
564 |
565 | KeychainAccess is available through [CocoaPods](http://cocoapods.org). To install
566 | it, simply add the following lines to your Podfile:
567 |
568 | ```ruby
569 | use_frameworks!
570 | pod 'KeychainAccess'
571 | ```
572 |
573 | ### Carthage
574 |
575 | KeychainAccess is available through [Carthage](https://github.com/Carthage/Carthage). To install
576 | it, simply add the following line to your Cartfile:
577 |
578 | `github "kishikawakatsumi/KeychainAccess"`
579 |
580 | ### Swift Package Manager
581 |
582 | KeychainAccess is also available through [Swift Package Manager](https://github.com/apple/swift-package-manager/).
583 |
584 | #### Xcode
585 |
586 | Select `File > Add Packages... > Add Package Dependency...`,
587 |
588 |
589 |
590 | #### CLI
591 |
592 | First, create `Package.swift` that its package declaration includes:
593 |
594 | ```swift
595 | // swift-tools-version:5.0
596 | import PackageDescription
597 |
598 | let package = Package(
599 | name: "MyLibrary",
600 | products: [
601 | .library(name: "MyLibrary", targets: ["MyLibrary"]),
602 | ],
603 | dependencies: [
604 | .package(url: "https://github.com/kishikawakatsumi/KeychainAccess.git", from: "3.0.0"),
605 | ],
606 | targets: [
607 | .target(name: "MyLibrary", dependencies: ["KeychainAccess"]),
608 | ]
609 | )
610 | ```
611 |
612 | Then, type
613 |
614 | ```shell
615 | $ swift build
616 | ```
617 |
618 | ### To manually add to your project
619 |
620 | 1. Add `Lib/KeychainAccess.xcodeproj` to your project
621 | 2. Link `KeychainAccess.framework` with your target
622 | 3. Add `Copy Files Build Phase` to include the framework to your application bundle
623 |
624 | _See [iOS Example Project](https://github.com/kishikawakatsumi/KeychainAccess/tree/master/Examples/Example-iOS) as reference._
625 |
626 |
627 |
628 | ## Author
629 |
630 | kishikawa katsumi, kishikawakatsumi@mac.com
631 |
632 | ## License
633 |
634 | KeychainAccess is available under the MIT license. See the LICENSE file for more info.
635 |
--------------------------------------------------------------------------------
/Sources/Keychain.swift:
--------------------------------------------------------------------------------
1 | ../Lib/KeychainAccess/Keychain.swift
--------------------------------------------------------------------------------