Compare commits

..

61 Commits

Author SHA1 Message Date
Arthur Ariel Sabintsev 6139af3394 Updated podspec 2024-05-04 20:22:58 -04:00
Steve Spigarelli b034739065 Add PrivacyInfo (#422)
Close #420 in favor of #422.
2024-05-04 20:21:14 -04:00
Arthur Ariel Sabintsev e410ed0cbc Update README.md 2023-12-29 20:22:58 -05:00
Arthur Sabintsev dfee0e0e29 Upped podspec 2023-05-17 14:38:53 -04:00
Arthur Sabintsev 6129b57d39 Upped version 2023-05-17 14:31:31 -04:00
blerdfoniqi 0ac904cd51 Adds support for iOS 13 (#411) 2023-05-17 14:20:23 -04:00
Arthur Sabintsev 9b675a8f92 Updated API manager comments and version in Siren 2022-09-20 22:40:00 -04:00
wwwbbat 399e1bfec2 Modify APIManager to make it possible to customize a bundleID. (#404) 2022-09-20 22:34:25 -04:00
Alex Burgel ec892ae746 Ignore skipped versions when using AlertType.force (#405)
fixes #402
2022-09-20 22:29:15 -04:00
Sandro 3bd7b595fb Fixed 'try' must precede 'await' (#400) 2022-06-25 21:35:36 -04:00
Arthur Sabintsev 3d8c83c720 Updated readme 2022-06-02 00:14:12 -04:00
Arthur Sabintsev 466e70236c Removed Gemfiles as cocoapods is now installed via homebrew 2022-06-02 00:13:42 -04:00
Arthur Sabintsev 0fba2a6954 Updated gems 2022-06-02 00:03:39 -04:00
Arthur Sabintsev 8afe1fe943 Updated podspec 2022-06-02 00:02:26 -04:00
Arthur Sabintsev fa7308fdd9 Fixed swiftlint issues 2022-06-02 00:01:53 -04:00
Arthur Sabintsev f7568b6c16 updated vars 2022-06-01 23:48:56 -04:00
Arthur Sabintsev 12d7ba2960 Fixed async compilation issue 2022-06-01 23:45:05 -04:00
Arthur Sabintsev 0325de208a Updated pods 2022-06-01 23:41:49 -04:00
Seokmin bb1fa6fa5c Update dialog can't appear bug (#397)
* Update dialog can't appear bug

Problem
1. Check update as .onForeground (Siren.shared.wail(performCheck: .onForeground))
2. If user swipe down the notification center screen to the bottom of screen (by swiping downward from the very top of the device's screen)
3. And back to app can't appear update dialog

Reason
If swipe down the notification center screen to the bottom of screen
iOS call observer like this
1. starting to swipe down : willResignActiveNotification
2. reached to bottom : didBecomeActiveNotification, willResignActiveNotification

* Update Siren.swift

* Null safety and don't hardcode

The delay time what to consider is it called by notification center screen to bottom become constant
And appDidBecomeActiveWorkItem is used null safety

Co-authored-by: seokmin <jsm@dio.co.kr>
2022-06-01 23:35:22 -04:00
Arthur Sabintsev e3bb33873d Updated podspec 2022-05-19 20:59:19 -04:00
Arthur Sabintsev 4eb08279ac Fixed croation localization. Fixed testing target 2022-05-19 20:55:28 -04:00
dependabot[bot] eb70823f96 Bump cocoapods-downloader from 1.4.0 to 1.6.3 (#392) 2022-04-12 12:35:18 -04:00
Arthur Sabintsev e92ab66220 Updated sample project to facebook 2022-03-23 20:41:28 -04:00
Arthur Sabintsev c265763d25 Updated Siren.podspec 2022-03-23 20:16:35 -04:00
Arthur Sabintsev 3f31c97fc9 Updated comments 2022-03-23 20:14:31 -04:00
Kien Nguyen 609f1653a4 Add lang parameter to APIManager (#391)
Co-authored-by: kientux <kiennt@sapo.vn>
2022-03-23 19:43:49 -04:00
Arthur Sabintsev 07babd6e36 Minor changes to APIManager 2021-09-17 01:00:05 -04:00
Arthur Ariel Sabintsev 8ed72c71c4 iOS 15 Support (#375)
* Updated to latest version of Swift compatible with iOS 15

* Updated docs

* Updated package manager meta files

* Update README.md

* Minor changes

* Minor changes with Xcode 13 RC

* Re ran pod install on sample proj

* Updated readme
2021-09-17 00:50:06 -04:00
dependabot[bot] 05cd85c479 Bump addressable from 2.7.0 to 2.8.0 (#372)
Bumps [addressable](https://github.com/sporkmonger/addressable) from 2.7.0 to 2.8.0.
- [Release notes](https://github.com/sporkmonger/addressable/releases)
- [Changelog](https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sporkmonger/addressable/compare/addressable-2.7.0...addressable-2.8.0)

---
updated-dependencies:
- dependency-name: addressable
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-22 15:02:46 -04:00
Arthur Sabintsev d8009d69dd Updated meta 2021-05-30 17:52:09 -04:00
Arthur Sabintsev 9173fc5297 Bumped to 5.8.1 2021-01-18 23:43:09 -05:00
Arthur Sabintsev bc4d6aa47a Fixed test target 2021-01-18 23:42:42 -05:00
Hamza Öztürk 64e0b73c3a Update SirenLocalizable.strings (#361) 2021-01-18 23:41:12 -05:00
Arthur Sabintsev a35be9ee2d Updated readme 2021-01-16 20:45:46 -05:00
Arthur Sabintsev f10f6928a3 Updated min version to 13. Added tvos support 2021-01-16 20:44:37 -05:00
Matt Freiburg 380f79053e Add tvOS 13 to if available checks in Presentation Manager (#360)
* Add tvOS 13 to if available checks

* Add queryItem for tvOS App Store

* Move inline tvOS Query parameter strings to Constants struct
2021-01-16 20:37:03 -05:00
Arthur Sabintsev 3197a6dc30 Ypdated swiftlint.yml 2020-12-29 15:34:09 -05:00
Arthur Sabintsev a5f51af7eb Update pod settings 2020-12-29 15:33:33 -05:00
Arthur Sabintsev 3a5a357834 Updated gemfile 2020-12-23 09:37:57 -05:00
Arthur Sabintsev 2f80f8dce2 Updated Bundle extension to be simpler 2020-12-21 11:16:11 -05:00
Arthur Sabintsev 2fa31da639 Updated project 2020-12-21 08:52:25 -05:00
Arthur Sabintsev d137dabe69 Update lockfile 2020-12-21 08:45:59 -05:00
Arthur Sabintsev c563cf5a61 Update Podspec 2020-12-21 08:44:03 -05:00
Arthur Sabintsev 308e1061c8 Merge branch 'master' of https://github.com/ArtSabintsev/Siren 2020-12-21 08:38:03 -05:00
Arthur Ariel Sabintsev 2cffe34e2c Fix Swift PM 5.3 Resource Bundle Migration (#358)
* Updated lockfile

* Updated package.swift

* Updated package.swift

* Updated BundleExtension

* Minified Package.swift file
2020-12-21 08:37:55 -05:00
Arthur Sabintsev 60968544ab Updated lockfile 2020-11-23 14:25:42 -05:00
Arthur Sabintsev 51b08a20c3 Updated podspec 2020-11-22 20:27:12 -05:00
Harlan Kellaway 6eb57bcdee Add missing AppStoreCountry values (#355)
Co-authored-by: Harlan Kellaway <hkellaway@users.noreply.github.com>
2020-11-22 18:36:09 -05:00
Arthur Ariel Sabintsev 6d40521756 Update README.md 2020-11-22 14:40:54 -05:00
Arthur Sabintsev 20a4a58b37 Updated to modern gitignore 2020-11-22 13:31:24 -05:00
Arthur Sabintsev 2490dc04db Modifications to .travis.yml 2020-11-22 08:09:41 -05:00
Arthur Ariel Sabintsev 9275cc2794 Update README.md 2020-11-22 07:59:51 -05:00
Arthur Sabintsev 336413447b Adjusted travis.yml file 2020-11-22 00:08:49 -05:00
Arthur Sabintsev d8d4bd8f1c Updated README 2020-11-22 00:07:23 -05:00
Arthur Sabintsev b5cc26d007 Fixed schemes 2020-11-22 00:01:34 -05:00
Arthur Sabintsev 5816cf245a Version bump 2020-11-21 23:40:27 -05:00
Arthur Sabintsev d546163f54 Removed FUNDING.yml 2020-11-21 22:10:05 -05:00
Arthur Sabintsev a165a13abd remove docs 2020-11-21 22:08:49 -05:00
Arthur Sabintsev bf49eeb464 Docs are now in html 2020-11-21 22:07:08 -05:00
Arthur Sabintsev 42ab71be3c Removed bundle/config 2020-11-21 22:02:30 -05:00
Arthur Sabintsev dc1bb6b058 Updated travis yml 2020-11-21 21:35:52 -05:00
60 changed files with 969 additions and 3235 deletions
-2
View File
@@ -1,2 +0,0 @@
---
BUNDLE_PATH: "/Users/arthur/.rvm/gems/"
-3
View File
@@ -1,3 +0,0 @@
# These are supported funding model platforms
github: ArtSabintsev
+52 -5
View File
@@ -1,6 +1,12 @@
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Build generated
build/
DerivedData/
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
@@ -9,11 +15,52 @@ build/
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
xcuserdata/
## Other
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
.DS_Store
## Obj-C/Swift specific
*.hmap
*.ipa
*.dSYM.zip
*.dSYM
## Playgrounds
timeline.xctimeline
playground.xcworkspace
# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
.build/
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
Carthage/Build
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
+3 -5
View File
@@ -2,14 +2,12 @@ reporter: "xcode"
included:
- ../Sources/
- Example/Tests/
disabled_rules:
- cyclomatic_complexity
- identifier_name
- file_length
- line_length
- nesting
- unused_optional_binding
- variable_name
# Specialized Rules
file_length:
- 500
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
+4 -1
View File
@@ -6,8 +6,11 @@ notifications:
before_install:
- brew update
- gem install bundler
- bundle
- cd Example/
- pod install
env:
- LC_CTYPE=en_US.UTF-8 LANG=en_US.UTF-8
script:
- set -o pipefail
- xcodebuild -project Example/Example.xcworkspace -scheme Example -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO
- xcodebuild -workspace Example.xcworkspace -scheme Example -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO
+8 -8
View File
@@ -45,7 +45,6 @@
31A1A1D27EA05F1E28033516 /* Pods-Example-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-Tests.release.xcconfig"; path = "Target Support Files/Pods-Example-Tests/Pods-Example-Tests.release.xcconfig"; sourceTree = "<group>"; };
3207656F9030B2912198AF2E /* Pods_Example_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
37940350BF612EEBD59D5DF4 /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
55EC364A1E6BB98A00726F13 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = ../../Siren/Info.plist; sourceTree = "<group>"; };
5A65216266BE44478A3B3AEB /* Pods-Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.debug.xcconfig"; path = "Target Support Files/Pods-Tests/Pods-Tests.debug.xcconfig"; sourceTree = "<group>"; };
740DAA3321466F1ABE6CC37D /* Pods-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.debug.xcconfig"; path = "Target Support Files/Pods-Example/Pods-Example.debug.xcconfig"; sourceTree = "<group>"; };
8E3A6C041D07CB6F00A8B7CF /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -121,7 +120,6 @@
8EACA96B1F37F2D3003134CA /* Images.xcassets */,
8EACA96C1F37F2D3003134CA /* Info.plist */,
8EACA96D1F37F2D3003134CA /* ViewController.swift */,
55EC364A1E6BB98A00726F13 /* Info.plist */,
);
path = "Supporting Files";
sourceTree = "<group>";
@@ -428,7 +426,7 @@
DEBUG_INFORMATION_FORMAT = dwarf;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = Tests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.sabintsev.SirenTests;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -448,7 +446,7 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = Tests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.sabintsev.SirenTests;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -505,7 +503,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -554,7 +552,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_VERSION = 4.2;
@@ -570,8 +568,9 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
DEVELOPMENT_TEAM = HT94948NDD;
INFOPLIST_FILE = "$(SRCROOT)/Example/Supporting Files/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 2.0.2;
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.Facebook;
PRODUCT_NAME = Example;
SWIFT_VERSION = 5.0;
@@ -587,8 +586,9 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
DEVELOPMENT_TEAM = HT94948NDD;
INFOPLIST_FILE = "$(SRCROOT)/Example/Supporting Files/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 2.0.2;
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.Facebook;
PRODUCT_NAME = Example;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+1 -1
View File
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
@@ -21,4 +21,3 @@ class ViewController: UIViewController {
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
platform :ios, '11.0'
platform :ios, '15.0'
inhibit_all_warnings!
use_frameworks!
+4 -4
View File
@@ -1,5 +1,5 @@
PODS:
- Siren (5.6.0)
- Siren (6.0.2)
DEPENDENCIES:
- Siren (from `../`)
@@ -9,8 +9,8 @@ EXTERNAL SOURCES:
:path: "../"
SPEC CHECKSUMS:
Siren: 600a3e991f8ff2ade8376ff2d10b287b9ff2df51
Siren: 1be92ef5775f9b61ebb294c79c59268ab0afcf5d
PODFILE CHECKSUM: 1b0b20618a6fdca0d708c439075d1f6313cc3ff0
PODFILE CHECKSUM: 5800641824958ea506d6ae52e89b594fe8270c18
COCOAPODS: 1.7.5
COCOAPODS: 1.11.2
+6 -5
View File
@@ -1,7 +1,7 @@
{
"name": "Siren",
"version": "5.6.0",
"swift_versions": "5.3",
"version": "6.0.2",
"swift_versions": "5.5",
"summary": "Notify users that a new version of your iOS app is available, and prompt them with the App Store link.",
"homepage": "https://github.com/ArtSabintsev/Siren",
"license": "MIT",
@@ -10,14 +10,15 @@
},
"description": "Notify your users when a new version of your iOS app is available, and prompt them with the App Store link.",
"platforms": {
"ios": "11.0"
"ios": "15.0",
"tvos": "15.0"
},
"source": {
"git": "https://github.com/ArtSabintsev/Siren.git",
"tag": "5.6.0"
"tag": "6.0.2"
},
"source_files": "Sources/**/*.swift",
"resources": "Sources/Siren.bundle",
"requires_arc": true,
"swift_version": "5.3"
"swift_version": "5.5"
}
+4 -4
View File
@@ -1,5 +1,5 @@
PODS:
- Siren (5.6.0)
- Siren (6.0.2)
DEPENDENCIES:
- Siren (from `../`)
@@ -9,8 +9,8 @@ EXTERNAL SOURCES:
:path: "../"
SPEC CHECKSUMS:
Siren: 600a3e991f8ff2ade8376ff2d10b287b9ff2df51
Siren: 1be92ef5775f9b61ebb294c79c59268ab0afcf5d
PODFILE CHECKSUM: 1b0b20618a6fdca0d708c439075d1f6313cc3ff0
PODFILE CHECKSUM: 5800641824958ea506d6ae52e89b594fe8270c18
COCOAPODS: 1.7.5
COCOAPODS: 1.11.2
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1220"
LastUpgradeVersion = "1340"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -14,10 +14,10 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8EC391801A58B465001C121E"
BuildableName = "Example.app"
BlueprintName = "Example"
ReferencedContainer = "container:Example.xcodeproj">
BlueprintIdentifier = "258F10561A9DF823C49949D6176054DD"
BuildableName = "Pods_Example_Tests.framework"
BlueprintName = "Pods-Example-Tests"
ReferencedContainer = "container:Pods.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
@@ -27,26 +27,7 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8EC391801A58B465001C121E"
BuildableName = "Example.app"
BlueprintName = "Example"
ReferencedContainer = "container:Example.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8E3A6C031D07CB6F00A8B7CF"
BuildableName = "Tests.xctest"
BlueprintName = "Tests"
ReferencedContainer = "container:Example.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
@@ -59,16 +40,6 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8EC391801A58B465001C121E"
BuildableName = "Example.app"
BlueprintName = "Example"
ReferencedContainer = "container:Example.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
@@ -76,16 +47,15 @@
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8EC391801A58B465001C121E"
BuildableName = "Example.app"
BlueprintName = "Example"
ReferencedContainer = "container:Example.xcodeproj">
BlueprintIdentifier = "258F10561A9DF823C49949D6176054DD"
BuildableName = "Pods_Example_Tests.framework"
BlueprintName = "Pods-Example-Tests"
ReferencedContainer = "container:Pods.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1340"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0AEE99A309977BD12A049FF48AF9BA4B"
BuildableName = "Pods_Example.framework"
BlueprintName = "Pods-Example"
ReferencedContainer = "container:Pods.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0AEE99A309977BD12A049FF48AF9BA4B"
BuildableName = "Pods_Example.framework"
BlueprintName = "Pods-Example"
ReferencedContainer = "container:Pods.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1220"
LastUpgradeVersion = "1340"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -14,10 +14,10 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8EF9F852224EACA500B20545"
BlueprintIdentifier = "A0E2640B83527AE54205D7FDE9C5D930"
BuildableName = "Siren.framework"
BlueprintName = "Siren"
ReferencedContainer = "container:Example.xcodeproj">
ReferencedContainer = "container:Pods.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
@@ -40,15 +40,6 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8EF9F852224EACA500B20545"
BuildableName = "Siren.framework"
BlueprintName = "Siren"
ReferencedContainer = "container:Example.xcodeproj">
</BuildableReference>
</MacroExpansion>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
@@ -59,10 +50,10 @@
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8EF9F852224EACA500B20545"
BlueprintIdentifier = "A0E2640B83527AE54205D7FDE9C5D930"
BuildableName = "Siren.framework"
BlueprintName = "Siren"
ReferencedContainer = "container:Example.xcodeproj">
ReferencedContainer = "container:Pods.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
@@ -19,9 +19,8 @@ mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
BCSYMBOLMAP_DIR="BCSymbolMaps"
# Used as a return value for each invocation of `strip_invalid_archs` function.
STRIP_BINARY_RETVAL=0
# This protects against multiple targets copying the same framework dependency at the same time. The solution
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
@@ -45,9 +44,19 @@ install_framework()
source="$(readlink "${source}")"
fi
if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then
# Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied
find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do
echo "Installing $f"
install_bcsymbolmap "$f" "$destination"
rm "$f"
done
rmdir "${source}/${BCSYMBOLMAP_DIR}"
fi
# Use filter instead of exclude so missing patterns don't throw errors.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
local basename
basename="$(basename -s .framework "$1")"
@@ -80,35 +89,69 @@ install_framework()
done
fi
}
# Copies and strips a vendored dSYM
install_dsym() {
local source="$1"
warn_missing_arch=${2:-true}
if [ -r "$source" ]; then
# Copy the dSYM into a the targets temp dir.
# Copy the dSYM into the targets temp dir.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
local basename
basename="$(basename -s .framework.dSYM "$source")"
binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}"
basename="$(basename -s .dSYM "$source")"
binary_name="$(ls "$source/Contents/Resources/DWARF")"
binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}"
# Strip invalid architectures so "fat" simulator / device frameworks work on device
# Strip invalid architectures from the dSYM.
if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
strip_invalid_archs "$binary"
strip_invalid_archs "$binary" "$warn_missing_arch"
fi
if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
if [[ $STRIP_BINARY_RETVAL == 0 ]]; then
# Move the stripped file into its final destination.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
else
# The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM"
mkdir -p "${DWARF_DSYM_FOLDER_PATH}"
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM"
fi
fi
}
# Used as a return value for each invocation of `strip_invalid_archs` function.
STRIP_BINARY_RETVAL=0
# Strip invalid architectures
strip_invalid_archs() {
binary="$1"
warn_missing_arch=${2:-true}
# Get architectures for current target binary
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
# Intersect them with the architectures we are building for
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
# If there are no archs supported by this binary then warn the user
if [[ -z "$intersected_archs" ]]; then
if [[ "$warn_missing_arch" == "true" ]]; then
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
fi
STRIP_BINARY_RETVAL=1
return
fi
stripped=""
for arch in $binary_archs; do
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary"
stripped="$stripped $arch"
fi
done
if [[ "$stripped" ]]; then
echo "Stripped $binary of architectures:$stripped"
fi
STRIP_BINARY_RETVAL=0
}
# Copies the bcsymbolmap files of a vendored framework
install_bcsymbolmap() {
local bcsymbolmap_path="$1"
@@ -132,34 +175,6 @@ code_sign_if_enabled() {
fi
}
# Strip invalid architectures
strip_invalid_archs() {
binary="$1"
# Get architectures for current target binary
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
# Intersect them with the architectures we are building for
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
# If there are no archs supported by this binary then warn the user
if [[ -z "$intersected_archs" ]]; then
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
STRIP_BINARY_RETVAL=0
return
fi
stripped=""
for arch in $binary_archs; do
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary"
stripped="$stripped $arch"
fi
done
if [[ "$stripped" ]]; then
echo "Stripped $binary of architectures:$stripped"
fi
STRIP_BINARY_RETVAL=1
}
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/Siren/Siren.framework"
fi
@@ -1,8 +1,10 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Siren"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Siren/Siren.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_CFLAGS = $(inherited) -isystem "${PODS_CONFIGURATION_BUILD_DIR}/Siren/Siren.framework/Headers" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/Siren"
OTHER_LDFLAGS = $(inherited) -framework "Siren"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
@@ -10,3 +12,5 @@ PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
@@ -1,8 +1,10 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Siren"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Siren/Siren.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_CFLAGS = $(inherited) -isystem "${PODS_CONFIGURATION_BUILD_DIR}/Siren/Siren.framework/Headers" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/Siren"
OTHER_LDFLAGS = $(inherited) -framework "Siren"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
@@ -10,3 +12,5 @@ PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
@@ -19,9 +19,8 @@ mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
BCSYMBOLMAP_DIR="BCSymbolMaps"
# Used as a return value for each invocation of `strip_invalid_archs` function.
STRIP_BINARY_RETVAL=0
# This protects against multiple targets copying the same framework dependency at the same time. The solution
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
@@ -45,9 +44,19 @@ install_framework()
source="$(readlink "${source}")"
fi
if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then
# Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied
find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do
echo "Installing $f"
install_bcsymbolmap "$f" "$destination"
rm "$f"
done
rmdir "${source}/${BCSYMBOLMAP_DIR}"
fi
# Use filter instead of exclude so missing patterns don't throw errors.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
local basename
basename="$(basename -s .framework "$1")"
@@ -80,35 +89,69 @@ install_framework()
done
fi
}
# Copies and strips a vendored dSYM
install_dsym() {
local source="$1"
warn_missing_arch=${2:-true}
if [ -r "$source" ]; then
# Copy the dSYM into a the targets temp dir.
# Copy the dSYM into the targets temp dir.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
local basename
basename="$(basename -s .framework.dSYM "$source")"
binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}"
basename="$(basename -s .dSYM "$source")"
binary_name="$(ls "$source/Contents/Resources/DWARF")"
binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}"
# Strip invalid architectures so "fat" simulator / device frameworks work on device
# Strip invalid architectures from the dSYM.
if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
strip_invalid_archs "$binary"
strip_invalid_archs "$binary" "$warn_missing_arch"
fi
if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
if [[ $STRIP_BINARY_RETVAL == 0 ]]; then
# Move the stripped file into its final destination.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
else
# The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM"
mkdir -p "${DWARF_DSYM_FOLDER_PATH}"
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM"
fi
fi
}
# Used as a return value for each invocation of `strip_invalid_archs` function.
STRIP_BINARY_RETVAL=0
# Strip invalid architectures
strip_invalid_archs() {
binary="$1"
warn_missing_arch=${2:-true}
# Get architectures for current target binary
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
# Intersect them with the architectures we are building for
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
# If there are no archs supported by this binary then warn the user
if [[ -z "$intersected_archs" ]]; then
if [[ "$warn_missing_arch" == "true" ]]; then
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
fi
STRIP_BINARY_RETVAL=1
return
fi
stripped=""
for arch in $binary_archs; do
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary"
stripped="$stripped $arch"
fi
done
if [[ "$stripped" ]]; then
echo "Stripped $binary of architectures:$stripped"
fi
STRIP_BINARY_RETVAL=0
}
# Copies the bcsymbolmap files of a vendored framework
install_bcsymbolmap() {
local bcsymbolmap_path="$1"
@@ -132,34 +175,6 @@ code_sign_if_enabled() {
fi
}
# Strip invalid architectures
strip_invalid_archs() {
binary="$1"
# Get architectures for current target binary
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
# Intersect them with the architectures we are building for
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
# If there are no archs supported by this binary then warn the user
if [[ -z "$intersected_archs" ]]; then
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
STRIP_BINARY_RETVAL=0
return
fi
stripped=""
for arch in $binary_archs; do
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary"
stripped="$stripped $arch"
fi
done
if [[ "$stripped" ]]; then
echo "Stripped $binary of architectures:$stripped"
fi
STRIP_BINARY_RETVAL=1
}
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/Siren/Siren.framework"
fi
@@ -1,8 +1,10 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Siren"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Siren/Siren.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_CFLAGS = $(inherited) -isystem "${PODS_CONFIGURATION_BUILD_DIR}/Siren/Siren.framework/Headers" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/Siren"
OTHER_LDFLAGS = $(inherited) -framework "Siren"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
@@ -10,3 +12,5 @@ PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
@@ -1,8 +1,10 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Siren"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Siren/Siren.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_CFLAGS = $(inherited) -isystem "${PODS_CONFIGURATION_BUILD_DIR}/Siren/Siren.framework/Headers" -iframework "${PODS_CONFIGURATION_BUILD_DIR}/Siren"
OTHER_LDFLAGS = $(inherited) -framework "Siren"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
@@ -10,3 +12,5 @@ PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
+1 -1
View File
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>5.6.0</string>
<string>6.0.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
@@ -0,0 +1,13 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Siren
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -suppress-warnings
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
@@ -0,0 +1,13 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Siren
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS -suppress-warnings
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
+24 -26
View File
@@ -18,11 +18,9 @@ final class SirenTests: XCTestCase {
// MARK: - API
extension SirenTests {
func testAPIDefaultsToUnitedStatesAppStore() {
XCTAssertEqual(siren.apiManager.country, AppStoreCountry.unitedStates)
}
}
// MARK: - Updates
@@ -230,7 +228,7 @@ extension SirenTests {
let language: Localization.Language = .croatian
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Nova ažuriranje je stigla")
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Novo ažuriranje je dostupno")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Sljedeći put")
@@ -353,19 +351,19 @@ extension SirenTests {
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Update")
}
func testGreekLocalization() {
let language: Localization.Language = .greek
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Διαθέσιμη Ενημέρωση")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Άλλη φορά")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Αγνόησε αυτήν την έκδοση")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Αναβάθμιση")
}
@@ -535,49 +533,49 @@ extension SirenTests {
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "بروزرسانی در دسترس")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "دفعه بعد")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "رد این نسخه")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "بروزرسانی")
}
func testPersianAfghanistanLocalization() {
let language: Localization.Language = .persianAfghanistan
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "بروزرسانی در دسترس")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "دگر بار")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "رد این نسخه")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "بروزرسانی")
}
func testPersianIranLocalization() {
let language: Localization.Language = .persianIran
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "بروزرسانی در دسترس")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "دفعه بعد")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "رد این نسخه")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "بروزرسانی")
}
func testPolishLocalization() {
let language: Localization.Language = .polish
@@ -775,17 +773,17 @@ extension SirenTests {
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Доступне Оновлення")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Наступного разу")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Пропустити версію")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Оновити")
}
func testUrduLocalization() {
let language: Localization.Language = .urdu
@@ -801,7 +799,7 @@ extension SirenTests {
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "اپڈیٹ کریں")
}
func testVietnameseLocalization() {
let language: Localization.Language = .vietnamese
@@ -817,5 +815,5 @@ extension SirenTests {
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Cập nhật")
}
}
-3
View File
@@ -1,3 +0,0 @@
source "https://rubygems.org"
gem "cocoapods"
-93
View File
@@ -1,93 +0,0 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.2)
activesupport (5.2.4.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.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.0)
addressable (~> 2.6)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.10.0)
cocoapods-deintegrate (>= 1.0.3, < 2.0)
cocoapods-downloader (>= 1.4.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-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)
nap (~> 1.0)
ruby-macho (~> 1.4)
xcodeproj (>= 1.19.0, < 2.0)
cocoapods-core (1.10.0)
activesupport (> 5.0, < 6)
addressable (~> 2.6)
algoliasearch (~> 1.0)
concurrent-ruby (~> 1.1)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
netrc (~> 0.11)
public_suffix
typhoeus (~> 1.0)
cocoapods-deintegrate (1.0.4)
cocoapods-downloader (1.4.0)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.0)
cocoapods-trunk (1.5.0)
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
cocoapods-try (1.2.0)
colored2 (3.1.2)
concurrent-ruby (1.1.7)
escape (0.0.4)
ethon (0.12.0)
ffi (>= 1.3.0)
ffi (1.13.1)
fourflusher (2.3.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
httpclient (2.8.3)
i18n (1.8.5)
concurrent-ruby (~> 1.0)
json (2.3.1)
minitest (5.14.2)
molinillo (0.6.6)
nanaimo (0.3.0)
nap (1.1.0)
netrc (0.11.0)
public_suffix (4.0.6)
ruby-macho (1.4.0)
thread_safe (0.3.6)
typhoeus (1.4.0)
ethon (>= 0.9.0)
tzinfo (1.2.8)
thread_safe (~> 0.1)
xcodeproj (1.19.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
PLATFORMS
ruby
DEPENDENCIES
cocoapods
BUNDLED WITH
2.0.2
+3 -3
View File
@@ -1,10 +1,10 @@
// swift-tools-version:5.3
// swift-tools-version:5.5
import PackageDescription
let package = Package(
name: "Siren",
platforms: [.iOS(.v11), .tvOS(.v11)],
platforms: [.iOS(.v13), .tvOS(.v13)],
products: [.library(name: "Siren", targets: ["Siren"])],
targets: [.target(name: "Siren", path: "Sources")],
targets: [.target(name: "Siren", path: "Sources", resources: [.copy("Siren.bundle"), .copy("PrivacyInfo.xcprivacy")])],
swiftLanguageVersions: [.v5]
)
+13 -10
View File
@@ -2,9 +2,13 @@
### Notify users when a new version of your app is available and prompt them to upgrade.
[![Travis CI Status](https://travis-ci.org/ArtSabintsev/Siren.svg?branch=master)](https://travis-ci.org/ArtSabintsev/Siren) ![Swift Support](https://img.shields.io/badge/Swift-5.3-orange.svg)
![Swift Support](https://img.shields.io/badge/Swift-5.5-orange.svg) [![CocoaPods](https://img.shields.io/cocoapods/v/Siren.svg)](https://cocoapods.org/pods/Siren) [![SwiftPM Compatible](https://img.shields.io/badge/SwiftPM-compatible-brightgreen.svg)](https://swift.org/package-manager/) [![Accio supported](https://img.shields.io/badge/Accio-supported-0A7CF5.svg?style=flat)](https://github.com/JamitLabs/Accio)
[![CocoaPods](https://img.shields.io/cocoapods/v/Siren.svg)](https://cocoapods.org/pods/Siren) [![SwiftPM Compatible](https://img.shields.io/badge/SwiftPM-compatible-brightgreen.svg)](https://swift.org/package-manager/) [![Accio supported](https://img.shields.io/badge/Accio-supported-0A7CF5.svg?style=flat)](https://github.com/JamitLabs/Accio)
---
# Important Information
I stopped being a proactive iOS engineer in 2021. For the time being, I will keep this library maintained for the community, but I will not be proactively adding features.
---
@@ -46,15 +50,12 @@ Siren is built to work with the [**Semantic Versioning**](https://semver.org/) s
## Features
### Current Features
- [x] CocoaPods, Carthage, and Swift Package Manager Support (see [Installation Instructions](https://github.com/ArtSabintsev/Siren#installation-instructions))
- [x] Compatible with iOS 13+ and tvOS 13+
- [x] CocoaPods and Swift Package Manager Support (see [Installation Instructions](https://github.com/ArtSabintsev/Siren#installation-instructions))
- [x] Three Types of Alerts (see [Screenshots](https://github.com/ArtSabintsev/Siren#screenshots))
- [x] Highly Customizable Presentation Rules (see [Implementation Examples](https://github.com/ArtSabintsev/Siren#implementation-examples))
- [x] Localized for 40+ Languages (see [Localization](https://github.com/ArtSabintsev/Siren#localization))
- [x] Device Compatibility Check (see [Device Compatibility](https://github.com/ArtSabintsev/Siren#device-compatibility))
- [x] 100% Documentation Coverage (see https://sabintsev.com/Siren)
### Future Features
A list of future development work can be found on [Siren's Kanban Board](https://github.com/ArtSabintsev/Siren/projects/1).
---
@@ -86,7 +87,8 @@ A list of future development work can be found on [Siren's Kanban Board](https:/
| Swift Version | Branch Name | Will Continue to Receive Updates?
| ------------- | ------------- | -------------
| 5.1+ | master | **Yes**
| 5.5+ | master | **Yes**
| 5.1-5.4 | swift5.4 | No
| 5.0 | swift5.0 | No
| 4.2 | swift4.2 | No
| 4.1 | swift4.1 | No
@@ -96,7 +98,8 @@ A list of future development work can be found on [Siren's Kanban Board](https:/
### CocoaPods
```ruby
pod 'Siren' # Swift 5.1+
pod 'Siren' # Swift 5.5+
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift5.4' # Swift 5.1-5.4
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift5.0' # Swift 5.0
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift4.2' # Swift 4.2
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift4.1' # Swift 4.1
@@ -107,7 +110,7 @@ pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'sw
### Swift Package Manager
```swift
.Package(url: "https://github.com/ArtSabintsev/Siren.git", majorVersion: 5)
.Package(url: "https://github.com/ArtSabintsev/Siren.git", majorVersion: 6)
```
## Implementation Examples
+8 -7
View File
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
# Version
s.version = "5.6.0"
s.swift_version = "5.3"
s.version = "6.1.3"
s.swift_version = "5.5"
# Meta
s.name = "Siren"
@@ -14,9 +14,10 @@ Pod::Spec.new do |s|
DESC
# Compatibility & Sources
s.platform = :ios, "11.0"
s.source = { :git => "https://github.com/ArtSabintsev/Siren.git", :tag => s.version.to_s }
s.source_files = 'Sources/**/*.swift'
s.resources = 'Sources/Siren.bundle'
s.requires_arc = true
s.ios.deployment_target = '13.0'
s.tvos.deployment_target = '13.0'
s.source = { :git => "https://github.com/ArtSabintsev/Siren.git", :tag => s.version.to_s }
s.source_files = 'Sources/**/*.swift'
s.resources = 'Sources/Siren.bundle'
s.requires_arc = true
end
+4
View File
@@ -82,7 +82,11 @@ private extension Bundle {
///
/// - Returns: The bundle's path or `nil`.
final class func sirenBundlePath() -> String? {
#if SWIFT_PACKAGE
return Bundle.module.path(forResource: "\(Siren.self)", ofType: Constants.bundleExtension)
#else
return Bundle(for: Siren.self).path(forResource: "\(Siren.self)", ofType: Constants.bundleExtension)
#endif
}
/// The path for a particular language localizationin Siren's localization `Bundle`.
+50 -39
View File
@@ -16,19 +16,36 @@ public struct APIManager {
static let bundleID = "bundleId"
/// Constant for the `country` parameter in the iTunes Lookup API request.
static let country = "country"
/// Constant for the `lang` parameter in the iTunes Lookup API request.
static let language = "lang"
/// Constant for the `entity` parameter in the iTunes Lookup API reqeust.
static let entity = "entity"
/// Constant for the `entity` parameter value when performing a tvOS iTunes Lookup API reqeust.
static let tvSoftware = "tvSoftware"
}
/// Return results or errors obtained from performing a version check with Siren.
typealias CompletionHandler = (Result<APIModel, KnownError>) -> Void
/// The Bundle ID for the your application. Defaults to "Bundle.main.bundleIdentifier".
let bundleID: String?
/// The region or country of an App Store in which the app is available.
let country: AppStoreCountry
/// The language for the localization of App Store responses.
let language: String?
/// Initializes `APIManager` to the region or country of an App Store in which the app is available.
/// By default, all version check requests are performed against the US App Store.
/// - Parameter country: The country for the App Store in which the app is available.
public init(country: AppStoreCountry = .unitedStates) {
/// By default, all version check requests are performed against the US App Store and the language of the copy/text is returned in English.
/// - Parameters:
/// - country: The country for the App Store in which the app is available.
/// - language: The locale to use for the App Store notes. The default result the API returns is equivalent to passing "en_us", so passing `nil` is equivalent to passing "en_us".
/// - bundleID: The bundleID for your app. Defaults to `Bundle.main.bundleIdentifier`. Passing `nil` will throw a `missingBundleID` error.
public init(country: AppStoreCountry = .unitedStates, language: String? = nil, bundleID: String? = Bundle.main.bundleIdentifier) {
self.country = country
self.language = language
self.bundleID = bundleID
}
/// The default `APIManager`.
@@ -48,22 +65,19 @@ extension APIManager {
/// Creates and performs a URLRequest against the iTunes Lookup API.
///
/// - Parameter handler: The completion handler for the iTunes Lookup API request.
func performVersionCheckRequest(completion handler: CompletionHandler?) {
guard Bundle.main.bundleIdentifier != nil else {
handler?(.failure(.missingBundleID))
return
/// - returns APIModel: The decoded JSON as an instance of APIModel.
func performVersionCheckRequest() async throws -> APIModel {
guard bundleID != nil else {
throw KnownError.missingBundleID
}
do {
let url = try makeITunesURL()
let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 30)
URLSession.shared.dataTask(with: request) { (data, response, error) in
URLCache.shared.removeCachedResponse(for: request)
self.processVersionCheckResults(withData: data, response: response, error: error, completion: handler)
}.resume()
let (data, response) = try await URLSession.shared.data(for: request)
return try processVersionCheckResults(withData: data, response: response)
} catch {
handler?(.failure(.malformedURL))
throw error
}
}
@@ -72,33 +86,20 @@ extension APIManager {
/// - Parameters:
/// - data: The JSON data returned from the request.
/// - response: The response metadata returned from the request.
/// - error: The error returned from the request.
/// - handler: The completion handler to call once the results of the request has been processed.
private func processVersionCheckResults(withData data: Data?,
response: URLResponse?,
error: Error?,
completion handler: CompletionHandler?) {
if let error = error {
handler?(.failure(.appStoreDataRetrievalFailure(underlyingError: error)))
} else {
guard let data = data else {
handler?(.failure(.appStoreDataRetrievalFailure(underlyingError: nil)))
return
}
do {
let apiModel = try JSONDecoder().decode(APIModel.self, from: data)
private func processVersionCheckResults(withData data: Data?, response: URLResponse?) throws -> APIModel {
guard let data = data else {
throw KnownError.appStoreDataRetrievalFailure(underlyingError: nil)
}
do {
let apiModel = try JSONDecoder().decode(APIModel.self, from: data)
guard !apiModel.results.isEmpty else {
handler?(.failure(.appStoreDataRetrievalEmptyResults))
return
}
DispatchQueue.main.async {
handler?(.success(apiModel))
}
} catch {
handler?(.failure(.appStoreJSONParsingFailure(underlyingError: error)))
guard !apiModel.results.isEmpty else {
throw KnownError.appStoreDataRetrievalEmptyResults
}
return apiModel
} catch {
throw KnownError.appStoreJSONParsingFailure(underlyingError: error)
}
}
@@ -112,12 +113,22 @@ extension APIManager {
components.host = "itunes.apple.com"
components.path = "/lookup"
var items: [URLQueryItem] = [URLQueryItem(name: Constants.bundleID, value: Bundle.main.bundleIdentifier)]
var items: [URLQueryItem] = [URLQueryItem(name: Constants.bundleID, value: bundleID)]
#if os(tvOS)
let tvOSQueryItem = URLQueryItem(name: Constants.entity, value: Constants.tvSoftware)
items.append(tvOSQueryItem)
#endif
if let countryCode = country.code {
let item = URLQueryItem(name: Constants.country, value: countryCode)
items.append(item)
}
if let language = language {
let item = URLQueryItem(name: Constants.language, value: language)
items.append(item)
}
components.queryItems = items
+4 -9
View File
@@ -226,24 +226,19 @@ private extension PresentationManager {
private extension PresentationManager {
private func createWindow() -> UIWindow? {
var window = UIWindow()
if #available(iOS 13.0, *) {
guard let windowScene = getFirstForegroundScene() else { return nil }
window = UIWindow(windowScene: windowScene)
} else {
window = UIWindow(frame: UIScreen.main.bounds)
}
guard let windowScene = getFirstForegroundScene() else { return nil }
let window = UIWindow(windowScene: windowScene)
window.windowLevel = UIWindow.Level.alert + 1
let viewController = SirenViewController()
viewController.retainedWindow = window
window.rootViewController = viewController
return window
}
@available(iOS 13.0, *)
@available(iOS 13.0, tvOS 13.0, *)
private func getFirstForegroundScene() -> UIWindowScene? {
let connectedScenes = UIApplication.shared.connectedScenes
if let windowActiveScene = connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
+2
View File
@@ -98,6 +98,7 @@ extension AppStoreCountry {
public static let kyrgyzstan: AppStoreCountry = "KG"
public static let cambodia: AppStoreCountry = "KH"
public static let stKittsAndNevis: AppStoreCountry = "KN"
public static let korea: AppStoreCountry = "KR"
public static let kuwait: AppStoreCountry = "KW"
public static let caymanIslands: AppStoreCountry = "KY"
public static let kazakhstan: AppStoreCountry = "KZ"
@@ -112,6 +113,7 @@ extension AppStoreCountry {
public static let latvia: AppStoreCountry = "LV"
public static let morocco: AppStoreCountry = "MAR"
public static let moldova: AppStoreCountry = "MD"
public static let maldives: AppStoreCountry = "MDV"
public static let madagascar: AppStoreCountry = "MG"
public static let northMacedonia: AppStoreCountry = "MK"
public static let mali: AppStoreCountry = "ML"
+23
View File
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyTrackingDomains</key>
<array/>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
</array>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
</dict>
</plist>
@@ -1,8 +1,8 @@
/* Update alert message: A new version of {APP NAME} is available. Please update to version {NEW VERSION} now.*/
"A new version of %@ is available. Please update to version %@ now." = "Nova verzia %@ je stigla. Ažuriraj na verziju %@ sada.";
"A new version of %@ is available. Please update to version %@ now." = "Nova verzija %@ je dostupna. Ažuriraj na verziju %@ sada.";
/* Update alert title */
"Update Available" = "Nova ažuriranje je stigla";
"Update Available" = "Novo ažuriranje je dostupno";
/* Update alert dismiss button title */
"Next time" = "Sljedeći put";
@@ -1,5 +1,5 @@
/* Update alert message: A new version of {APP NAME} is available. Please update to version {NEW VERSION} now.*/
"A new version of %@ is available. Please update to version %@ now." = "%@' nın yeni bir sürümü mevcut. Lütfen %@ sürümüne güncelleyin.";
"A new version of %@ is available. Please update to version %@ now." = "%@ uygulamasının yeni bir sürümü mevcut. Lütfen %@ sürümüne güncelleyin.";
/* Update alert title */
"Update Available" = "Güncelleme Mevcut";
+54 -28
View File
@@ -52,12 +52,22 @@ public final class Siren: NSObject {
/// The last date that an alert was presented to the user.
private var alertPresentationDate: Date? = UserDefaults.alertPresentationDate
/// Prevents the update dialog from not displaying when the user swipes down
/// on a notification center notification to the bottom of screen when calling
/// the Siren.shared.wail notificaiton using the `.onForeground` performCheck option.
private var appDidBecomeActiveWorkItem: DispatchWorkItem?
/// The minimal amount of time needed before calling the update notification
/// after entering the app from a notificaiton.
/// Refer to comment in `appDidBecomeActiveWorkItem` for more information.
private let appDidBecomeActiveWorkItemTimeDelay = 0.02
/// The App Store's unique identifier for an app.
private var appID: Int?
/// The completion handler used to return the results or errors returned by Siren.
private var resultsHandler: ResultsHandler?
/// The deinitialization method that clears out all observers,
deinit {
presentationManager.cleanUp()
@@ -81,7 +91,7 @@ public extension Siren {
switch performCheck {
case .onDemand:
removeForegroundObservers()
performVersionCheck()
startVersionCheckFlow()
case .onForeground:
addForegroundObservers()
}
@@ -102,11 +112,7 @@ public extension Siren {
}
DispatchQueue.main.async {
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(url)
}
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
}
@@ -114,16 +120,25 @@ public extension Siren {
// MARK: - Version Check and Alert Presentation Flow
private extension Siren {
/// Initiates the unidirectional version checking flow.
func performVersionCheck() {
/// Initiates the version checking flow.
func startVersionCheckFlow() {
alertPresentationDate = UserDefaults.alertPresentationDate
apiManager.performVersionCheckRequest { result in
switch result {
case .success(let apiModel):
Task {
await performVersionCheck()
}
}
/// Initiatives the version check request.
func performVersionCheck() async {
do {
let apiModel = try await apiManager.performVersionCheckRequest()
DispatchQueue.main.async {
self.validate(apiModel: apiModel)
case .failure(let error):
self.resultsHandler?(.failure(error))
}
} catch (let error as KnownError) {
self.resultsHandler?(.failure(error))
} catch {
// Do nothing. Silences exhaustive error.
}
}
@@ -190,23 +205,25 @@ private extension Siren {
/// - currentAppStoreVersion: The curren version of the app in the App Store.
/// - model: The iTunes Lookup Model.
func determineIfAlertPresentationRulesAreSatisfied(forCurrentAppStoreVersion currentAppStoreVersion: String, andModel model: Model) {
// Did the user:
// - request to skip being prompted with version update alerts for a specific version
// - and is the latest App Store update the same version that was requested?
if let previouslySkippedVersion = UserDefaults.storedSkippedVersion,
let currentInstalledVersion = currentInstalledVersion,
!currentAppStoreVersion.isEmpty,
currentAppStoreVersion == previouslySkippedVersion {
resultsHandler?(.failure(.skipVersionUpdate(installedVersion: currentInstalledVersion,
appStoreVersion: currentAppStoreVersion)))
return
}
let updateType = DataParser.parseForUpdate(forInstalledVersion: currentInstalledVersion,
andAppStoreVersion: currentAppStoreVersion)
do {
let rules = try rulesManager.loadRulesForUpdateType(updateType)
// Did the user:
// - request to skip being prompted with version update alerts for a specific version
// - and is the latest App Store update the same version that was requested
// - and app is not forcing updates?
if let previouslySkippedVersion = UserDefaults.storedSkippedVersion,
let currentInstalledVersion = currentInstalledVersion,
!currentAppStoreVersion.isEmpty,
currentAppStoreVersion == previouslySkippedVersion,
rules.alertType != .force {
resultsHandler?(.failure(.skipVersionUpdate(installedVersion: currentInstalledVersion,
appStoreVersion: currentAppStoreVersion)))
return
}
if rules.frequency == .immediately {
presentAlert(withRules: rules, forCurrentAppStoreVersion: currentAppStoreVersion, model: model, andUpdateType: updateType)
} else {
@@ -277,7 +294,14 @@ private extension Siren {
object: nil,
queue: nil) { [weak self] _ in
guard let self = self else { return }
self.performVersionCheck()
self.appDidBecomeActiveWorkItem = DispatchWorkItem {
Task {
await self.performVersionCheck()
}
}
if let appDidBecomeActiveWorkItem = self.appDidBecomeActiveWorkItem {
DispatchQueue.main.asyncAfter(deadline: .now() + self.appDidBecomeActiveWorkItemTimeDelay, execute: appDidBecomeActiveWorkItem)
}
}
}
@@ -291,6 +315,8 @@ private extension Siren {
object: nil,
queue: nil) { [weak self] _ in
guard let self = self else { return }
self.appDidBecomeActiveWorkItem?.cancel()
self.appDidBecomeActiveWorkItem = nil
self.presentationManager.cleanUp()
}
}
-47
View File
@@ -1,47 +0,0 @@
# APIManager
APIManager for Siren
``` swift
public struct APIManager
```
## Initializers
### `init(country:)`
Initializes `APIManager` to the region or country of an App Store in which the app is available.
By default, all version check requests are performed against the US App Store.
``` swift
public init(country: AppStoreCountry = .unitedStates)
```
#### Parameters
- country: The country for the App Store in which the app is available.
### `init(countryCode:)`
Convenience initializer that initializes `APIManager` to the region or country of an App Store in which the app is available.
If nil, version check requests are performed against the US App Store.
``` swift
public init(countryCode: String?)
```
#### Parameters
- countryCode: The raw country code for the App Store in which the app is available.
## Properties
### `` `default` ``
The default `APIManager`.
``` swift
let `default`
```
The version check is performed against the US App Store.
-41
View File
@@ -1,41 +0,0 @@
# AlertAction
The `UIAlertController` button that was pressed upon being presented an update alert.
``` swift
public enum AlertAction
```
## Enumeration Cases
### `appStore`
The user clicked on the `Update` option, which took them to the app's App Store page.
``` swift
case appStore
```
### `nextTime`
The user clicked on the `Next Time` option, which dismissed the alert.
``` swift
case nextTime
```
### `skip`
The user clicked on the `Skip this version` option, which dismissed the alert.
``` swift
case skip
```
### `unknown`
(Default) The user never chose an option. This is returned when an error is thrown by Siren.
``` swift
case unknown
```
-49
View File
@@ -1,49 +0,0 @@
# AlertConstants
The default constants used for the update alert's messaging.
``` swift
public struct AlertConstants
```
## Properties
### `alertMessage`
The text that conveys the message that there is an app update available
``` swift
let alertMessage = "A new version of %@ is available. Please update to version %@ now."
```
### `alertTitle`
The alert title which defaults to *Update Available*.
``` swift
let alertTitle = "Update Available"
```
### `nextTimeButtonTitle`
The button text that conveys the message that the user should be prompted to update next time the app launches.
``` swift
let nextTimeButtonTitle = "Next time"
```
### `skipButtonTitle`
The text that conveys the message that the the user wants to skip this version update.
``` swift
let skipButtonTitle = "Skip this version"
```
### `updateButtonTitle`
The button text that conveys the message that the user would like to update the app right away.
``` swift
let updateButtonTitle = "Update"
```
File diff suppressed because it is too large Load Diff
-44
View File
@@ -1,44 +0,0 @@
# Types
- [APIManager](/APIManager):
APIManager for Siren
- [PresentationManager](/PresentationManager):
PresentationManager for Siren
- [RulesManager](/RulesManager):
RulesManager for Siren
- [RulesManager.UpdateType](/RulesManager_UpdateType):
Informs Siren of the type of update that is available so that
the appropriate ruleset is used to present the update alert.
- [AlertAction](/AlertAction):
The `UIAlertController` button that was pressed upon being presented an update alert.
- [AlertConstants](/AlertConstants):
The default constants used for the update alert's messaging.
- [AppStoreCountry](/AppStoreCountry):
Region or country of an App Store in which an app can be available.
- [Localization](/Localization):
Localization information and strings for Siren.
- [Localization.Language](/Localization_Language):
Determines the available languages in which the update message and alert button titles should appear.
- [Model](/Model):
The validated and unwrapped `APIModel`.
This model is presented to the end user in Siren's completion handler.
- [PerformCheck](/PerformCheck):
The type of check to perform when Siren's `wail` method is performed.
- [Rules](/Rules):
Alert Presentation Rules for Siren.
- [Rules.AlertType](/Rules_AlertType):
Determines the type of alert to present after a successful version check has been performed.
- [Rules.UpdatePromptFrequency](/Rules_UpdatePromptFrequency):
Determines the frequency in which the user is prompted to update the app
once a new version is available in the App Store and if they have not updated yet.
- [UpdateResults](/UpdateResults):
The relevant metadata returned from Siren upon completing a successful version check.
- [Siren](/Siren):
The Siren Class.
- [KnownError](/KnownError):
Enumerates all potentials errors that Siren can handle.
# Operators
- [==(lhs:rhs:)](/==\(lhs:rhs:\)):
Adds ability to equate instances of `AppStoreCountry` to each other.
-127
View File
@@ -1,127 +0,0 @@
# KnownError
Enumerates all potentials errors that Siren can handle.
``` swift
public enum KnownError
```
## Inheritance
`LocalizedError`
## Enumeration Cases
### `appStoreAppIDFailure`
Error retrieving trackId as the JSON does not contain a 'trackId' key.
``` swift
case appStoreAppIDFailure
```
### `appStoreDataRetrievalEmptyResults`
Error retrieving App Store data as JSON results were empty. Is your app available in the US? If not, change the `countryCode` variable to fix this error.
``` swift
case appStoreDataRetrievalEmptyResults
```
### `appStoreDataRetrievalFailure`
Error retrieving App Store data as an error was returned.
``` swift
case appStoreDataRetrievalFailure(underlyingError: Error?)
```
### `appStoreJSONParsingFailure`
Error parsing App Store JSON data.
``` swift
case appStoreJSONParsingFailure(underlyingError: Error)
```
### `appStoreOSVersionUnsupported`
The version of iOS on the device is lower than that of the one required by the app version update.
``` swift
case appStoreOSVersionUnsupported
```
### `appStoreVersionArrayFailure`
Error retrieving App Store verson number as the JSON does not contain a `version` key.
``` swift
case appStoreVersionArrayFailure
```
### `currentVersionReleaseDate`
The `currentVersionReleaseDate` key is missing in the JSON payload. Please leave an issue on https://github.com/ArtSabintsev/Siren with as many details as possible.
``` swift
case currentVersionReleaseDate
```
### `malformedURL`
One of the iTunes URLs used in Siren is malformed. Please leave an issue on https://github.com/ArtSabintsev/Siren with as many details as possible.
``` swift
case malformedURL
```
### `missingBundleID`
Please make sure that you have set a `Bundle Identifier` in your project.
``` swift
case missingBundleID
```
### `noUpdateAvailable`
No new update available.
``` swift
case noUpdateAvailable
```
### `recentlyPrompted`
Siren will not present an update alert if it performed one too recently. If you would like to present an alert every time Siren is called, please consider setting the `UpdatePromptFrequency.immediately` rule in `RulesManager`
``` swift
case recentlyPrompted
```
### `releasedTooSoon`
The app has been released for X days, but Siren cannot prompt the user until Y (where Y \> X) days have passed.
``` swift
case releasedTooSoon(daysSinceRelease: Int, releasedForDays: Int)
```
### `skipVersionUpdate`
The user has opted to skip updating their current version of the app to the current App Store version.
``` swift
case skipVersionUpdate(installedVersion: String, appStoreVersion: String)
```
## Properties
### `localizedDescription`
The localized description for each error handled by Siren.
``` swift
var localizedDescription: String
```
-69
View File
@@ -1,69 +0,0 @@
# Localization
Localization information and strings for Siren.
``` swift
public struct Localization
```
## Methods
### `alertMessage(forCurrentAppStoreVersion:)`
The localized string for the `UIAlertController`'s message field. .
``` swift
public func alertMessage(forCurrentAppStoreVersion currentAppStoreVersion: String) -> String
```
#### Returns
A localized string for the update message.
### `alertTitle()`
The localized string for the `UIAlertController`'s title field. .
``` swift
public func alertTitle() -> String
```
#### Returns
A localized string for the phrase "Update Available".
### `nextTimeButtonTitle()`
The localized string for the "Next time" `UIAlertAction`.
``` swift
public func nextTimeButtonTitle() -> String
```
#### Returns
A localized string for the phrase "Next time".
### `skipButtonTitle()`
The localized string for the "Skip this version" `UIAlertAction`.
``` swift
public func skipButtonTitle() -> String
```
#### Returns
A localized string for the phrase "Skip this version".
### `updateButtonTitle()`
The localized string for the "Update" `UIAlertAction`.
``` swift
public func updateButtonTitle() -> String
```
#### Returns
A localized string for the phrase "Update".
-360
View File
@@ -1,360 +0,0 @@
# Localization.Language
Determines the available languages in which the update message and alert button titles should appear.
``` swift
public enum Language
```
By default, the operating system's default lanuage setting is used. However, you can force a specific language
by setting the forceLanguageLocalization property before calling checkVersion()
## Inheritance
`String`
## Enumeration Cases
### `arabic`
Arabic Language Localization
``` swift
case arabic
```
### `armenian`
Armenian Language Localization
``` swift
case armenian
```
### `basque`
Basque Language Localization
``` swift
case basque
```
### `chineseSimplified`
Simplified Chinese Language Localization
``` swift
case chineseSimplified
```
### `chineseTraditional`
Traditional Chinese Localization Localization
``` swift
case chineseTraditional
```
### `croatian`
Croatian Language Localization
``` swift
case croatian
```
### `czech`
Czech Language Localization
``` swift
case czech
```
### `danish`
Danish Language Localization
``` swift
case danish
```
### `dutch`
Dutch Language Localization
``` swift
case dutch
```
### `english`
English Language Localization
``` swift
case english
```
### `estonian`
Estonian Language Localization
``` swift
case estonian
```
### `finnish`
Finnish Language Localization
``` swift
case finnish
```
### `french`
French Language Localization
``` swift
case french
```
### `german`
German Language Localization
``` swift
case german
```
### `greek`
Greek Language Localization
``` swift
case greek
```
### `hebrew`
Hebrew Language Localization
``` swift
case hebrew
```
### `hungarian`
Hungarian Language Localization
``` swift
case hungarian
```
### `indonesian`
Indonesian Language Localization
``` swift
case indonesian
```
### `italian`
Italian Language Localization
``` swift
case italian
```
### `japanese`
Japanese Language Localization
``` swift
case japanese
```
### `korean`
Korean Language Localization
``` swift
case korean
```
### `latvian`
Latvian Language Localization
``` swift
case latvian
```
### `lithuanian`
Lithuanian Language Localization
``` swift
case lithuanian
```
### `malay`
Malay Language Localization
``` swift
case malay
```
### `norwegian`
Norwegian Language Localization
``` swift
case norwegian
```
### `persian`
Persian Language Localization
``` swift
case persian
```
### `persianAfghanistan`
Persian (Afghanistan) Language Localization
``` swift
case persianAfghanistan
```
### `persianIran`
Persian (Iran) Language Localization
``` swift
case persianIran
```
### `polish`
Polish Language Localization
``` swift
case polish
```
### `portugueseBrazil`
Brazilian Portuguese Language Localization
``` swift
case portugueseBrazil
```
### `portuguesePortugal`
Portugal's Portuguese Language Localization
``` swift
case portuguesePortugal
```
### `romanian`
Romanian Language Localization
``` swift
case romanian
```
### `russian`
Russian Language Localization
``` swift
case russian
```
### `serbianCyrillic`
Serbian (Cyrillic) Language Localization
``` swift
case serbianCyrillic
```
### `serbianLatin`
Serbian (Latin) Language Localization
``` swift
case serbianLatin
```
### `slovenian`
Slovenian Language Localization
``` swift
case slovenian
```
### `spanish`
Spanish Language Localization
``` swift
case spanish
```
### `swedish`
Swedish Language Localization
``` swift
case swedish
```
### `thai`
Thai Language Localization
``` swift
case thai
```
### `turkish`
Turkish Language Localization
``` swift
case turkish
```
### `urdu`
Urdu Language Localization
``` swift
case urdu
```
### `ukrainian`
Ukranian Language Localization
``` swift
case ukrainian
```
### `vietnamese`
Vietnamese Language Localization
``` swift
case vietnamese
```
-50
View File
@@ -1,50 +0,0 @@
# Model
The validated and unwrapped `APIModel`.
This model is presented to the end user in Siren's completion handler.
``` swift
public struct Model
```
## Properties
### `appID`
The app's App ID.
``` swift
let appID: Int
```
### `currentVersionReleaseDate`
The release date for the latest version of the app.
``` swift
let currentVersionReleaseDate: String
```
### `minimumOSVersion`
The minimum version of iOS that the current version of the app requires.
``` swift
let minimumOSVersion: String
```
### `releaseNotes`
The releases notes from the latest version of the app.
``` swift
let releaseNotes: String?
```
### `version`
The latest version of the app.
``` swift
let version: String
```
-30
View File
@@ -1,30 +0,0 @@
# PerformCheck
The type of check to perform when Siren's `wail` method is performed.
``` swift
public enum PerformCheck
```
>
## Enumeration Cases
### `onDemand`
Performs a version check only when Siren's `wail` method is called,
as the `UIApplication.didBecomeActiveNotification` is ignored.
``` swift
case onDemand
```
### `onForeground`
(DEFAULT) Perform a version check whenever the app enters the foreground.
This value must be set when Siren's `wail` method is called to enable the
`UIApplication.didBecomeActiveNotification` observer.
``` swift
case onForeground
```
-46
View File
@@ -1,46 +0,0 @@
# PresentationManager
PresentationManager for Siren
``` swift
public class PresentationManager
```
## Initializers
### `init(alertTintColor:appName:alertTitle:alertMessage:updateButtonTitle:nextTimeButtonTitle:skipButtonTitle:forceLanguageLocalization:)`
`PresentationManager`'s public initializer.
``` swift
public init(alertTintColor tintColor: UIColor? = nil, appName: String? = nil, alertTitle: String = AlertConstants.alertTitle, alertMessage: String = AlertConstants.alertMessage, updateButtonTitle: String = AlertConstants.updateButtonTitle, nextTimeButtonTitle: String = AlertConstants.nextTimeButtonTitle, skipButtonTitle: String = AlertConstants.skipButtonTitle, forceLanguageLocalization forceLanguage: Localization.Language? = nil)
```
#### Parameters
- tintColor: The alert's tintColor. Settings this to `nil` defaults to the system default color.
- appName: The name of the app (overrides the default/bundled name).
- alertTitle: The title field of the `UIAlertController`.
- alertMessage: The `message` field of the `UIAlertController`.
- nextTimeButtonTitle: The `title` field of the Next Time Button `UIAlertAction`.
- skipButtonTitle: The `title` field of the Skip Button `UIAlertAction`.
- updateButtonTitle: The `title` field of the Update Button `UIAlertAction`.
- forceLanguage: The language the alert to which the alert should be set. If `nil`, it falls back to the device's preferred locale.
## Properties
### `` `default` ``
The default `PresentationManager`.
``` swift
let `default`
```
By default:
- There is no tint color (defaults to Apple's system `blue` color.)
- The name of the app is equal to the name that appears in `Info.plist`.
- The strings are all set to that of the user's device localization (if supported) or it falls back to English.
-76
View File
@@ -1,76 +0,0 @@
# Rules
Alert Presentation Rules for Siren.
``` swift
public struct Rules
```
## Initializers
### `init(promptFrequency:forAlertType:)`
Initializes the alert presentation rules.
``` swift
public init(promptFrequency frequency: UpdatePromptFrequency, forAlertType alertType: AlertType)
```
#### Parameters
- frequency: How often a user should be prompted to update the app once a new version is available in the App Store.
- alertType: The type of alert that should be presented.
## Properties
### `annoying`
Performs a version check immediately, but allows the user to skip updating the app until the next time the app becomes active.
``` swift
var annoying: Rules
```
### `critical`
Performs a version check immediately and forces the user to update the app.
``` swift
var critical: Rules
```
### `` `default` ``
Performs a version check once a day, but allows the user to skip updating the app until
the next time the app becomes active or skipping the update all together until another version is released.
``` swift
var `default`: Rules
```
This is the default setting.
### `hinting`
Performs a version check weekly, but allows the user to skip updating the app until the next time the app becomes active.
``` swift
var hinting: Rules
```
### `persistent`
Performs a version check daily, but allows the user to skip updating the app until the next time the app becomes active.
``` swift
var persistent: Rules
```
### `relaxed`
Performs a version check weekly, but allows the user to skip updating the app until
the next time the app becomes active or skipping the update all together until another version is released.
``` swift
var relaxed: Rules
```
-61
View File
@@ -1,61 +0,0 @@
# RulesManager
RulesManager for Siren
``` swift
public struct RulesManager
```
## Initializers
### `init(majorUpdateRules:minorUpdateRules:patchUpdateRules:revisionUpdateRules:showAlertAfterCurrentVersionHasBeenReleasedForDays:)`
Initializer that sets update-specific `Rules` for all updates (e.g., major, minor, patch, revision).
This means that each of the four update types can have their own specific update rules.
``` swift
public init(majorUpdateRules: Rules = .default, minorUpdateRules: Rules = .default, patchUpdateRules: Rules = .default, revisionUpdateRules: Rules = .default, showAlertAfterCurrentVersionHasBeenReleasedForDays releasedForDays: Int = 1)
```
By default, the `releasedForDays` parameter delays the update alert from being presented for *1 day*
to avoid an issue where the *iTunes Lookup* API response is updated faster than the time it takes for the binary
to become available on App Store CDNs across all regions. Usually it takes 6-24 hours, hence the *1 day* delay.
>
#### Parameters
- rules: The rules that should be set for all version updates.
- releasedForDays: The amount of time (in days) that the app should delay before presenting the user
### `init(globalRules:showAlertAfterCurrentVersionHasBeenReleasedForDays:)`
Initializer that sets the same update `Rules` for all types of updates (e.g., major, minor, patch, revision).
This means that all four update types will use the same presentation rules.
``` swift
public init(globalRules rules: Rules = .default, showAlertAfterCurrentVersionHasBeenReleasedForDays releasedForDays: Int = 1)
```
By default, the `releasedForDays` parameter delays the update alert from being presented for *1 day*
to avoid an issue where the *iTunes Lookup* API response is updated faster than the time it takes for the binary
to become available on App Store CDNs across all regions. Usually it takes 6-24 hours, hence the *1 day* delay.
>
#### Parameters
- rules: The rules that should be set for all version updates.
- releasedForDays: The amount of time (in days) that the app should delay before presenting the user
## Properties
### `` `default` ``
The default `RulesManager`.
``` swift
let `default`
```
By default, the `Rules.default` rule is used for all update typs.
-64
View File
@@ -1,64 +0,0 @@
# RulesManager.UpdateType
Informs Siren of the type of update that is available so that
the appropriate ruleset is used to present the update alert.
``` swift
public enum UpdateType
```
- major: Major release available: A.b.c.d
- minor: Minor release available: a.B.c.d
- patch: Patch release available: a.b.C.d
- revision: Revision release available: a.b.c.D
- unknown: No information available about the update.
## Inheritance
`String`
## Enumeration Cases
### `major`
Major release available: A.b.c.d
``` swift
case major
```
### `minor`
Minor release available: a.B.c.d
``` swift
case minor
```
### `patch`
Patch release available: a.b.C.d
``` swift
case patch
```
### `revision`
Revision release available: a.b.c.D
``` swift
case revision
```
### `unknown`
No information available about the update.
``` swift
case unknown
```
-42
View File
@@ -1,42 +0,0 @@
# Rules.AlertType
Determines the type of alert to present after a successful version check has been performed.
``` swift
enum AlertType
```
## Enumeration Cases
### `force`
Forces the user to update your app (1 button alert).
``` swift
case force
```
### `option`
Presents the user with option to update app now or at next launch (2 button alert).
``` swift
case option
```
### `skip`
Presents the user with option to update the app now, at next launch, or to skip this version all together (3 button alert).
``` swift
case skip
```
### `none`
Doesn't present the alert.
Use this option if you would like to present a custom alert to the end-user.
``` swift
case none
```
-38
View File
@@ -1,38 +0,0 @@
# Rules.UpdatePromptFrequency
Determines the frequency in which the user is prompted to update the app
once a new version is available in the App Store and if they have not updated yet.
``` swift
enum UpdatePromptFrequency
```
## Inheritance
`UInt`
## Enumeration Cases
### `immediately`
Version check performed every time the app is launched.
``` swift
case immediately
```
### `daily`
Version check performed once a day.
``` swift
case daily
```
### `weekly`
Version check performed once a week.
``` swift
case weekly
```
-93
View File
@@ -1,93 +0,0 @@
# Siren
The Siren Class.
``` swift
public final class Siren: NSObject
```
## Inheritance
`NSObject`
## Nested Type Aliases
### `ResultsHandler`
Return results or errors obtained from performing a version check with Siren.
``` swift
public typealias ResultsHandler = (Result<UpdateResults, KnownError>) -> Void
```
## Properties
### `shared`
The Siren singleton. The main point of entry to the Siren library.
``` swift
let shared
```
### `apiManager`
The manager that controls the App Store API that is
used to fetch the latest version of the app.
``` swift
var apiManager: APIManager = .default
```
Defaults to the US App Store.
### `presentationManager`
The manager that controls the update alert's string localization and tint color.
``` swift
var presentationManager: PresentationManager = .default
```
Defaults the string's lange localization to the user's device localization.
### `rulesManager`
The manager that controls the type of alert that should be displayed
and how often an alert should be displayed dpeneding on the type
of update that is available relative to the installed version of the app
(e.g., different rules for major, minor, patch and revision updated can be used).
``` swift
var rulesManager: RulesManager = .default
```
Defaults to performing a version check once a day with an alert that allows
the user to skip updating the app until the next time the app becomes active or
skipping the update all together until another version is released.
## Methods
### `wail(performCheck:completion:)`
This method executes the Siren version checking and alert presentation flow.
``` swift
func wail(performCheck: PerformCheck = .onForeground, completion handler: ResultsHandler? = nil)
```
#### Parameters
- performCheck: Defines how the version check flow is entered. Defaults to `.onForeground`.
- handler: Returns the metadata around a successful version check and interaction with the update modal or it returns nil.
### `launchAppStore()`
Launches the AppStore in two situations when the user clicked the `Update` button in the UIAlertController modal.
``` swift
func launchAppStore()
```
This function is marked `public` as a convenience for those developers who decide to build a custom alert modal
instead of using Siren's prebuilt update alert.
-42
View File
@@ -1,42 +0,0 @@
# UpdateResults
The relevant metadata returned from Siren upon completing a successful version check.
``` swift
public struct UpdateResults
```
## Properties
### `alertAction`
The `UIAlertAction` the user chose upon being presented with the update alert.
Defaults to `unknown` until an alert is actually presented.
``` swift
var alertAction: AlertAction = .unknown
```
### `localization`
The Siren-supported locale that was used for the string in the update alert.
``` swift
let localization: Localization
```
### `model`
The Swift-mapped and unwrapped API model, if a successful version check was performed.
``` swift
let model: Model
```
### `updateType`
The type of update that was returned for the API.
``` swift
var updateType: RulesManager.UpdateType = .unknown
```
-1
View File
@@ -1 +0,0 @@
Generated at 2020-11-21T21:11:33-0500 using [swift-doc](https://github.com/SwiftDocOrg/swift-doc) 1.0.0-beta.5.
-29
View File
@@ -1,29 +0,0 @@
<details>
<summary>Types</summary>
- [APIManager](/APIManager)
- [AlertAction](/AlertAction)
- [AlertConstants](/AlertConstants)
- [AppStoreCountry](/AppStoreCountry)
- [KnownError](/KnownError)
- [Localization](/Localization)
- [Localization.Language](/Localization.Language)
- [Model](/Model)
- [PerformCheck](/PerformCheck)
- [PresentationManager](/PresentationManager)
- [Rules](/Rules)
- [Rules.AlertType](/Rules.AlertType)
- [Rules.UpdatePromptFrequency](/Rules.UpdatePromptFrequency)
- [RulesManager](/RulesManager)
- [RulesManager.UpdateType](/RulesManager.UpdateType)
- [Siren](/Siren)
- [UpdateResults](/UpdateResults)
</details>
<details>
<summary>Operators</summary>
- [==(lhs:rhs:)](/==\(lhs:rhs:\))
</details>