Skip to content

Commit

Permalink
Add perishable object storage (#6)
Browse files Browse the repository at this point in the history
* Add perishable object storage

* Remove unused default value

* Update comments

* Move "expireAfter" time interval to the store function instead of the get function. Test the perishable functions

* fixed comment for PR

* update expectation names

* Updated CI settings to run only on the latest MacOS and latest current iOS

* updated minimum iOS version to 11

* updated ruby gems

* update iOS deployment target for test host app to iOS 11

---------

Co-authored-by: Gligor Kotushevski <gligorkot@gmail.com>
  • Loading branch information
CrunchieDCD and gligorkot authored May 1, 2023
1 parent a2ead58 commit 09ebc88
Show file tree
Hide file tree
Showing 13 changed files with 216 additions and 128 deletions.
77 changes: 11 additions & 66 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ name: CI
on: pull_request

jobs:
pod-lint-10_15:
pod-lint:
name: Pod lint
runs-on: macos-10.15
runs-on: macos-13

steps:
- name: Checkout
Expand All @@ -23,13 +23,13 @@ jobs:
run: bundle exec pod lib lint --verbose --fail-fast --swift-version=5.5
shell: bash

test-no-iOS-host-10_15:
name: Run swift tests that don't require iOS host on MacOS 10.15
runs-on: macos-10.15
test-no-iOS-host-13:
name: Run swift tests that don't require iOS host on MacOS 13
runs-on: macos-13
strategy:
matrix:
# latest 11 and all available versions 12
xcodeVersions: ['11.7', '12.0', '12.1', '12.2', '12.3', '12.4']
# all available versions of XCode14
xcodeVersions: ['14.1', '14.2', '14.3']

steps:
- name: Checkout
Expand All @@ -44,64 +44,9 @@ jobs:
run: swift test -c debug -Xswiftc -enable-testing
shell: bash

test-no-iOS-host-11:
name: Run swift tests that don't require iOS host on MacOS 11
runs-on: macos-11
strategy:
matrix:
# latest 12 and all available versions 13
xcodeVersions: ['12.5', '13.0', '13.1']

steps:
- name: Checkout
uses: actions/checkout@v2

- name: Set up XCode Version
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: ${{ matrix.xcodeVersions }}

- name: Run tests that don't require iOS host
run: swift test -c debug -Xswiftc -enable-testing
shell: bash

test-keychain-iOS-host-10_15-XCode11:
name: Run swift tests that require keychain entitlement on XCode 11
runs-on: macos-10.15

steps:
- name: Checkout
uses: actions/checkout@v2

- name: Set up XCode Version
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '11.7'

- name: Run tests that require iOS host for keychain entitlement
run: xcodebuild -project SecureStorageTestsHostApp/SecureStorageTestsHostApp.xcodeproj -scheme SecureStorageTestsHostApp -sdk iphonesimulator -destination "platform=iOS Simulator,name=iPhone 11,OS=13.7" test
shell: bash

test-keychain-iOS-host-11-XCode12:
name: Run swift tests that require keychain entitlement on XCode 12
runs-on: macos-11

steps:
- name: Checkout
uses: actions/checkout@v2

- name: Set up XCode Version
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '12.5'

- name: Run tests that require iOS host for keychain entitlement
run: xcodebuild -project SecureStorageTestsHostApp/SecureStorageTestsHostApp.xcodeproj -scheme SecureStorageTestsHostApp -sdk iphonesimulator -destination "platform=iOS Simulator,name=iPhone 12,OS=14.5" test
shell: bash

test-keychain-iOS-host-11-XCode13:
name: Run swift tests that require keychain entitlement on XCode 13
runs-on: macos-11
test-keychain-iOS-host-13-XCode14:
name: Run swift tests that require keychain entitlement on XCode 14
runs-on: macos-13

steps:
- name: Checkout
Expand All @@ -113,5 +58,5 @@ jobs:
xcode-version: latest-stable

- name: Run tests that require iOS host for keychain entitlement
run: xcodebuild -project SecureStorageTestsHostApp/SecureStorageTestsHostApp.xcodeproj -scheme SecureStorageTestsHostApp -sdk iphonesimulator -destination "platform=iOS Simulator,name=iPhone 13,OS=15.0" test
run: xcodebuild -project SecureStorageTestsHostApp/SecureStorageTestsHostApp.xcodeproj -scheme SecureStorageTestsHostApp -sdk iphonesimulator -destination "platform=iOS Simulator,name=iPhone 14,OS=16.4" test
shell: bash
6 changes: 3 additions & 3 deletions GKStorageKit.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|

s.name = 'GKStorageKit'
s.version = '2.0.0'
s.version = '2.2.0'
s.summary = 'GKStorageKit framework.'
s.description = <<-DESC
* GKStorageKit framework
Expand All @@ -10,8 +10,8 @@ Pod::Spec.new do |s|
s.license = { :type => 'Apache License, Version 2.0', :file => 'LICENSE' }
s.author = { 'Gligor Kotushevski' => 'gligorkot@gmail.com' }
s.social_media_url = 'https://twitter.com/gligor_nz'
s.platform = :ios, '9.0'
s.ios.deployment_target = '9.0'
s.platform = :ios, '11.0'
s.ios.deployment_target = '11.0'
s.source = { :git => 'https://github.com/gligorkot/GKStorageKit.git', :tag => s.version.to_s }

s.source_files = 'Sources/GKStorageKit/**/*'
Expand Down
69 changes: 34 additions & 35 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,50 +1,50 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.5)
CFPropertyList (3.0.6)
rexml
activesupport (5.2.6)
activesupport (7.0.4.3)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
addressable (2.8.4)
public_suffix (>= 2.0.2, < 6.0)
algoliasearch (1.27.5)
httpclient (~> 2.8, >= 2.8.3)
json (>= 1.5.1)
atomos (0.1.3)
claide (1.0.3)
cocoapods (1.10.2)
addressable (~> 2.6)
claide (1.1.0)
cocoapods (1.12.1)
addressable (~> 2.8)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.10.2)
cocoapods-core (= 1.12.1)
cocoapods-deintegrate (>= 1.0.3, < 2.0)
cocoapods-downloader (>= 1.4.0, < 2.0)
cocoapods-downloader (>= 1.6.0, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.4.0, < 2.0)
cocoapods-trunk (>= 1.6.0, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
fourflusher (>= 2.3.0, < 3.0)
gh_inspector (~> 1.0)
molinillo (~> 0.6.6)
molinillo (~> 0.8.0)
nap (~> 1.0)
ruby-macho (~> 1.4)
xcodeproj (>= 1.19.0, < 2.0)
cocoapods-core (1.10.2)
activesupport (> 5.0, < 6)
addressable (~> 2.6)
ruby-macho (>= 2.3.0, < 3.0)
xcodeproj (>= 1.21.0, < 2.0)
cocoapods-core (1.12.1)
activesupport (>= 5.0, < 8)
addressable (~> 2.8)
algoliasearch (~> 1.0)
concurrent-ruby (~> 1.1)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
netrc (~> 0.11)
public_suffix
public_suffix (~> 4.0)
typhoeus (~> 1.0)
cocoapods-deintegrate (1.0.5)
cocoapods-downloader (1.5.1)
cocoapods-downloader (1.6.3)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.1)
Expand All @@ -53,32 +53,31 @@ GEM
netrc (~> 0.11)
cocoapods-try (1.2.0)
colored2 (3.1.2)
concurrent-ruby (1.1.9)
concurrent-ruby (1.2.2)
escape (0.0.4)
ethon (0.15.0)
ethon (0.16.0)
ffi (>= 1.15.0)
ffi (1.15.4)
ffi (1.15.5)
fourflusher (2.3.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
httpclient (2.8.3)
i18n (1.8.11)
i18n (1.13.0)
concurrent-ruby (~> 1.0)
json (2.6.1)
minitest (5.14.4)
molinillo (0.6.6)
json (2.6.3)
minitest (5.18.0)
molinillo (0.8.0)
nanaimo (0.3.0)
nap (1.1.0)
netrc (0.11.0)
public_suffix (4.0.6)
public_suffix (4.0.7)
rexml (3.2.5)
ruby-macho (1.4.0)
thread_safe (0.3.6)
ruby-macho (2.5.1)
typhoeus (1.4.0)
ethon (>= 0.9.0)
tzinfo (1.2.9)
thread_safe (~> 0.1)
xcodeproj (1.21.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
xcodeproj (1.22.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
Expand All @@ -93,4 +92,4 @@ DEPENDENCIES
cocoapods (~> 1.10)

BUNDLED WITH
2.0.2
2.2.3
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import PackageDescription
let package = Package(
name: "GKStorageKit",
platforms: [
.iOS(.v9),
.iOS(.v11),
.macOS(.v10_11)
],
products: [
Expand Down
2 changes: 1 addition & 1 deletion Package@swift-5.2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import PackageDescription
let package = Package(
name: "GKStorageKit",
platforms: [
.iOS(.v9),
.iOS(.v11),
.macOS(.v10_11)
],
products: [
Expand Down
2 changes: 1 addition & 1 deletion Package@swift-5.3.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import PackageDescription
let package = Package(
name: "GKStorageKit",
platforms: [
.iOS(.v9),
.iOS(.v11),
.macOS(.v10_11)
],
products: [
Expand Down
2 changes: 1 addition & 1 deletion Package@swift-5.4.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import PackageDescription
let package = Package(
name: "GKStorageKit",
platforms: [
.iOS(.v9),
.iOS(.v11),
.macOS(.v10_11)
],
products: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@
INFOPLIST_KEY_UIMainStoryboardFile = Main;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -451,7 +451,7 @@
INFOPLIST_KEY_UIMainStoryboardFile = Main;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -473,7 +473,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -497,7 +497,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
32 changes: 16 additions & 16 deletions SecureStorageTestsHostApp/SecureStorageTestsHostApp/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
32 changes: 32 additions & 0 deletions Sources/GKStorageKit/Storage/ObjectStorageService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,38 @@ final class ObjectStorageService: ObjectStorageInterface, StorageKitDecorator {
onSuccess(nil)
}
}

func storePerishableObject<T: Codable>(_ value: T, forKey key: String, expireAfter timeInterval: TimeInterval, onSuccess: () -> ()) {
let storableTimestampItem = PerishableItem<T>(expireOn: Date().timeIntervalSince1970 + timeInterval, item: value)
storeObject(storableTimestampItem, forKey: key, onSuccess: onSuccess)
}

func getPerishableObject<T: Codable>(forKey key: String, onSuccess: (T) -> (), expired: () -> ()) {
getObject(forKey: key) { (storable: PerishableItem<T>?) in
if let storable = storable, storable.expireOn > Date().timeIntervalSince1970 {
// if cache exists and timestamp is not older than timeInterval, return item
onSuccess(storable.item)
} else {
expired()
}
}
}

func storePerishableCollection<T: Codable>(_ collection: Array<T>, forKey key: String, expireAfter timeInterval: TimeInterval, onSuccess: () -> ()) {
let storableTimestampCollection = PerishableCollection<T>(expireOn: Date().timeIntervalSince1970 + timeInterval, collection: collection)
storeObject(storableTimestampCollection, forKey: key, onSuccess: onSuccess)
}

func getPerishableCollection<T: Codable>(forKey key: String, onSuccess: ([T]?) -> (), expired: () -> ()) {
getObject(forKey: key) { (storable: PerishableCollection<T>?) in
if let storable = storable, storable.expireOn > Date().timeIntervalSince1970 {
// if cache exists and timestamp is not older than timeInterval, return collection
onSuccess(storable.collection)
} else {
expired()
}
}
}

func removeValue(forKey key: String, onSuccess: () -> ()) {
objectStorage.removeObject(forKey: key)
Expand Down
Loading

0 comments on commit 09ebc88

Please sign in to comment.