Compare commits

..

482 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
Arthur Sabintsev 9bb7a43b72 Renamed again to revert github issue 2020-11-21 21:12:28 -05:00
Arthur Sabintsev ef8272aa0e Renamed to fix a github cache issue 2020-11-21 21:12:19 -05:00
Arthur Sabintsev d8b9283143 Updated docs 2020-11-21 21:11:48 -05:00
Arthur Sabintsev a8ffb6b410 Re-added how gems are installed 2020-11-21 21:11:02 -05:00
Arthur Sabintsev 4dc392f964 Added docs 2020-11-21 20:56:05 -05:00
Arthur Sabintsev 36fb52a574 Minor changes to structure of repo 2020-11-21 20:55:19 -05:00
Arthur Sabintsev 994e44b4fd Deleted out of date docs. Updated other metadata 2020-11-21 20:53:15 -05:00
Arthur Sabintsev 3340418fba Updated Gems 2020-11-21 20:38:06 -05:00
Arthur Sabintsev d655412b7c Fixed Example project 2020-11-21 20:28:24 -05:00
Arthur Sabintsev 90a052c920 Fixed Example project 2020-11-21 20:27:34 -05:00
Arthur Sabintsev 723f73f371 Fixed Example project 2020-11-21 20:27:16 -05:00
Arthur Sabintsev 784ef62967 Updated sample project. Removed Carthage support. Updated Readme 2020-11-21 14:36:44 -05:00
Arthur Ariel Sabintsev 5680814481 Minor spacing change 2020-11-21 13:30:00 -05:00
Arthur Ariel Sabintsev 4b96af4cfc Project-level updates + AppStoreCountry updates 2020-11-21 13:22:30 -05:00
Harlan Kellaway 48cc0e53d8 Type for App Store country (#352)
* Structured type for AppStore country

* Example usage of AppStoreCountry

* Add all App Store country codes

Co-authored-by: Harlan Kellaway <hkellaway@users.noreply.github.com>
2020-11-20 23:11:31 -05:00
Arthur Ariel Sabintsev 1f6ae4635d Removed iOS 13-specific code that's no longer needed or was never working in SirenVC 2020-10-31 08:40:54 -04:00
Arthur Ariel Sabintsev eeb186481e Merge branch 'master' of https://github.com/ArtSabintsev/Siren 2020-09-20 23:37:10 -04:00
Arthur Ariel Sabintsev aade02d4f6 Update README.md 2020-09-20 23:35:30 -04:00
Arthur Ariel Sabintsev 8a0dd7378a Updated podspec 2020-09-20 23:34:31 -04:00
Arthur Ariel Sabintsev 94d8ffb70f Adds missing state to scene management (#348) 2020-09-20 23:33:24 -04:00
Arthur Ariel Sabintsev a24b0ba657 Updated podspec 2020-07-20 20:15:30 -04:00
Danil Shkarupin 9ec4235c67 Fixed case when system notification is shown when trying to show Siren alert (#342)
* Fixed for case when system notification is shown when trying to show Siren alert

* Made Siren alert window optional for cases when app does not have a foreground scene

Co-authored-by: Danil Shkarupin <shkarupinde@spb.psbank.ru>
2020-07-20 20:14:39 -04:00
Arthur Ariel Sabintsev 918dac71d3 Update README.md 2020-06-14 23:35:54 -04:00
Arthur Ariel Sabintsev e99df968fb Update README.md 2020-06-14 23:32:33 -04:00
Arthur Ariel Sabintsev ce5312f8c8 Updated Package.swift 2020-06-14 23:31:19 -04:00
Arthur Ariel Sabintsev 4430cdd272 Merge branch 'master' of https://github.com/ArtSabintsev/Siren 2020-06-14 23:31:03 -04:00
Arthur Ariel Sabintsev b96dfe3790 Update README.md 2020-06-14 23:30:34 -04:00
Arthur Ariel Sabintsev 1a37f10ef2 Update manifest file 2020-06-13 15:58:39 -04:00
Arthur Ariel Sabintsev c0f7d2375c Updated manifest 2020-06-13 15:29:17 -04:00
Arthur Ariel Sabintsev bb8a8c91cf Updated package.swift 2020-06-12 14:29:51 -04:00
Arthur Ariel Sabintsev 323887c21b Updated Package.swift and manifest 2020-06-12 13:44:31 -04:00
Arthur Ariel Sabintsev d828943e4d Updated package.swift 2020-06-12 12:34:36 -04:00
Arthur Ariel Sabintsev c3eb837d8f Updated manifest...again 2020-06-12 12:20:36 -04:00
Arthur Ariel Sabintsev 4198ad9e89 Updated podspec 2020-06-12 12:17:12 -04:00
Arthur Ariel Sabintsev 69092ff70c Update Package.swift 2020-06-12 12:15:20 -04:00
Arthur Ariel Sabintsev df8f8338b3 Updated Package.swift 2020-06-12 10:57:42 -04:00
Arthur Ariel Sabintsev f44a06cd32 Reverted swift-tools-version 2020-06-12 10:54:01 -04:00
Arthur Ariel Sabintsev 68e60f490b Updated manifest 2020-06-12 10:53:03 -04:00
Arthur Ariel Sabintsev 84ece2335f e-updated Package.swift 2020-06-12 10:50:23 -04:00
Arthur Ariel Sabintsev c607fa72f3 Addressed default swift version issue on clone 2020-06-12 10:46:53 -04:00
Arthur Ariel Sabintsev 2f3ed12e00 Addressed default swift version issue on clone 2020-06-12 10:46:41 -04:00
Arthur Ariel Sabintsev dc9b8bbba4 updated podspec 2020-06-12 10:39:46 -04:00
Arthur Ariel Sabintsev 1b95580ad8 Updated plist 2020-06-12 10:29:12 -04:00
Arthur Ariel Sabintsev d9322bdb4f Updated manifest 2020-06-12 10:26:00 -04:00
Arthur Ariel Sabintsev 434e0cd2a0 Updated manifest 2020-06-12 10:22:35 -04:00
Arthur Ariel Sabintsev 2140c28398 Updated manifest 2020-06-12 10:22:29 -04:00
Arthur Ariel Sabintsev b901930ce5 Minor fixes with respect to Xcode 11.5 2020-06-05 08:37:36 -04:00
Arthur Ariel Sabintsev 90fcde1221 Formatting fixes 2020-04-25 15:54:59 -04:00
Arthur Ariel Sabintsev 357afb22ab Removed unnecessary self. references 2020-03-16 21:59:22 -04:00
Arthur Ariel Sabintsev 93e0f66020 Update README.md 2020-03-05 23:30:11 -05:00
Arthur Ariel Sabintsev 7c952267e8 Create FUNDING.yml 2020-02-21 19:22:06 -05:00
Arthur Ariel Sabintsev 7fc6777d3d Bumped podspec to 5.4.0 2020-02-19 23:28:10 -05:00
Giorgio Fiderio ca3559cd93 Delay updaterWindow creation in the PresentationManager (#327) 2020-02-19 23:26:23 -05:00
Arthur Ariel Sabintsev 3c7d06eac0 Revert "Updated README and sample project to support changes found in 5.3.0. Closes #326"
This reverts commit c62c16f1b9.
2020-02-18 09:40:34 -05:00
Arthur Ariel Sabintsev c62c16f1b9 Updated README and sample project to support changes found in 5.3.0. Closes #326 2020-02-15 20:19:53 -05:00
Arthur Ariel Sabintsev 32de6efe8b Updated podspec 2020-02-10 21:02:09 -05:00
Arthur Ariel Sabintsev acfbf2a2d5 Enabled scenes and fixes warning 2020-02-10 21:01:45 -05:00
kisaha00 ad967116cb Fix Create UIWindow (#325) 2020-02-10 21:00:05 -05:00
Arthur Ariel Sabintsev c114526eb8 Cleaning up project hierarchy 2019-12-04 21:30:42 -05:00
Arthur Ariel Sabintsev 70ad233b78 Updated podspec 2019-10-12 09:55:34 -04:00
Arthur Ariel Sabintsev 2b3c9c067d Potential fix for unblocking the UI in iOS 13 (#314)
* Potential fix for unblocking the UI in iOS 13

* Potential fix for layered alert/window issue
2019-10-12 09:52:47 -04:00
Arthur Ariel Sabintsev 6bd43afc0c Updated podspec 2019-10-06 21:19:06 -04:00
Arthur Ariel Sabintsev be49cd82ff Moved alertAction logic to happen after cleanup, which hopefully solves the iOS 13 multiple alert layering issue 2019-10-06 21:18:45 -04:00
Arthur Ariel Sabintsev 06994a9408 Update README.md 2019-10-03 09:29:13 -04:00
Arthur Ariel Sabintsev dc787a23d7 Update ISSUE_TEMPLATE.md 2019-09-18 16:15:00 -04:00
Arthur Ariel Sabintsev a1d30353df Removed misplaced generic call 2019-09-15 07:51:46 -04:00
Arthur Ariel Sabintsev b19712d8da Update README.md 2019-09-15 00:48:11 -04:00
Arthur Ariel Sabintsev 245fec5abc Merge branch 'master' of https://github.com/ArtSabintsev/Siren 2019-09-15 00:37:28 -04:00
Arthur Ariel Sabintsev 34683f71fb Updated docs 2019-09-15 00:37:23 -04:00
Arthur Ariel Sabintsev 251c186ff3 Update README.md 2019-09-15 00:17:35 -04:00
Arthur Ariel Sabintsev 5b18c1606c Update README.md 2019-09-15 00:11:50 -04:00
Arthur Ariel Sabintsev e1257d9eb6 Updated gem lockfile 2019-09-15 00:02:20 -04:00
Arthur Ariel Sabintsev 516e368e82 Updated docs 2019-09-14 23:51:28 -04:00
Arthur Ariel Sabintsev de01c00d2e Update README.md 2019-09-14 23:48:01 -04:00
Arthur Ariel Sabintsev eb278bc030 Update README.md 2019-09-14 23:47:31 -04:00
Arthur Ariel Sabintsev 367092af09 Xcode 11 / iOS 13 / Swift 5.1 Support (#306)
* Updated package.swift

* Added support for UIScene notifications

* Updated Package.swift

* Updated travis yml for forthcoming xcode11

* Fixed up notifications

* More consolidation of methods

* Updated podspec
2019-09-14 23:43:19 -04:00
Arthur Ariel Sabintsev ef6d9ffa42 Updated package.swift 2019-09-08 10:20:14 -04:00
Arthur Ariel Sabintsev 3375ae2552 Updated podspec 2019-09-02 21:18:03 -04:00
Arthur Ariel Sabintsev 234d558b31 Fixed romanian localization 2019-09-02 21:17:48 -04:00
Arthur Ariel Sabintsev 3ff9fff4c4 Changed smaple project 2019-08-29 08:27:01 -04:00
Arthur Ariel Sabintsev 7b2f451643 Added Romanian language localization. Closes #302. 2019-08-29 08:26:28 -04:00
Arthur Ariel Sabintsev eee3edc923 Update README.md 2019-08-20 20:46:19 -04:00
Arthur Ariel Sabintsev d59fbf6e5f Updated Jazzy Docs 2019-08-17 20:19:18 -04:00
Stavros Schizas f042d70762 Fix misspell words (#301) 2019-08-17 20:18:00 -04:00
Arthur Ariel Sabintsev a034d842de Updated podspec 2019-08-07 21:45:37 -04:00
Arthur Ariel Sabintsev 7470bcd720 Updated Gemfiles 2019-08-07 21:22:00 -04:00
Arthur Ariel Sabintsev 47b0b5381e Updated Package.swift 2019-08-07 21:20:29 -04:00
Arthur Ariel Sabintsev 5ef05950ed Update README.md 2019-07-02 21:32:39 -04:00
Arthur Ariel Sabintsev 84e728d65c Simplified docs to only show public API 2019-07-02 21:24:42 -04:00
Arthur Ariel Sabintsev dcfe7df5ea Removed @objcMembers. 2019-06-26 07:18:11 -04:00
Arthur Ariel Sabintsev a759b4b947 Siren.swift is now visible to Objective-C 2019-06-04 22:04:43 -04:00
Arthur Ariel Sabintsev 5f70d96b2c Updated Gemfile 2019-05-29 21:44:47 -04:00
Arthur Ariel Sabintsev f9bc4dfb4f Update Gemfile 2019-05-14 22:13:52 -04:00
Arthur Ariel Sabintsev 6947b485a5 Updated posepc 2019-05-14 21:29:11 -04:00
Arthur Ariel Sabintsev cb1febdaf3 Fixed same version bug found in #288 (#289)
* Fixed bug found in #288

* Adds throwable function to handle same version error

* Updates docs
2019-05-14 21:28:44 -04:00
Arthur Ariel Sabintsev 2284e63c36 Updated docs 2019-04-24 16:25:18 -04:00
Arthur Ariel Sabintsev af16cbbe20 Update .travis.yml 2019-04-22 16:34:48 -04:00
Arthur Ariel Sabintsev 38f6d9d1b5 Update .travis.yml 2019-04-22 16:10:50 -04:00
Arthur Ariel Sabintsev f9abb391d0 Update README.md 2019-04-19 08:22:51 -04:00
Arthur Ariel Sabintsev a22230707a Update travis.yml file 2019-04-16 21:32:52 -04:00
Arthur Ariel Sabintsev fc155c83d5 Updated podspec 2019-04-16 21:26:14 -04:00
Arthur Ariel Sabintsev 298155897f Updated podspec and docs 2019-04-16 21:23:59 -04:00
Arthur Ariel Sabintsev c9fb91a3ed Update DateExtension to remove whitespaces 2019-04-16 21:20:30 -04:00
Niklas Fahl 07aa46fd1d Fixed issue with date offset calculations due to time zone (#284)
* - added time zone to date formatter for correct date offset calculations

* - added default parameters to days since function

* - naming change in days since function removing Siren specific naming in an extension for Foundation class

* - added documentation for days since function due to parameter changes in function signature

* - back to old function signature
2019-04-16 21:16:43 -04:00
Arthur Ariel Sabintsev 448657eefe Updated lockfile 2019-04-05 11:53:07 -04:00
Arthur Ariel Sabintsev 195de7391e Merge branch 'master' of https://github.com/ArtSabintsev/Siren 2019-04-05 11:49:15 -04:00
Arthur Ariel Sabintsev 4b88e28a99 Travis.yml updates 2019-04-05 11:49:11 -04:00
Cihat Gündüz a420119765 Update SwiftPM manifest file (#281)
* Update SwiftPM manifest file

* [README] Add 'Accio supported' badge
2019-04-02 23:29:59 -04:00
Arthur Ariel Sabintsev 1e759f197b Update README.md 2019-03-30 22:04:08 -04:00
Arthur Ariel Sabintsev 93113a4f2e Update README.md 2019-03-30 22:03:14 -04:00
Arthur Ariel Sabintsev c7df74e190 Fixed info.plist issues 2019-03-29 23:18:45 -04:00
Arthur Ariel Sabintsev 2591c0b3d4 Updated podspec 2019-03-27 23:42:46 -04:00
Arthur Ariel Sabintsev e669f8f5c0 Updated ruby version and gems 2019-03-27 23:41:29 -04:00
Arthur Ariel Sabintsev 77caddd434 Updated Gemfile.lock 2019-03-27 23:17:43 -04:00
Arthur Ariel Sabintsev 8a0c03627c Updated Siren.podspec 2019-03-27 23:17:19 -04:00
Arthur Ariel Sabintsev c8519ea5be Updated readme 2019-03-27 23:16:55 -04:00
Arthur Ariel Sabintsev 5d8f4800e1 Updated README.md 2019-03-27 23:15:47 -04:00
Arthur Ariel Sabintsev 2a4e5ceda3 Swift 5 Implementation and Architecture Changes (#279)
* Compatible with Swift5

* Update button now appears on the right side in .option messages

* Renamed LookupModel to APIModel and made it internal. Created a new Model class that is exposed publicly

* Implemented Result type from Swift5

* Updated docs

* Future proofing travis-ci for when 10.2 is supported
2019-03-27 23:13:06 -04:00
Arthur Ariel Sabintsev a3c7cfa26d Updated imports 2019-03-10 23:42:11 -04:00
Arthur Ariel Sabintsev 8477f5fbe6 Updated podspec 2019-03-10 23:40:40 -04:00
Arthur Ariel Sabintsev 3c036ce559 A couple more import fixes 2019-03-10 23:40:17 -04:00
Thi 212e68969a Fix missing imports (#273) 2019-03-10 23:37:39 -04:00
Arthur Ariel Sabintsev 56a834ee41 Reverted default uncommented example 2019-02-09 22:52:04 -05:00
Arthur Ariel Sabintsev df6174ba06 Simplified oberver methods 2019-02-09 22:50:34 -05:00
Arthur Ariel Sabintsev a11b7f0600 Updated Podspec 2019-02-08 20:42:16 -05:00
Ryoh Tsukahara de971bf52f FIX a conditional statement for the skip action. (#270) 2019-02-08 20:41:52 -05:00
Arthur Ariel Sabintsev 5f00463928 Update README.md 2019-02-02 23:01:12 -05:00
Arthur Ariel Sabintsev cf4274fb16 Update README.md 2019-02-02 22:15:09 -05:00
Arthur Ariel Sabintsev a2cd55d83b Merge branch 'master' of https://github.com/ArtSabintsev/Siren 2019-02-02 16:30:07 -05:00
Arthur Ariel Sabintsev 3c064ffa4e Updated docs 2019-02-02 16:29:55 -05:00
Arthur Ariel Sabintsev 84301d4ba2 Update README.md 2019-02-02 16:28:46 -05:00
Arthur Ariel Sabintsev e226f934c0 Updated podspec to 4.1.1 2019-02-02 16:05:29 -05:00
Arthur Ariel Sabintsev 33b6e60862 Improved documentation in a few places and improved Results type 2019-02-02 16:03:56 -05:00
Arthur Ariel Sabintsev fc64e7aca7 Updated docs and travis file 2019-02-02 15:47:23 -05:00
Arthur Ariel Sabintsev f976791460 Updated Podspec to 4.1.0 2019-02-02 15:34:35 -05:00
Arthur Ariel Sabintsev 2a948f0133 Manual version check and alert presentation (#268)
* Manual version check and alert presentation

* Fixes #267

* Adds the PerformCheck enum

* Added a deinit

* Reverted appdelegate uncommented method

* Updated rule ordering to be alphabetical

* Standardized naming

* emoved extra space

* Updated docs
2019-02-02 15:31:43 -05:00
Morgan Dock 2253c339ff add hinting static rules configuration (#269) 2019-02-02 15:09:50 -05:00
Arthur Ariel Sabintsev 85a8a4141d Removed shouldPerformVersionCheckOnSubsequentLaunch userdefault to fi… (#264)
* Removed shouldPerformVersionCheckOnSubsequentLaunch userdefault to fix NexTime bug

* Updated podspec to 4.0.2
2019-01-10 23:46:26 -05:00
Arthur Ariel Sabintsev fc8d7d80d0 Update README.md 2019-01-08 23:59:05 -05:00
Arthur Ariel Sabintsev 7167868002 Update README.md 2019-01-08 23:55:49 -05:00
Arthur Ariel Sabintsev ced4415181 Update README.md 2019-01-08 20:27:13 -05:00
Arthur Ariel Sabintsev d28f69d7bc Update README.md 2019-01-08 20:24:37 -05:00
Arthur Ariel Sabintsev 790d771a2a Improved AppDelegate examples 2019-01-08 20:14:02 -05:00
Arthur Ariel Sabintsev eed4b9ac41 Reverted example project back to defaultExampleUsingCompletionHandler() 2019-01-05 23:21:37 -05:00
Arthur Ariel Sabintsev cde489c888 Fixed alert layering issue. Fixed function scoping. Added background observer. Updated docs 2019-01-05 23:08:34 -05:00
Arthur Ariel Sabintsev 6c8a47fb17 Update README.md 2019-01-03 10:05:45 -05:00
Arthur Ariel Sabintsev 40fbca14a2 Update README.md 2018-12-28 11:52:47 -05:00
Arthur Ariel Sabintsev c31afc015a Update README.md 2018-12-28 11:45:14 -05:00
Arthur Ariel Sabintsev c508279a0c Update .gitignore 2018-12-27 23:43:23 -05:00
Arthur Ariel Sabintsev 7502760c6e Update README.md 2018-12-27 23:42:54 -05:00
Arthur Ariel Sabintsev eabb29fc8b Updated README 2018-12-27 08:42:43 -05:00
Arthur Ariel Sabintsev cc3b7b6715 Update README.md 2018-12-27 08:41:53 -05:00
Arthur Ariel Sabintsev 1503bcbb1c Update README.md 2018-12-27 08:39:45 -05:00
Arthur Ariel Sabintsev 15872781a8 Update README.md 2018-12-27 08:37:59 -05:00
Arthur Ariel Sabintsev 4286f34b1d Update README.md 2018-12-27 08:37:36 -05:00
Arthur Ariel Sabintsev 78526b17cb Update README.md 2018-12-27 08:36:42 -05:00
Arthur Ariel Sabintsev 217883dc34 Update README.md 2018-12-27 08:36:01 -05:00
Arthur Ariel Sabintsev a492985dcf Update README.md 2018-12-27 08:35:00 -05:00
Arthur Ariel Sabintsev 85c6867a70 Update README.md 2018-12-27 08:34:46 -05:00
Arthur Ariel Sabintsev dbfe20032f Siren 4.0.0 (#250)
* Scoping changes to most utility classes

* Updated docs

* Continued code clean up and file renaming

* Metadata cleanup

* Updated docs

* Updated Siren.podspec to 4.0.0

* Massive overhaul of the localization logic

* Fixed tests

* Updated docs

* Minor cleanup

* Added new Configuration type but have not hooked it up

* Non-working commit for Configuration

* Continued configuration by thinning down Siren's main interface

* Removed singleton and improved window presenting logic

* Removed dead code. Confined utility methods to proper locations

* Updated some documentation

* Rebuilt version checking and alert presentation logic, however skip alert presentation logic is broken

* Fixed skip version logic

* Added default settings

* Removed delegates and added completion handler

* Changed initialization scheme

* Minor changes to initialization

* Fixed tests and error logic

* Minor changes to sample project

* Renamed all managers

* Improved Errors

* Continued cleanup

* Mor cleanup

* Continued cleanup

* Removed Log struct as it is no longer needed. Removed unused helpers. Merged remaining helpers into mainline Siren.swift file

* Began adding more documentation

* Renamed alertManager to presentationManager

* Removed redundant comments

* Changed alphabetical ordering

* Added some more built in rules

* minor improvemeent to VersionCheckFrequency

* Code cleanup

* Added some missing errors

* More robust error handling

* Added more rules

* Changed start to wail

* Added deviceLanguageLocalization

* Added documentation to BundleExtension

* Added DateExtension documentation

* Added UIAlertController extension documentation

* Added UserDefaultsExtension documentation

* Added APIManager documentation

* Added PresentationManager documentation and began adding RulesManager documentation

* Added AlertAction documentation

* Added Results.swift documentation

* Added Rules.swift documentation

* Added documentation to VersionParser and SirenViewController

* Some metadata cleanup

* Lots more documentation

* Moved networking code in APIManagr.swift

* Moved lots of logic out of siren and into PresentationManager and Localization

* More abstraction

* Cleaned up alert presentation

* More cleanup

* minor changres

* App now has less properties, improved uni-directional flow, and tests that account for that

* Continued code modification

* More documentation changes

* More scope changes

* More scope changes

* More documentation

* Fixed app store version null bug

* More changes

* Reorganized code in presentationmanager

* Reorganized code in presentationmanager

* Improved cache handling

* Added a lot more documentation and removed some unnecessary optionality

* Continued adding documentation

* Fixed bug with layering of alert. Tons more documentation

* Finished documenting all functions and properties

* Updated jazzy docs

* Added missing documentation

* Removed superfluous files

* Fixed bugs around prompt frequency. Updated code and documentation around prompt frequency

* Reached 100% of private function and beyond documentation

* Fixed bug arond presenting localized strings vs custom strings

* Added lots of examples to AppDelegate. Updated README. Removed attributed string settings since they never worked

* Documentation updated. Added tons of examples to AppDelegate.swift with comments

* Updated README

* Updated README.md

* Updated README.md

* Updated README.md

* Removed random fragment in readme

* Updated README

* More README updates

* More README updates

* Updated README

* More metadata updates

* Update metadata

* Regenerated jazzy docs
2018-12-26 20:47:03 -05:00
Arthur Ariel Sabintsev 168cc437c1 Update ISSUE_TEMPLATE.md 2018-12-21 22:38:07 -05:00
Arthur Ariel Sabintsev b65d0d9c75 Updated Siren.podspec 2018-12-20 17:21:55 -05:00
ivan aee7eeca8a Update Siren.swift (#254)
* Update Siren.swift

- fixed url session caching issue in performVersionCheck().

* Update Siren.swift

- swapped .reloadIgnoringCacheData caching policy with .reloadIgnoringLocalAndRemoteCacheData in performVersionCheck() method.
2018-12-20 17:17:48 -05:00
ArtSabintsev dc63e9ea2f Updated base ruby-version 2018-11-17 13:50:08 -05:00
Arthur Ariel Sabintsev 121178a603 Update README.md 2018-11-10 10:59:40 -05:00
Arthur Ariel Sabintsev d946ccbc1b Updated Podspec and Contributors docs 2018-11-09 13:03:42 -05:00
Ilija Puaca 608329ec30 Removed print statement from UserDefaults getter (#247) 2018-11-09 13:02:08 -05:00
Arthur Ariel Sabintsev 8686a397dd Update README.md 2018-11-09 13:01:08 -05:00
Arthur Ariel Sabintsev 4dd7941d22 Updated podspec and docs 2018-11-07 21:42:47 -05:00
Arthur Ariel Sabintsev a43d87d0ae Reverted trackId back to Int. Closes #246 2018-11-07 21:41:46 -05:00
Arthur Ariel Sabintsev 9a72fcc164 Minor stylistic change 2018-11-04 07:18:18 -05:00
Arthur Ariel Sabintsev 2b15eb55aa Minor stylistic change 2018-11-04 07:16:23 -05:00
Arthur Ariel Sabintsev 364ba7d755 Updated Gems 2018-11-01 23:36:01 -04:00
Arthur Ariel Sabintsev fb9633cf25 Update Gemfile 2018-11-01 23:22:14 -04:00
Arthur Ariel Sabintsev 417caff8b1 Updated Siren docs 2018-10-29 23:10:36 -04:00
Arthur Ariel Sabintsev a66052c592 Updated docs 2018-10-29 23:09:59 -04:00
Arthur Ariel Sabintsev d152dc4887 Update ISSUE_TEMPLATE.md 2018-10-29 22:51:10 -04:00
Arthur Ariel Sabintsev 7ff3f21945 Update ISSUE_TEMPLATE.md 2018-10-29 22:48:12 -04:00
Arthur Ariel Sabintsev 5b3742175c Update ISSUE_TEMPLATE.md 2018-10-29 22:47:59 -04:00
Arthur Ariel Sabintsev 2e0b11d30a Update ISSUE_TEMPLATE.md 2018-10-29 22:47:45 -04:00
Arthur Ariel Sabintsev 7176b45aed Update ISSUE_TEMPLATE.md 2018-10-29 22:47:12 -04:00
Arthur Ariel Sabintsev 954ce02353 Update ISSUE_TEMPLATE.md 2018-10-26 10:43:09 -04:00
Arthur Ariel Sabintsev a3fbdfaee0 Update ISSUE_TEMPLATE.md 2018-10-26 10:26:35 -04:00
Arthur Ariel Sabintsev 92c8ac45cc Update README.md 2018-10-25 22:37:42 -04:00
Arthur Ariel Sabintsev 63ed8219dc Update README.md 2018-10-25 22:37:35 -04:00
Arthur Ariel Sabintsev 2b482d367c Fixed indentation 2018-10-25 21:18:17 -04:00
Arthur Ariel Sabintsev cc639488b3 Updated lockfile 2018-10-25 20:59:58 -04:00
Arthur Ariel Sabintsev 0772192629 Updated podspec 2018-10-25 20:52:28 -04:00
Arthur Ariel Sabintsev c2449e25a2 Fixed tackId parsing. Added some documentation 2018-10-25 20:50:36 -04:00
Arthur Ariel Sabintsev da0b258863 Update README.md 2018-10-02 08:37:13 -04:00
Arthur Ariel Sabintsev 58da2806a1 Update README.md 2018-09-29 23:08:58 -04:00
Arthur Ariel Sabintsev 25ec41abbd Updated docs 2018-09-29 23:04:40 -04:00
Arthur Ariel Sabintsev 1c9dd88d68 Update README.md 2018-09-29 23:03:55 -04:00
Arthur Ariel Sabintsev dd0966b29b Updated podspec 2018-09-29 00:02:53 -04:00
Arthur Ariel Sabintsev 421eb6802e 100% documentation again 2018-09-29 00:00:26 -04:00
Arthur Ariel Sabintsev 01c33f99d6 Added more docs 2018-09-28 23:51:39 -04:00
Arthur Ariel Sabintsev de925dc477 Added more missing documentation 2018-09-28 23:44:50 -04:00
Arthur Ariel Sabintsev bdf15f9be8 Updated project 2018-09-28 10:02:09 -04:00
Arthur Ariel Sabintsev 8cb742d2a6 Updated docs 2018-09-28 09:59:55 -04:00
Arthur Ariel Sabintsev 2168a4f1fc Updated docs 2018-09-28 09:58:39 -04:00
Arthur Ariel Sabintsev 1febce77dd Updated podspec 2018-09-27 22:22:23 -04:00
Arthur Ariel Sabintsev 2197494481 Removed force unwrapped localization methods 2018-09-27 22:21:42 -04:00
Arthur Ariel Sabintsev 74284809e3 Cleaned up constants file 2018-09-27 21:51:47 -04:00
Arthur Ariel Sabintsev 841d04dafd Removed dead file 2018-09-27 21:47:09 -04:00
Arthur Ariel Sabintsev d4c7baf247 project updates 2018-09-27 21:41:46 -04:00
Arthur Ariel Sabintsev 6f0b8f733c Minor changes 2018-09-27 21:39:09 -04:00
Arthur Ariel Sabintsev f217d5cd73 Further refactoring for Swift 4.2 (#231)
* Began moving code around to clean Siren.swift

* further cleanup of siren.swift

* Removed superfluous test helping function

* More code cleanup

* Added code that potentially fixes old bug about users not being reprompted after NEXT TIME is tapped

* Continued work on UserDefaults changes

* Improved UserDefaults handling

* Fixed UserDefaults comments
2018-09-27 21:37:01 -04:00
Arthur Ariel Sabintsev 7cfd6e788f Update README.md 2018-09-22 15:46:29 -04:00
Arthur Ariel Sabintsev 1a215cc608 Converted SirenAlertMessaging strings to type of NSAttributedString (#228)
* Converted SirenAlertMessaging strings to type of NSAttributedString

* Updated documentation

* Removed whitespace

* Removed more whitespace

* Updated sample code and README

* Updated sample code and README

* Updated sample code and README

* Added some docs

* Updated Gems

* Updated podspec
2018-09-22 15:41:32 -04:00
Arthur Ariel Sabintsev 7e30501d1c Update ISSUE_TEMPLATE.md 2018-09-21 07:53:02 -04:00
Arthur Ariel Sabintsev 6df36c9c8c Update .travis.yml 2018-09-20 08:23:10 -04:00
Arthur Ariel Sabintsev d7bbe9e8a6 Update README.md 2018-09-18 22:14:19 -04:00
Arthur Ariel Sabintsev 62b51d52a5 Removed .build folder 2018-09-18 21:43:19 -04:00
Arthur Ariel Sabintsev 6aa91d26c4 Minor changes 2018-09-18 21:07:44 -04:00
Arthur Ariel Sabintsev beb19f19c0 Updated osx_image to xcode10 2018-09-16 22:16:31 -04:00
Arthur Ariel Sabintsev 6e504a84a0 Updated example project and framework swift_version to 4.2 2018-09-16 21:58:19 -04:00
Arthur Ariel Sabintsev 129bffe9d8 Update README.md 2018-09-16 21:52:35 -04:00
Arthur Ariel Sabintsev cd4328feee Merged with swift4.2 branch 2018-09-16 21:46:26 -04:00
Arthur Ariel Sabintsev 1ac84cafc8 Updated podspec and other files 2018-09-16 21:45:58 -04:00
Arthur Ariel Sabintsev 36bff434f6 Merge branch 'master' into swift4.2 2018-09-16 21:40:38 -04:00
Arthur Ariel Sabintsev 94b319573e Update README.md 2018-08-07 14:17:50 -04:00
Arthur Ariel Sabintsev 43abfabe15 Update README.md 2018-08-04 21:10:50 -04:00
Arthur Ariel Sabintsev 9ac0dea011 Update README.md 2018-08-03 09:25:13 -04:00
Arthur Ariel Sabintsev 9721263f90 Updated project and framework to Swift 4.2. Updated UIWindowLevelAlert reference 2018-08-03 09:23:58 -04:00
Arthur Ariel Sabintsev 124fd715ef Xcode 10b5 fixes. 2018-08-03 08:59:16 -04:00
Arthur Ariel Sabintsev 1c3aee01fd Updated travis.yml 2018-07-28 01:13:26 -04:00
Arthur Ariel Sabintsev fe3b0acb6d Updated travis.yml 2018-07-28 00:54:08 -04:00
Arthur Ariel Sabintsev 509b5c9ca3 Updated travis.yml 2018-07-28 00:47:29 -04:00
Arthur Ariel Sabintsev 9c00d90424 Updated travis.yml 2018-07-28 00:40:01 -04:00
Arthur Ariel Sabintsev b4bba84753 Updated travis.yml 2018-07-27 22:39:40 -04:00
Arthur Ariel Sabintsev 47b95c97e0 Update README.md 2018-07-27 22:31:09 -04:00
Arthur Ariel Sabintsev fedee61c34 Update .travis.yml 2018-07-27 22:30:27 -04:00
Arthur Ariel Sabintsev 0c5c0fd1bf Update README.md 2018-07-25 22:02:40 -04:00
Arthur Ariel Sabintsev f2929ef72b Reverted docs location 2018-07-25 22:02:18 -04:00
Arthur Ariel Sabintsev f19075e6b4 Updated docs. Made certain sequences lazy 2018-07-25 22:00:38 -04:00
Arthur Ariel Sabintsev 4063d7e061 Updated docs and gems 2018-07-25 11:46:42 -04:00
Arthur Ariel Sabintsev 75bf43da3c Merged with downstream 2018-07-24 10:01:39 -04:00
Arthur Ariel Sabintsev 556382e38e Updatdd metadata 2018-07-24 09:59:59 -04:00
Titouan Van Belle de480f9cb8 Update German localisation (#218)
The current translation is not grammatically ideal.
2018-07-24 09:56:48 -04:00
Arthur Ariel Sabintsev 0643cd318c Update README.md 2018-07-04 12:34:34 -04:00
Arthur Ariel Sabintsev c7ffac16a1 Update README.md 2018-07-04 12:34:20 -04:00
Arthur Ariel Sabintsev 0f85e4087a Updated CONTRIBUTORS.md file 2018-07-01 22:33:08 -04:00
Arthur Ariel Sabintsev 1bdffa86fc Updated podspec 2018-07-01 22:29:50 -04:00
Arthur Ariel Sabintsev 8ffc87556c Updated gems 2018-07-01 22:29:19 -04:00
Arthur Ariel Sabintsev 43a5d734c1 Minor changes 2018-07-01 22:28:34 -04:00
Ryan 4fad697cd5 Use method introduced in iOS 10 for opening URLs with UIApplication, when appropriate. (#216) 2018-07-01 22:15:34 -04:00
Arthur Ariel Sabintsev 7ab708edf6 Minor changes after path renames 2018-07-01 21:59:48 -04:00
Arthur Ariel Sabintsev 094b218c1d Renamed example project and tests project 2018-07-01 21:57:26 -04:00
Arthur Ariel Sabintsev 3117731c00 Removed jazzy.yml 2018-06-07 22:52:10 -04:00
Arthur Ariel Sabintsev 3d7ebea02f Merge branch 'master' of https://github.com/ArtSabintsev/Siren 2018-06-07 22:51:35 -04:00
Arthur Ariel Sabintsev 53f32cd3d5 Updated docs 2018-06-07 22:51:33 -04:00
Arthur Ariel Sabintsev af6a9825e1 Update .gitattributes 2018-06-07 22:50:02 -04:00
Arthur Ariel Sabintsev bc570b028e Updated README 2018-06-07 22:48:42 -04:00
Arthur Ariel Sabintsev c37cd6968f Update .gitattributes 2018-06-07 22:47:23 -04:00
Arthur Ariel Sabintsev ef8498a8e6 Updated metadata 2018-06-06 20:51:41 -04:00
Arthur Ariel Sabintsev 10ddcab12c Updated logic slightly. Updated sample bundleId 2018-06-06 20:49:35 -04:00
Arthur Ariel Sabintsev 8344ed8cb3 Merge branch 'master' of https://github.com/ArtSabintsev/Siren 2018-06-06 20:07:38 -04:00
Gabriel Martelo d3668c8943 Localized title (#214)
* Expose localized title

* Update sirenDidDetectNewVersionWithoutAlert delegate method
2018-06-06 20:06:04 -04:00
Arthur Ariel Sabintsev 4def0e9441 Merge branch 'master' of https://github.com/ArtSabintsev/Siren 2018-05-08 19:48:47 -04:00
Arthur Ariel Sabintsev fa692a3912 Update README.md 2018-04-27 23:09:17 -04:00
Arthur Ariel Sabintsev 80a449975b Updated gitattributes 2018-04-27 23:09:02 -04:00
Arthur Ariel Sabintsev 3fd2f93d21 Update README.md 2018-04-27 23:08:41 -04:00
Arthur Ariel Sabintsev 13ad9ba3da Updated gitattributes 2018-04-27 23:04:37 -04:00
Arthur Ariel Sabintsev 31a59a4b3c Added .gitattributes 2018-04-27 23:00:45 -04:00
Arthur Ariel Sabintsev 19f303535c Updated podspec 2018-04-27 22:50:39 -04:00
Arthur Ariel Sabintsev cdfae11e70 SirenDelegate Enhancements (#210)
* SirenDelegate now returns SirenLookupModel

* Updated README and documentation

* Updated README

* Updated .travis.yml file
2018-04-27 22:50:11 -04:00
Arthur Ariel Sabintsev 676b125666 Updated podspec 2018-04-27 22:19:59 -04:00
Arthur Ariel Sabintsev 3032aed434 Updated jazzy and docs 2018-04-27 22:19:35 -04:00
Arthur Ariel Sabintsev a9a5be48e6 Minor enhancements to documentation and SirenLookupModel 2018-04-27 22:10:18 -04:00
Antoine Cœur 6999fefad4 HTTPS when supported (#209) 2018-04-27 12:56:47 -04:00
Arthur Ariel Sabintsev 7ef6584c14 Update README.md 2018-04-27 11:00:05 -04:00
Arthur Ariel Sabintsev ecf41d965c Merge branch 'master' of https://github.com/ArtSabintsev/Siren 2018-04-23 19:59:53 -04:00
Arthur Ariel Sabintsev 4338a2dae2 Updated model to be alphabetical 2018-04-23 19:59:52 -04:00
Arthur Ariel Sabintsev e80a073fe9 Update README.md 2018-04-23 19:57:35 -04:00
Arthur Ariel Sabintsev a1404096bf Updated Siren 2018-04-23 10:23:14 -04:00
Arthur Ariel Sabintsev cef1a7f560 Update README.md 2018-04-23 10:19:26 -04:00
Arthur Ariel Sabintsev 7ef618d402 Update README.md 2018-04-23 10:15:59 -04:00
Arthur Ariel Sabintsev 4b32315ad1 Modified travis.yml file 2018-04-23 10:06:33 -04:00
Arthur Ariel Sabintsev 2504f5efc0 Modified travis.yml file 2018-04-23 09:58:12 -04:00
Arthur Ariel Sabintsev 2acc8ee0c0 Added travis.yml file 2018-04-23 09:53:47 -04:00
Arthur Ariel Sabintsev 2c833b84ee Updated docs and metadata 2018-04-23 09:50:35 -04:00
Arthur Ariel Sabintsev fd5aaabb99 Minor doc change 2018-04-23 09:44:23 -04:00
Arthur Ariel Sabintsev 4eb31510d0 Fixed unowned to weak 2018-04-23 09:40:12 -04:00
Arthur Ariel Sabintsev 8bb784a16b SirenLookupModel now parses releaseNotes. Closes #206. 2018-04-23 09:35:01 -04:00
Arthur Ariel Sabintsev c98b124f73 Update README.md 2018-03-29 16:42:16 -04:00
Arthur Ariel Sabintsev 5e12e74e9c Update README.md 2018-03-29 16:16:09 -04:00
Arthur Ariel Sabintsev 04ad0f1682 Update gemfile 2018-03-29 16:02:46 -04:00
Arthur Ariel Sabintsev 87a58c65de Updated podspec 2018-03-29 16:01:38 -04:00
Arthur Ariel Sabintsev c2e278df55 Updated syntax for 4.1 2018-03-29 15:58:42 -04:00
Arthur Ariel Sabintsev dee7bc8e5e Updated synatx for 4.1. 2018-03-29 15:58:04 -04:00
Arthur Ariel Sabintsev e7fc566b10 Updated docs 2018-03-22 00:30:58 -04:00
Arthur Ariel Sabintsev a4ab45f772 Update README.md 2018-03-14 22:30:06 -04:00
Arthur Ariel Sabintsev c72eaf234c Improved ccoapods compatibility by modernizing podspec 2018-03-14 21:32:52 -04:00
Arthur Ariel Sabintsev edb8906b4d Updated metadata 2018-03-11 22:13:24 -04:00
Txai Wieser b7fb413814 Changed pt-BR text to be less agressive. (#201) 2018-03-11 22:09:52 -04:00
Arthur Ariel Sabintsev 0246ee905a Updated docs 2018-03-10 19:51:58 -05:00
Balázs Vincze 853eed62c4 Check if the return data contains any results (#200) 2018-03-10 19:33:21 -05:00
Arthur Ariel Sabintsev 4725475cfc Update README.md 2018-02-23 09:08:52 -05:00
Arthur Ariel Sabintsev 1d03dc16e1 Updated README 2018-02-21 18:57:17 -05:00
Arthur Ariel Sabintsev 1d3be00440 Updated docs. Closes #198. 2018-02-21 18:56:17 -05:00
Arthur Ariel Sabintsev 42c5ab103d Updated README and podspec 2017-12-08 11:09:23 -05:00
Arthur Ariel Sabintsev a82d13d1a2 Override Siren's Default Copy/Messaging in UIAlertController/UIAlertActionSheet (#187)
* Added SirenAlertMessaging struct to allow for custom overriding of messaging in UIAlertController update modal

* Spacing fix

* Comment updates

* alertMessaging is now long lazy

* Updated Sample message

* Commented sample message

* Updates Keys to Constants
2017-12-08 09:06:08 -07:00
Arthur Ariel Sabintsev 77cda5f933 Updated bundle id 2017-12-07 01:56:49 -05:00
Arthur Ariel Sabintsev a5bd175373 Closes #183. Fixes Country Code App Store URL in comments within AppDelegate. 2017-11-27 10:45:17 -05:00
Arthur Ariel Sabintsev a95766201b Updated Dutch localization 2017-11-21 23:35:30 -05:00
Attia Mo 6a7901f443 Fix Arabic localization. (#182)
* Fix Arabic localization.

* update Arabic localization Tests
2017-11-21 23:28:09 -05:00
Aaron Brager 97b23f2804 Update README with phased rollout options (#181) 2017-11-17 16:54:37 -05:00
Arthur Ariel Sabintsev e475b18892 Updated Contributors docs 2017-11-09 16:07:05 -05:00
Arthur Ariel Sabintsev c41f146a2d Update podspec 2017-11-09 16:05:42 -05:00
NSemakov 12ec30958c Add import UIKit for compilation as static framework. (#179) 2017-11-09 16:04:59 -05:00
Arthur Ariel Sabintsev cdb05f36a1 Update README.md 2017-10-23 21:58:17 -04:00
Arthur Ariel Sabintsev 8a85468354 Updated metadata 2017-10-21 10:37:54 -04:00
Vladislav Jevremović 54e91577a7 'characters' is deprecated in Swift 4 (#176) 2017-10-21 10:36:03 -04:00
Arthur Ariel Sabintsev 171250c580 Updated podspec and Contributors.md file 2017-10-19 23:57:29 -04:00
Dmytro Cheverda 1b07f76f59 Add Ukrainian localization (#175)
* Add Ukrainian localization

* Update tests to cover Ukrainian localization
2017-10-19 23:56:38 -04:00
Arthur Ariel Sabintsev b7819acbd5 Fixed transitive dependency issue by increasing scope from private to fileprivate on a couple variables and functions 2017-10-19 16:14:04 -04:00
Arthur Ariel Sabintsev 2c10d82f7f Updated Podspec 2017-10-15 22:49:05 -04:00
Arthur Ariel Sabintsev d7514471ba SirenError is now Public. Closes #174. 2017-10-15 22:48:47 -04:00
Arthur Ariel Sabintsev b918235b4e Updated podspec 2017-10-12 22:32:44 -04:00
Arthur Ariel Sabintsev 6d1e626036 Re-enabled isUpdateCompatibleWithDeviceOS 2017-10-12 22:19:25 -04:00
Arthur Ariel Sabintsev e235f46b3b Updated podspec 2017-10-11 19:48:02 -04:00
Arthur Ariel Sabintsev 17f9952d8b Updated docs 2017-10-11 19:47:20 -04:00
Arthur Ariel Sabintsev 5abf8ede8d Updated UpdateType and SirenDelegate 2017-10-11 19:45:56 -04:00
Jussi Suojanen 8caddf0f8c Add update type information to custom alert delegate function (#171) 2017-10-11 19:34:16 -04:00
Arthur Ariel Sabintsev f6219ccb90 Merge branch 'master' of https://github.com/ArtSabintsev/Siren 2017-09-13 22:15:13 -04:00
Arthur Ariel Sabintsev 21e5f579e2 Updated Docs 2017-09-13 22:15:09 -04:00
Arthur Ariel Sabintsev 7c7791c17a Update README.md 2017-09-13 20:50:01 -04:00
Arthur Ariel Sabintsev b03b7d12bf Updated metadata 2017-09-13 13:52:52 -04:00
Jason Ash 01e439d523 Resolve accessibility issues (#162)
A few variables and one function had private access and errors were thrown stating they were inaccessible, changed to fileprivate to resolve this issue.
2017-09-13 13:50:48 -04:00
Arthur Ariel Sabintsev 1701df1c72 Update README.md 2017-09-13 08:25:46 -04:00
Arthur Ariel Sabintsev 6d5070cdb4 Updated README 2017-09-13 08:20:19 -04:00
Arthur Ariel Sabintsev 9460160937 README updates 2017-09-13 08:17:53 -04:00
Arthur Ariel Sabintsev afeadfddfa README updates 2017-09-13 08:06:25 -04:00
Arthur Ariel Sabintsev d234e8c472 Swift 4 and Xcode 9 Support (#147)
* Converted to Swift 4 using Xcode 9b1.

* Updated README with Swift 4.0 support

* Swiftier syntax for certain localization methods

* More documentation

* Implemented Swift 4 Access Control rules

* Fixed Urdu Test

* Fixed some project settings. Replaced most JSON parsing with SirenLookupModel, which conforms to codable

* Adds Siren Error. Augments Siren, SirenDelegate. Fixes double alert issue.

* Some docs changes

* Updated docs

* Simplified model

* Removed docs to fix merge conflicts. Will remake after merge

* Fixes for Xcode9b5

* Jazzy docs dump to fix CI

* Tightening up Siren.swift after Xcode 9b5 changes

* Fixed signature for sirenDidFailVersionCheck to take an Error vs NSError

* Updated README

* Minor project level changes

* Updated .swift-version and podspec
2017-09-13 08:04:48 -04:00
Arthur Ariel Sabintsev ca33c8f2c8 Updated README 2017-09-11 20:45:14 -04:00
Arthur Ariel Sabintsev 51eb58d236 Update Gemfile.lock 2017-08-27 15:02:33 -04:00
Arthur Ariel Sabintsev a8311bd6b9 Updated podspec and contributors file 2017-08-27 11:45:39 -04:00
Ryoh Tsukahara f8aa3f5534 WIP: Update ja localization (#159)
* Updated Japanese Localization

* Updated test for Japanese localization
2017-08-27 11:43:16 -04:00
Arthur Ariel Sabintsev eba3e056c2 Updated README and AppDelegate in example app 2017-08-07 19:50:56 -04:00
Arthur Ariel Sabintsev 321ba43a15 Updated docs 2017-08-06 07:07:57 -04:00
Arthur Ariel Sabintsev 0b9bae5cbb Updated podspec to 2.0.7 2017-08-05 13:45:25 -04:00
Arthur Ariel Sabintsev c6b3ece14e Updated podspec to 2.0.7 2017-08-05 13:43:41 -04:00
Arthur Ariel Sabintsev 6203ff3e17 Added SirenLog. Removed assertionFailures on default implementations … (#157)
* Added SirenLog. Removed assertionFailures on default implementations of methods defined by SirenDelegate.

* Exposes launchAppStore
2017-08-05 13:43:06 -04:00
Arthur Ariel Sabintsev f9f9b82668 Updated podspec 2017-07-30 21:49:25 -04:00
Arthur Ariel Sabintsev 59e4b9e113 Update README.md 2017-07-10 11:56:27 -04:00
Arthur Ariel Sabintsev a5a1797cce Changed comment in sample project 2017-07-10 11:48:13 -04:00
Arthur Ariel Sabintsev 9eeb265614 Moved CODEOWNERS 2017-07-07 22:41:05 -04:00
Arthur Ariel Sabintsev 31c0109adb Create CODEOWNERS 2017-07-07 22:39:06 -04:00
Arthur Ariel Sabintsev df3a8fd14f Updated CONTRIBUTORS.md 2017-06-19 14:11:33 -04:00
Arthur Ariel Sabintsev c51fcc851b Added Contributors.md 2017-06-19 14:07:47 -04:00
Arthur Ariel Sabintsev add692995a Updated Metadata files after PR merge 2017-06-19 14:03:47 -04:00
Ryoh Tsukahara 379d4b3d82 Set "en_US_POSIX" as the locale of the date formatter (#150) 2017-06-19 13:57:59 -04:00
Arthur Ariel Sabintsev c402feabf1 Update README.md 2017-06-18 23:05:39 -04:00
Arthur Ariel Sabintsev 1d563f89bf Updated docs 2017-06-15 23:54:42 -04:00
Arthur Ariel Sabintsev 3a4d7dd841 Added Urdu Localization and tests 2017-06-15 23:53:23 -04:00
Arthur Ariel Sabintsev 543a3cc1cb Updated README 2017-06-06 22:32:11 -04:00
Arthur Ariel Sabintsev f44a3ba879 Update README.md 2017-06-05 22:57:39 -04:00
Arthur Ariel Sabintsev 54b1042b5c Updated README with Swift 4.0 support 2017-06-05 22:57:12 -04:00
Arthur Ariel Sabintsev a904ca08df Updated README 2017-06-05 22:39:04 -04:00
Arthur Ariel Sabintsev 6101b30b3e Updated Podspec, Gemfile, Readme, and Contributors 2017-06-04 14:59:05 -04:00
Seyed Mojtaba Hosseini Zeidabadi 208f0ade0a Persian localization added. (#144)
Persian localization tests added.
2017-06-04 14:53:59 -04:00
Arthur Ariel Sabintsev e285ded587 Updated Gemfile 2017-05-29 14:51:37 -04:00
Arthur Ariel Sabintsev f2dc07757c Update CONTRIBUTORS.md 2017-05-29 14:43:21 -04:00
Arthur Ariel Sabintsev 6d7613fa3e Added tests for Czech localization. Updated README and Podspec 2017-05-29 14:42:31 -04:00
premyslvlcek 2352276947 Czech language support added (#143)
Czech translation
2017-05-29 14:38:26 -04:00
Arthur Ariel Sabintsev 28b789f28f Update README.md 2017-05-26 01:57:32 -04:00
Arthur Ariel Sabintsev d14e0ad046 Updated Contributors.md 2017-04-26 10:43:33 -04:00
Arthur Ariel Sabintsev d322afa41a Updated podspec 2017-04-26 10:34:01 -04:00
Txai Wieser a5a95c43af Update pt-BR localization (#140)
In Portuguese from Brazil you say "o aplicativo" (the application) with masculine pronoun, you can say "a aplicação" too but it's not very common, and its a little weird. So "A new version the 'Application'" would be translated to "Uma nova versão DO `Aplicativo`" and NOT "Uma nova versão DA 'Aplicação'"

Thank you! :)
2017-04-26 10:33:17 -04:00
Txai Wieser a6a521c8d1 Fixed Enum cases typo (#139) 2017-04-20 09:49:49 -04:00
Arthur Ariel Sabintsev 18a56fa45e Update README.md 2017-04-08 23:56:26 -04:00
Arthur Ariel Sabintsev 278d9e863e Update README.md 2017-04-08 23:55:37 -04:00
Arthur Ariel Sabintsev ba2bc03263 Update README.md 2017-04-08 03:13:26 -04:00
Arthur Ariel Sabintsev 28aba0f794 Updated gems 2017-04-08 03:11:25 -04:00
Arthur Ariel Sabintsev e8ac4b78e1 Update ISSUE_TEMPLATE.md 2017-04-08 02:30:53 -04:00
Arthur Ariel Sabintsev daaa063c60 Update ISSUE_TEMPLATE.md 2017-04-08 02:25:29 -04:00
Arthur Ariel Sabintsev f339fab54d Update ISSUE_TEMPLATE.md 2017-04-08 02:23:52 -04:00
Arthur Ariel Sabintsev 69d49689ce SirenVersionCheckType is now Siren.VersionCheckType. Updated docs and podspec. 2017-04-08 02:12:18 -04:00
Arthur Ariel Sabintsev bd4b17fafc Updated docs 2017-04-08 02:09:18 -04:00
Arthur Ariel Sabintsev 950830d94d Merge pull request #136 from ArtSabintsev/improvement/delayed-launch
2.0.0
2017-04-08 01:50:29 -04:00
Arthur Ariel Sabintsev 11bfdca77a README updates 2017-04-08 01:49:54 -04:00
Arthur Ariel Sabintsev 3e1aa263cb Updated readme and sample project 2017-04-08 01:46:39 -04:00
Arthur Ariel Sabintsev 628ff9bb8d Updated sample project, readme, podspec, project hierarchy 2017-04-08 01:41:49 -04:00
Arthur Ariel Sabintsev 4dd92112eb Added JSONKeys 2017-04-08 01:23:51 -04:00
Arthur Ariel Sabintsev 7c5f153e1f printMessage change 2017-04-08 01:11:56 -04:00
Arthur Ariel Sabintsev 3717686bf8 Documentation changes and sanity check 2017-04-08 01:05:15 -04:00
Arthur Ariel Sabintsev 404e61bcf2 Removed extra new line 2017-04-08 00:58:44 -04:00
Arthur Ariel Sabintsev 4d4fb66fd1 showAlertAfterCurrentVersionHasBeenReleasedForDays is a non-optional Int defaulting to 1 day. Added SirenTestHelper 2017-04-08 00:57:49 -04:00
Arthur Ariel Sabintsev 43232c3e94 Updated swiftlint rules 2017-04-08 00:26:00 -04:00
Arthur Ariel Sabintsev 04ecdc5d86 Updated swiftlint rules 2017-04-08 00:22:56 -04:00
Arthur Ariel Sabintsev c14ffbeaca Updated tests 2017-04-08 00:22:08 -04:00
Arthur Ariel Sabintsev c6dd2e38d9 Created SirenDelegate. Better namespacing 2017-04-08 00:21:28 -04:00
Arthur Ariel Sabintsev f37197e2d6 Removed unncessary self declarations 2017-04-07 23:56:56 -04:00
Arthur Ariel Sabintsev 1301d13b19 Update README.md 2017-04-03 18:49:31 -04:00
Arthur Ariel Sabintsev 868fd61abb Update README.md 2017-03-22 18:35:50 -04:00
Arthur Ariel Sabintsev fd3160ead2 Update README.md 2017-03-22 18:35:01 -04:00
Arthur Ariel Sabintsev bbf166c41e Updated Docs 2017-03-22 00:19:29 -04:00
Arthur Ariel Sabintsev fa410383fb Update README.md 2017-03-21 23:37:07 -04:00
Arthur Ariel Sabintsev 28f7595712 Update README.md 2017-03-21 23:36:38 -04:00
Arthur Ariel Sabintsev d49d41a147 Updated README 2017-03-21 23:34:58 -04:00
Arthur Ariel Sabintsev 4a329bafff Updated Podspec 2017-03-21 23:31:06 -04:00
Arthur Ariel Sabintsev 4569b1352c Merge pull request #134 from ArtSabintsev/improvement/Date-Extension-Safety
Added SirenDateExtension. Improved app safety.
2017-03-21 23:30:19 -04:00
Arthur Ariel Sabintsev 2632a9b661 Added SirenDateExtension. Improved app safety. 2017-03-21 23:26:07 -04:00
Arthur Ariel Sabintsev 74f266aaf0 Updated Podspec and README 2017-03-21 23:12:13 -04:00
Arthur Ariel Sabintsev 7a66d39eaa Added assets 2017-03-18 00:27:43 -04:00
Arthur Ariel Sabintsev 5ee91398b4 Updated Docs. Update scoping in extension files. 2017-03-18 00:19:35 -04:00
Arthur Ariel Sabintsev 2238ed76d9 Modified podspec 2017-03-18 00:12:06 -04:00
Arthur Ariel Sabintsev 77fec7c466 Merge pull request #131 from ArtSabintsev/improvement/codebase
Split code into separate files
2017-03-17 23:29:55 -04:00
Arthur Ariel Sabintsev 95b35eb045 Split code into separate files 2017-03-17 23:26:52 -04:00
Arthur Ariel Sabintsev cf99475842 Updated README 2017-03-14 17:10:35 -04:00
Arthur Ariel Sabintsev dee148be33 Update ISSUE_TEMPLATE.md 2017-03-13 11:35:18 -04:00
Arthur Ariel Sabintsev cb3e865e96 Update README.md 2017-03-11 23:49:03 -05:00
Arthur Ariel Sabintsev ef8f6e1a8e Removed dead links in project 2017-03-04 22:52:20 -05:00
Arthur Ariel Sabintsev 98dd98b8b5 Update README.md 2017-03-04 22:27:39 -05:00
Arthur Ariel Sabintsev 3d5775a00f Updated podspec 2017-03-04 22:24:28 -05:00
Arthur Ariel Sabintsev 5f0c8419c8 Fixed Carthage support 2017-03-04 22:24:04 -05:00
Arthur Ariel Sabintsev 474c84222b Merge branch 'master' of https://github.com/ArtSabintsev/Siren 2017-03-04 02:14:30 -05:00
Arthur Ariel Sabintsev 1a868a150e Updated for Swift PM support 2017-03-04 02:14:28 -05:00
Arthur Ariel Sabintsev 2d29f1cc2c Update README.md 2017-03-04 01:33:26 -05:00
Arthur Ariel Sabintsev 9d98c4679c Updated README 2017-03-04 01:01:21 -05:00
Arthur Ariel Sabintsev 3a47bd871b Updated README 2017-03-04 01:00:45 -05:00
193 changed files with 5292 additions and 10818 deletions
+1
View File
@@ -0,0 +1 @@
Docs/* linguist-vendored
+1
View File
@@ -0,0 +1 @@
* @artsabintsev
+25 -7
View File
@@ -1,10 +1,28 @@
======
Before posting an issue, please make sure your issue has not already been resolved or answered elsehwere.
## If you're experiencing a problem integrating Siren into your app, please provide the following information when posting a new issue:
Common Issue:
> "Error retrieving iOS version number as there was no data returned."
- **Are you using the [latest version](https://github.com/ArtSabintsev/Siren/releases) of Siren?**:
- **What is your app's Bundle ID?**:
- **When was the latest version of your app published to the App Store?**:
- **Is your app published in the US App Store? If not, what App Store is it published in?**:
- **Does Siren work if you plugin your app's `BundleID` (and `countryCode`, if necessary) into the Example app?**:
Check if your app is available in the US App Store, otherwise add the corresponding country code when setting up Siren: https://github.com/ArtSabintsev/Siren/blob/master/Siren/Siren.swift#L198
---
Please delete this text before submitting a new issue.
======
## Before posting an issue, please make sure your issue has not already been resolved or answered elsewhere.
### Common Issue #1:
>"Error retrieving iOS version number as there was no data returned."
Check if your app is available in the US App Store, otherwise add the corresponding country code when setting up Siren.
### Common Issue #2:
> "Support for macOS App Store."
Siren does not and will not support the macOS App Store.
### Common Issue #3:
> "Support for prompting TestFlight users to update to the newest beta build."
Siren does not support this functionality. There is no publicly accessible TestFlight API akin to that of the public App Store API that Siren can utilize to provide this functionality.
# Please delete this text before submitting a new issue.
+45 -6
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,19 +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:
# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
# 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
-7
View File
@@ -1,7 +0,0 @@
module: Siren
author: Arthur Ariel Sabintsev
author_url: http://www.sabintsev.com
github_url: https://github.com/artsabintsev/siren
copyright: "© 2015-2017 [Arthur Ariel Sabintsev](http://www.sabintsev.com)"
clean: true
podspec: Siren.podspec
-1
View File
@@ -1 +0,0 @@
3.0
+7 -4
View File
@@ -1,10 +1,13 @@
reporter: "xcode"
included:
- ../Siren/
- ../Sources/
- Example/Tests/
disabled_rules:
- cyclomatic_complexity
- identifier_name
- file_length
- line_length
- variable_name
reporter: "xcode"
- nesting
- unused_optional_binding
@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "self:/Users/Arthur/Documents/oss/siren/Sample App/SirenExample.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
+16
View File
@@ -0,0 +1,16 @@
language: swift
osx_image: xcode11
notifications:
email: false
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 -workspace Example.xcworkspace -scheme Example -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO
Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

-63
View File
@@ -1,63 +0,0 @@
### Creators
[Arthur Ariel Sabintsev](http://www.sabintsev.com/) and [Aaron Brager](http://twitter.com/GetAaron)
### Siren Project Contributors
- [Dmitry Bespalov](https://github.com/diamondsky) for [Pull Request #7](https://github.com/ArtSabintsev/Siren/pull/7)
- [Daniel Bauke](https://github.com/bonkey) for [Pull Request #8](https://github.com/ArtSabintsev/Siren/pull/8)
- [ipedro](https://github.com/ipedro) for [Pull Request #76 (Harpy)](https://github.com/ArtSabintsev/Harpy/pull/76)
- [Michael Graff](http://github.com/skandragon) for [Pull Request #15](https://github.com/ArtSabintsev/Siren/pull/15)
- [Jaroslav_](https://github.com/jaroslavas) for [Pull Request #83 (Harpy)](https://github.com/ArtSabintsev/Harpy/pull/83)
- [Dylan Bettermann](https://github.com/dbettermann) for [Pull Request #18](https://github.com/ArtSabintsev/Siren/pull/18)
- [Daniel](https://github.com/Daniel) for [Pull Request #21](https://github.com/ArtSabintsev/Siren/pull/21)
- [nagaho](https://github.com/nagaho) for [Pull Request #22](https://github.com/ArtSabintsev/Siren/pull/22)
- [Parnsind Hantrakool](https://github.com/kong707) for [Pull Request #91 (Harpy)](https://github.com/ArtSabintsev/Harpy/issues/91)
- [Tibor Molnár](https://github.com/fatalaa) for [Pull Request #96 (Harpy)](https://github.com/ArtSabintsev/Harpy/issues/96)
- [Tanel Suurhans](https://github.com/tanelsuurhans) and [Jaroslav_](https://github.com/jaroslavas) for [Pull Request #99 (Harpy)](https://github.com/ArtSabintsev/Harpy/issues/99)
- [Zaid M. Said](https://github.com/SentulAsia) for [Pull Request #36](https://github.com/ArtSabintsev/Siren/pull/36)
- [Vahan Margaryan](https://github.com/VahanMargaryan) for [Pull Request #37](https://github.com/ArtSabintsev/Siren/pull/37)
- [Justus Kandzi](https://github.com/jkandzi) for [Pull Request #108 (Harpy)](https://github.com/ArtSabintsev/Harpy/pull/108)
- [Maxim-Inv](https://github.com/Maxim-Inv) for [Pull Request #40](https://github.com/ArtSabintsev/Siren/pull/40)
- [Dirk van Oosterbosch](https://github.com/irlabs) for [Pull Request #54](https://github.com/ArtSabintsev/Siren/pull/54) and [Pull Request #55](https://github.com/ArtSabintsev/Siren/pull/55)
- [pavankataria](https://github.com/pavankataria) for [Pull Request #63](https://github.com/ArtSabintsev/Siren/pull/63)
- [attilat85](https://github.com/attilat85) for [Pull Request #124 (Harpy)](https://github.com/ArtSabintsev/Harpy/pull/124)
- [Vahan Margaryan](https://github.com/VahanMargaryan) for [Pull Request #71](https://github.com/ArtSabintsev/Siren/pull/71)
- [Josip Injic](https://github.com/jinjic) for [Pull Request #73](https://github.com/ArtSabintsev/Siren/pull/73)
- [Thi](https://github.com/thii) for [Pull Request #78](https://github.com/ArtSabintsev/Siren/pull/78)
- [Ilija Puaca](https://github.com/ilijapuaca) for [Pull Request #141 (Harpy)](https://github.com/ArtSabintsev/Harpy/pull/141)
- [thii](https://github.com/ilijapuaca) for [Pull Request #83](https://github.com/ArtSabintsev/Siren/pull/83)
- [Kristaps Grinbergs](https://github.com/fassko) for [Pull Request #90](https://github.com/ArtSabintsev/Siren/pull/90)
- [Luciano Nascimento](https://github.com/@lucianocn) for [Pull Request #146 (Harpy)](https://github.com/ArtSabintsev/Harpy/pull/146)
- [Stefan Kieleithner](https://github.com/steviki) for [Pull Request #97](https://github.com/ArtSabintsev/Siren/pull/97)
- [Vladislav Jevremović](https://github.com/VladislavJevremovic) for [Pull Request #98](https://github.com/ArtSabintsev/Siren/pull/98)
- [Stefan Kieleithner](https://github.com/steviki) for [Pull Request #99](https://github.com/ArtSabintsev/Siren/pull/99)
- [Konstantinos N.](https://github.com/kwstasna) for [Pull Request #101](https://github.com/ArtSabintsev/Siren/pull/101)
- [Christoph Mantler](https://github.com/ChrisixFlash) for [Pull Request #103](https://github.com/ArtSabintsev/Siren/pull/103)
- [Christoph Mantler](https://github.com/ChrisixFlash) for [Pull Request #106](https://github.com/ArtSabintsev/Siren/pull/106)
- [Pietro D'Alessandro](https://github.com/xedla) for [Pull Request #107](https://github.com/ArtSabintsev/Siren/pull/107)
### Harpy Project Contributors
This repo is a Swift language port of [Harpy](http://github.com/ArtSabintsev/Harpy). We couldn't have built this port without acknowledging the following developers who were instrumental in getting Harpy to v3.2.1, the version of Harpy that Siren was based on.
A huge **Thank You** to the following developers:
- [Borut Tomažin](https://github.com/borut-t)
- [Bertie Liu](https://github.com/https://github.com/aceisScope)
- [Burakkilic](https://github.com/burakkilic)
- [Claas Lange](https://github.com/claaslange)
- [Daniel](https://github.com/danieltskv)
- [David Keegan](https://github.com/kgn)
- [Erick](https://github.com/dexcell0)
- [Ercillagorka](https://github.com/ercillagorka)
- [Jamie Ly](http://github,com/jamiely)
- [Jon Andersen](https://github.com/jonandersen)
- [Josh T. Brown](https://github.com/joshuatbrown)
- [Mark Rickert](https://github.com/markrickert)
- [Patrick Debois](https://github.com/jedi4ever)
- [Pius Uzamere](https://github.com/pius)
- [Rahul Jiresal](https://github.com/rahuljiresal)
- [Rui Peres](https://github.com/RuiAAPeres)
- [Thomas Hempel](https://github.com/thomashempel)
- [TrentW](https://github.com/trentw)
### Special Thanks
Finally, a massive **Thank You** to [Aaron Brager](http://twitter.com/GetAaron) for the dev-work and issue-moderation he's done on Harpy since 2012. A Swift port could not have happened without him.
@@ -7,14 +7,14 @@
objects = {
/* Begin PBXBuildFile section */
3FE098CD6A77A275505E4EA0 /* Pods_SirenExample_SirenExampleTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D09EBE9EBE5F60D1F8FB92E3 /* Pods_SirenExample_SirenExampleTests.framework */; };
5913ECF89C0DE3BEB22031BE /* Pods_Example_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3207656F9030B2912198AF2E /* Pods_Example_Tests.framework */; };
8E1635A91E6A0B9C0060CE27 /* SirenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EE6C74C1E6A0AE100DBE454 /* SirenTests.swift */; };
8EBDF8251E6A0C41006C87B4 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8EBDF8211E6A0C41006C87B4 /* LaunchScreen.xib */; };
8EBDF8261E6A0C41006C87B4 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8EBDF8231E6A0C41006C87B4 /* Main.storyboard */; };
8EE6C7431E6A0AA500DBE454 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EE6C7411E6A0AA500DBE454 /* AppDelegate.swift */; };
8EE6C7441E6A0AA500DBE454 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EE6C7421E6A0AA500DBE454 /* ViewController.swift */; };
8EE6C7481E6A0AB800DBE454 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8EE6C7461E6A0AB800DBE454 /* Images.xcassets */; };
CAA1757776EDFC5110EF9093 /* Pods_SirenExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BA741D9C16473F5089F50DCE /* Pods_SirenExample.framework */; };
8EACA9711F380294003134CA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8EACA9671F37F2D3003134CA /* LaunchScreen.xib */; };
8EACA9721F380294003134CA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8EACA9691F37F2D3003134CA /* Main.storyboard */; };
8EACA9731F380294003134CA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8EACA96B1F37F2D3003134CA /* Images.xcassets */; };
8EACA9741F38029B003134CA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EACA9661F37F2D3003134CA /* AppDelegate.swift */; };
8EACA9751F38029B003134CA /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EACA96D1F37F2D3003134CA /* ViewController.swift */; };
E7269D91A22F64E1A0C661C5 /* Pods_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37940350BF612EEBD59D5DF4 /* Pods_Example.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -28,7 +28,7 @@
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
558455D81C6690B4004BE492 /* Embed Frameworks */ = {
8EF9F892224EB00200B20545 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
@@ -41,22 +41,24 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
78A551479948AAC7089950DB /* Pods-SirenExample-SirenExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SirenExample-SirenExampleTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-SirenExample-SirenExampleTests/Pods-SirenExample-SirenExampleTests.release.xcconfig"; sourceTree = "<group>"; };
8E3A6C041D07CB6F00A8B7CF /* SirenExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SirenExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
8EBDF8221E6A0C41006C87B4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = SirenExample/Base.lproj/LaunchScreen.xib; sourceTree = SOURCE_ROOT; };
8EBDF8241E6A0C41006C87B4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = SirenExample/Base.lproj/Main.storyboard; sourceTree = SOURCE_ROOT; };
8EC391811A58B465001C121E /* SirenExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SirenExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
8EE6C7411E6A0AA500DBE454 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = SirenExample/AppDelegate.swift; sourceTree = SOURCE_ROOT; };
8EE6C7421E6A0AA500DBE454 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ViewController.swift; path = SirenExample/ViewController.swift; sourceTree = SOURCE_ROOT; };
8EE6C7461E6A0AB800DBE454 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = SirenExample/Images.xcassets; sourceTree = SOURCE_ROOT; };
8EE6C7471E6A0AB800DBE454 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = SirenExample/Info.plist; sourceTree = SOURCE_ROOT; };
3008B0CC506A71223653ED92 /* Pods-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.release.xcconfig"; path = "Target Support Files/Pods-Tests/Pods-Tests.release.xcconfig"; sourceTree = "<group>"; };
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; };
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; };
8EACA9661F37F2D3003134CA /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
8EACA9681F37F2D3003134CA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
8EACA96A1F37F2D3003134CA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
8EACA96B1F37F2D3003134CA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
8EACA96C1F37F2D3003134CA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
8EACA96D1F37F2D3003134CA /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
8EC391811A58B465001C121E /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
8EE6C74B1E6A0AE100DBE454 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
8EE6C74C1E6A0AE100DBE454 /* SirenTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SirenTests.swift; sourceTree = "<group>"; };
A3B7BC14BE83C3ECC35CE7F0 /* Pods-SirenExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SirenExample.release.xcconfig"; path = "Pods/Target Support Files/Pods-SirenExample/Pods-SirenExample.release.xcconfig"; sourceTree = "<group>"; };
BA741D9C16473F5089F50DCE /* Pods_SirenExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SirenExample.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D09EBE9EBE5F60D1F8FB92E3 /* Pods_SirenExample_SirenExampleTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SirenExample_SirenExampleTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D38FD6B912E9B6CB22B52416 /* Pods-SirenExample-SirenExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SirenExample-SirenExampleTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SirenExample-SirenExampleTests/Pods-SirenExample-SirenExampleTests.debug.xcconfig"; sourceTree = "<group>"; };
D6F83899DD66820E60E4D8D7 /* Pods-SirenExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SirenExample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SirenExample/Pods-SirenExample.debug.xcconfig"; sourceTree = "<group>"; };
E83E47CD9052083916E39F84 /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.release.xcconfig"; path = "Target Support Files/Pods-Example/Pods-Example.release.xcconfig"; sourceTree = "<group>"; };
EA761E9782C2024D152342D4 /* Pods-Example-Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-Tests.debug.xcconfig"; path = "Target Support Files/Pods-Example-Tests/Pods-Example-Tests.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -64,7 +66,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
3FE098CD6A77A275505E4EA0 /* Pods_SirenExample_SirenExampleTests.framework in Frameworks */,
5913ECF89C0DE3BEB22031BE /* Pods_Example_Tests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -72,120 +74,127 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
CAA1757776EDFC5110EF9093 /* Pods_SirenExample.framework in Frameworks */,
E7269D91A22F64E1A0C661C5 /* Pods_Example.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
8E1005DE1A5DD02300509B14 /* SirenExample */ = {
781697C27F2F128F70738C30 /* Pods */ = {
isa = PBXGroup;
children = (
8EE6C7411E6A0AA500DBE454 /* AppDelegate.swift */,
8EE6C7421E6A0AA500DBE454 /* ViewController.swift */,
8EBDF8211E6A0C41006C87B4 /* LaunchScreen.xib */,
8EBDF8231E6A0C41006C87B4 /* Main.storyboard */,
8EE6C7461E6A0AB800DBE454 /* Images.xcassets */,
8EE6C7471E6A0AB800DBE454 /* Info.plist */,
740DAA3321466F1ABE6CC37D /* Pods-Example.debug.xcconfig */,
E83E47CD9052083916E39F84 /* Pods-Example.release.xcconfig */,
5A65216266BE44478A3B3AEB /* Pods-Tests.debug.xcconfig */,
3008B0CC506A71223653ED92 /* Pods-Tests.release.xcconfig */,
EA761E9782C2024D152342D4 /* Pods-Example-Tests.debug.xcconfig */,
31A1A1D27EA05F1E28033516 /* Pods-Example-Tests.release.xcconfig */,
);
name = SirenExample;
path = "Sample App";
path = Pods;
sourceTree = "<group>";
};
8E641D2420C8B44B00908555 /* Frameworks */ = {
isa = PBXGroup;
children = (
37940350BF612EEBD59D5DF4 /* Pods_Example.framework */,
3207656F9030B2912198AF2E /* Pods_Example_Tests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
8EACA9651F37F2D3003134CA /* Example */ = {
isa = PBXGroup;
children = (
8EACA9661F37F2D3003134CA /* AppDelegate.swift */,
8EACA96E1F37F2DD003134CA /* Supporting Files */,
);
path = Example;
sourceTree = "<group>";
};
8EACA96E1F37F2DD003134CA /* Supporting Files */ = {
isa = PBXGroup;
children = (
8EACA9671F37F2D3003134CA /* LaunchScreen.xib */,
8EACA9691F37F2D3003134CA /* Main.storyboard */,
8EACA96B1F37F2D3003134CA /* Images.xcassets */,
8EACA96C1F37F2D3003134CA /* Info.plist */,
8EACA96D1F37F2D3003134CA /* ViewController.swift */,
);
path = "Supporting Files";
sourceTree = "<group>";
};
8EC391781A58B465001C121E = {
isa = PBXGroup;
children = (
8E1005DE1A5DD02300509B14 /* SirenExample */,
8EE6C74A1E6A0AE100DBE454 /* SirenExampleTests */,
8EACA9651F37F2D3003134CA /* Example */,
8EE6C74A1E6A0AE100DBE454 /* Tests */,
8EC391821A58B465001C121E /* Products */,
9883644C6938DD7B325CF897 /* Pods */,
B0E0937140212D28DA5BB4DC /* Frameworks */,
8E641D2420C8B44B00908555 /* Frameworks */,
781697C27F2F128F70738C30 /* Pods */,
);
sourceTree = "<group>";
};
8EC391821A58B465001C121E /* Products */ = {
isa = PBXGroup;
children = (
8EC391811A58B465001C121E /* SirenExample.app */,
8E3A6C041D07CB6F00A8B7CF /* SirenExampleTests.xctest */,
8EC391811A58B465001C121E /* Example.app */,
8E3A6C041D07CB6F00A8B7CF /* Tests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
8EE6C74A1E6A0AE100DBE454 /* SirenExampleTests */ = {
8EE6C74A1E6A0AE100DBE454 /* Tests */ = {
isa = PBXGroup;
children = (
8EE6C74B1E6A0AE100DBE454 /* Info.plist */,
8EE6C74C1E6A0AE100DBE454 /* SirenTests.swift */,
);
path = SirenExampleTests;
sourceTree = "<group>";
};
9883644C6938DD7B325CF897 /* Pods */ = {
isa = PBXGroup;
children = (
D6F83899DD66820E60E4D8D7 /* Pods-SirenExample.debug.xcconfig */,
A3B7BC14BE83C3ECC35CE7F0 /* Pods-SirenExample.release.xcconfig */,
D38FD6B912E9B6CB22B52416 /* Pods-SirenExample-SirenExampleTests.debug.xcconfig */,
78A551479948AAC7089950DB /* Pods-SirenExample-SirenExampleTests.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
B0E0937140212D28DA5BB4DC /* Frameworks */ = {
isa = PBXGroup;
children = (
BA741D9C16473F5089F50DCE /* Pods_SirenExample.framework */,
D09EBE9EBE5F60D1F8FB92E3 /* Pods_SirenExample_SirenExampleTests.framework */,
);
name = Frameworks;
path = Tests;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8E3A6C031D07CB6F00A8B7CF /* SirenExampleTests */ = {
8E3A6C031D07CB6F00A8B7CF /* Tests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 8E3A6C0D1D07CB6F00A8B7CF /* Build configuration list for PBXNativeTarget "SirenExampleTests" */;
buildConfigurationList = 8E3A6C0D1D07CB6F00A8B7CF /* Build configuration list for PBXNativeTarget "Tests" */;
buildPhases = (
18B2F4C5E6DDDC457FD43E43 /* [CP] Check Pods Manifest.lock */,
F0D788DF78612C5704C442B8 /* [CP] Check Pods Manifest.lock */,
8E3A6C001D07CB6F00A8B7CF /* Sources */,
8E3A6C011D07CB6F00A8B7CF /* Frameworks */,
8E3A6C021D07CB6F00A8B7CF /* Resources */,
3598D77A285D3BE445AC3875 /* [CP] Embed Pods Frameworks */,
0B5B37CD784A3F0BD44B8FBF /* [CP] Copy Pods Resources */,
F4829FA85904971576C7920A /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
8E3A6C0A1D07CB6F00A8B7CF /* PBXTargetDependency */,
);
name = SirenExampleTests;
name = Tests;
productName = SirenTests;
productReference = 8E3A6C041D07CB6F00A8B7CF /* SirenExampleTests.xctest */;
productReference = 8E3A6C041D07CB6F00A8B7CF /* Tests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
8EC391801A58B465001C121E /* SirenExample */ = {
8EC391801A58B465001C121E /* Example */ = {
isa = PBXNativeTarget;
buildConfigurationList = 8EC391A01A58B466001C121E /* Build configuration list for PBXNativeTarget "SirenExample" */;
buildConfigurationList = 8EC391A01A58B466001C121E /* Build configuration list for PBXNativeTarget "Example" */;
buildPhases = (
A6F122F8C1AD8028FA78EAE7 /* [CP] Check Pods Manifest.lock */,
007D5BEF60AE64704A038FBF /* [CP] Check Pods Manifest.lock */,
8EC3917D1A58B465001C121E /* Sources */,
8EC3917E1A58B465001C121E /* Frameworks */,
8EE3A3F81E6A0E470010BDCE /* SwiftLint */,
8EC3917F1A58B465001C121E /* Resources */,
558455D81C6690B4004BE492 /* Embed Frameworks */,
30C2DF2EEFEA7D3101DB372A /* [CP] Embed Pods Frameworks */,
B4236009F7EFD4DE6A509FC8 /* [CP] Copy Pods Resources */,
8EF9F892224EB00200B20545 /* Embed Frameworks */,
E31482FEAF1E4460E554FDD1 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = SirenExample;
name = Example;
productName = Siren;
productReference = 8EC391811A58B465001C121E /* SirenExample.app */;
productReference = 8EC391811A58B465001C121E /* Example.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
@@ -196,25 +205,36 @@
attributes = {
LastSwiftMigration = 0700;
LastSwiftUpdateCheck = 0730;
LastUpgradeCheck = 0820;
LastUpgradeCheck = 1220;
ORGANIZATIONNAME = "Sabintsev iOS Projects";
TargetAttributes = {
8E3A6C031D07CB6F00A8B7CF = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 0800;
LastSwiftMigration = 1020;
TestTargetID = 8EC391801A58B465001C121E;
};
8EC391801A58B465001C121E = {
CreatedOnToolsVersion = 6.1.1;
DevelopmentTeam = HT94948NDD;
DevelopmentTeamName = "Arthur Sabintsev";
LastSwiftMigration = 0800;
LastSwiftMigration = 1020;
SystemCapabilities = {
com.apple.BackgroundModes = {
enabled = 0;
};
com.apple.InAppPurchase = {
enabled = 0;
};
com.apple.Push = {
enabled = 0;
};
};
};
};
};
buildConfigurationList = 8EC3917C1A58B465001C121E /* Build configuration list for PBXProject "SirenExample" */;
buildConfigurationList = 8EC3917C1A58B465001C121E /* Build configuration list for PBXProject "Example" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
@@ -225,8 +245,8 @@
projectDirPath = "";
projectRoot = "";
targets = (
8EC391801A58B465001C121E /* SirenExample */,
8E3A6C031D07CB6F00A8B7CF /* SirenExampleTests */,
8EC391801A58B465001C121E /* Example */,
8E3A6C031D07CB6F00A8B7CF /* Tests */,
);
};
/* End PBXProject section */
@@ -243,73 +263,35 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8EBDF8261E6A0C41006C87B4 /* Main.storyboard in Resources */,
8EBDF8251E6A0C41006C87B4 /* LaunchScreen.xib in Resources */,
8EE6C7481E6A0AB800DBE454 /* Images.xcassets in Resources */,
8EACA9711F380294003134CA /* LaunchScreen.xib in Resources */,
8EACA9721F380294003134CA /* Main.storyboard in Resources */,
8EACA9731F380294003134CA /* Images.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
0B5B37CD784A3F0BD44B8FBF /* [CP] Copy Pods Resources */ = {
007D5BEF60AE64704A038FBF /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SirenExample-SirenExampleTests/Pods-SirenExample-SirenExampleTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
18B2F4C5E6DDDC457FD43E43 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Example-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
30C2DF2EEFEA7D3101DB372A /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SirenExample/Pods-SirenExample-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
3598D77A285D3BE445AC3875 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SirenExample-SirenExampleTests/Pods-SirenExample-SirenExampleTests-frameworks.sh\"\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
8EE3A3F81E6A0E470010BDCE /* SwiftLint */ = {
@@ -326,34 +308,62 @@
shellPath = /bin/sh;
shellScript = "if which swiftlint >/dev/null; then\nswiftlint lint --config ../.swiftlint.yml\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi";
};
A6F122F8C1AD8028FA78EAE7 /* [CP] Check Pods Manifest.lock */ = {
E31482FEAF1E4460E554FDD1 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/Siren/Siren.framework",
);
name = "[CP] Check Pods Manifest.lock";
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Siren.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
B4236009F7EFD4DE6A509FC8 /* [CP] Copy Pods Resources */ = {
F0D788DF78612C5704C442B8 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Example-Tests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
F4829FA85904971576C7920A /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Example-Tests/Pods-Example-Tests-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/Siren/Siren.framework",
);
name = "[CP] Copy Pods Resources";
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Siren.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SirenExample/Pods-SirenExample-resources.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example-Tests/Pods-Example-Tests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
@@ -371,8 +381,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8EE6C7431E6A0AA500DBE454 /* AppDelegate.swift in Sources */,
8EE6C7441E6A0AA500DBE454 /* ViewController.swift in Sources */,
8EACA9741F38029B003134CA /* AppDelegate.swift in Sources */,
8EACA9751F38029B003134CA /* ViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -381,24 +391,24 @@
/* Begin PBXTargetDependency section */
8E3A6C0A1D07CB6F00A8B7CF /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8EC391801A58B465001C121E /* SirenExample */;
target = 8EC391801A58B465001C121E /* Example */;
targetProxy = 8E3A6C091D07CB6F00A8B7CF /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
8EBDF8211E6A0C41006C87B4 /* LaunchScreen.xib */ = {
8EACA9671F37F2D3003134CA /* LaunchScreen.xib */ = {
isa = PBXVariantGroup;
children = (
8EBDF8221E6A0C41006C87B4 /* Base */,
8EACA9681F37F2D3003134CA /* Base */,
);
name = LaunchScreen.xib;
sourceTree = "<group>";
};
8EBDF8231E6A0C41006C87B4 /* Main.storyboard */ = {
8EACA9691F37F2D3003134CA /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
8EBDF8241E6A0C41006C87B4 /* Base */,
8EACA96A1F37F2D3003134CA /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
@@ -408,39 +418,41 @@
/* Begin XCBuildConfiguration section */
8E3A6C0B1D07CB6F00A8B7CF /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = D38FD6B912E9B6CB22B52416 /* Pods-SirenExample-SirenExampleTests.debug.xcconfig */;
baseConfigurationReference = EA761E9782C2024D152342D4 /* Pods-Example-Tests.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ANALYZER_NONNULL = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = SirenExampleTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
INFOPLIST_FILE = Tests/Info.plist;
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)";
SWIFT_VERSION = 3.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SirenExample.app/SirenExample";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example";
};
name = Debug;
};
8E3A6C0C1D07CB6F00A8B7CF /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 78A551479948AAC7089950DB /* Pods-SirenExample-SirenExampleTests.release.xcconfig */;
baseConfigurationReference = 31A1A1D27EA05F1E28033516 /* Pods-Example-Tests.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ANALYZER_NONNULL = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = SirenExampleTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.3;
INFOPLIST_FILE = Tests/Info.plist;
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)";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SirenExample.app/SirenExample";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example";
};
name = Release;
};
@@ -452,14 +464,23 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -482,11 +503,12 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.2;
};
name = Debug;
};
@@ -498,14 +520,23 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -521,48 +552,55 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_VERSION = 4.2;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
8EC391A11A58B466001C121E /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = D6F83899DD66820E60E4D8D7 /* Pods-SirenExample.debug.xcconfig */;
baseConfigurationReference = 740DAA3321466F1ABE6CC37D /* Pods-Example.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = "$(SRCROOT)/SirenExample/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
CODE_SIGN_IDENTITY = "iPhone Developer";
DEVELOPMENT_TEAM = HT94948NDD;
INFOPLIST_FILE = "$(SRCROOT)/Example/Supporting Files/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.apple.itunesconnect.mobile;
PRODUCT_NAME = SirenExample;
SWIFT_VERSION = 3.0;
MARKETING_VERSION = 2.0.2;
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.Facebook;
PRODUCT_NAME = Example;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
8EC391A21A58B466001C121E /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = A3B7BC14BE83C3ECC35CE7F0 /* Pods-SirenExample.release.xcconfig */;
baseConfigurationReference = E83E47CD9052083916E39F84 /* Pods-Example.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = "$(SRCROOT)/SirenExample/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
CODE_SIGN_IDENTITY = "iPhone Developer";
DEVELOPMENT_TEAM = HT94948NDD;
INFOPLIST_FILE = "$(SRCROOT)/Example/Supporting Files/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.apple.itunesconnect.mobile;
PRODUCT_NAME = SirenExample;
MARKETING_VERSION = 2.0.2;
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.Facebook;
PRODUCT_NAME = Example;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
8E3A6C0D1D07CB6F00A8B7CF /* Build configuration list for PBXNativeTarget "SirenExampleTests" */ = {
8E3A6C0D1D07CB6F00A8B7CF /* Build configuration list for PBXNativeTarget "Tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
8E3A6C0B1D07CB6F00A8B7CF /* Debug */,
@@ -571,7 +609,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
8EC3917C1A58B465001C121E /* Build configuration list for PBXProject "SirenExample" */ = {
8EC3917C1A58B465001C121E /* Build configuration list for PBXProject "Example" */ = {
isa = XCConfigurationList;
buildConfigurations = (
8EC3919E1A58B466001C121E /* Debug */,
@@ -580,7 +618,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
8EC391A01A58B466001C121E /* Build configuration list for PBXNativeTarget "SirenExample" */ = {
8EC391A01A58B466001C121E /* Build configuration list for PBXNativeTarget "Example" */ = {
isa = XCConfigurationList;
buildConfigurations = (
8EC391A11A58B466001C121E /* Debug */,
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:/Users/Arthur/Documents/oss/siren/SirenExample/Example.xcodeproj">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?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>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -2,7 +2,7 @@
<Workspace
version = "1.0">
<FileRef
location = "group:SirenExample.xcodeproj">
location = "group:Example.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
@@ -0,0 +1,8 @@
<?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>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
+269
View File
@@ -0,0 +1,269 @@
//
// AppDelegate.swift
// Siren
//
// Created by Arthur Sabintsev on 1/3/15.
// Copyright (c) 2015 Sabintsev iOS Projects. All rights reserved.
//
import Siren
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
window?.makeKeyAndVisible()
/// - Warning:
/// Siren should ONLY be placed in UIApplication.didFinishLaunchingWithOptions and only after the `window?.makeKeyAndVisible()` call.
/// Siren initializes a listener on `didBecomeActiveNotification` to perform version checks.
// defaultExample()
// defaultExampleUsingCompletionHandler()
// manualExampleWithCompletionHandler()
// minimalCustomizationPresentationExample()
// forceLocalizationCustomizationPresentationExample()
// customMessagingPresentationExample()
// annoyingRuleExample()
hyperCriticalRulesExample()
// updateSpecificRulesExample()
// customAlertRulesExample()
// appStoreCountryChangeExample()
// complexExample()
return true
}
}
// Examples on how to use Siren
private extension AppDelegate {
/// The simplest implementation of Siren.
/// All default rules are implemented and the
/// results of the completion handler are ignored.
func defaultExample() {
Siren.shared.wail()
}
/// The simplest implementation of Siren.
/// All default rules are implemented and the
/// results of the completion handler are returned or an error is returned.
func defaultExampleUsingCompletionHandler() {
Siren.shared.wail { results in
switch results {
case .success(let updateResults):
print("AlertAction ", updateResults.alertAction)
print("Localization ", updateResults.localization)
print("Model ", updateResults.model)
print("UpdateType ", updateResults.updateType)
case .failure(let error):
print(error.localizedDescription)
}
}
}
/// Rather than waiting for `didBecomeActive` state changes (e.g., app launching/relaunching),
/// Siren's version checking and alert presentation methods will be triggered each time this method is called.
func manualExampleWithCompletionHandler() {
Siren.shared.wail(performCheck: .onDemand) { results in
switch results {
case .success(let updateResults):
print("AlertAction ", updateResults.alertAction)
print("Localization ", updateResults.localization)
print("Model ", updateResults.model)
print("UpdateType ", updateResults.updateType)
case .failure(let error):
print(error.localizedDescription)
}
}
}
/// Minor customization to Siren's update alert presentation.
func minimalCustomizationPresentationExample() {
let siren = Siren.shared
siren.rulesManager = RulesManager(globalRules: .annoying)
siren.presentationManager = PresentationManager(alertTintColor: .purple,
appName: "Siren Example App Override!")
siren.wail { results in
switch results {
case .success(let updateResults):
print("AlertAction ", updateResults.alertAction)
print("Localization ", updateResults.localization)
print("Model ", updateResults.model)
print("UpdateType ", updateResults.updateType)
case .failure(let error):
print(error.localizedDescription)
}
}
}
/// Forcing the language of the update alert to a specific localization (e.g., Russian is forced in this function)
func forceLocalizationCustomizationPresentationExample() {
let siren = Siren.shared
siren.presentationManager = PresentationManager(forceLanguageLocalization: .russian)
siren.wail { results in
switch results {
case .success(let updateResults):
print("AlertAction ", updateResults.alertAction)
print("Localization ", updateResults.localization)
print("Model ", updateResults.model)
print("UpdateType ", updateResults.updateType)
case .failure(let error):
print(error.localizedDescription)
}
}
}
/// Example on how to change specific strings in the update alert.
func customMessagingPresentationExample() {
let siren = Siren.shared
siren.presentationManager = PresentationManager(alertTitle: "Update Now, OK?",
nextTimeButtonTitle: "Next time, please!?")
siren.wail { results in
switch results {
case .success(let updateResults):
print("AlertAction ", updateResults.alertAction)
print("Localization ", updateResults.localization)
print("Model ", updateResults.model)
print("UpdateType ", updateResults.updateType)
case .failure(let error):
print(error.localizedDescription)
}
}
}
/// How to present an alert every time the app is foregrounded.
func annoyingRuleExample() {
let siren = Siren.shared
siren.rulesManager = RulesManager(globalRules: .annoying)
siren.wail { results in
switch results {
case .success(let updateResults):
print("AlertAction ", updateResults.alertAction)
print("Localization ", updateResults.localization)
print("Model ", updateResults.model)
print("UpdateType ", updateResults.updateType)
case .failure(let error):
print(error.localizedDescription)
}
}
}
/// How to present an alert every time the app is foregrounded.
/// This will block the user from using the app until they update the app.
/// Setting `showAlertAfterCurrentVersionHasBeenReleasedForDays` to `0` IS NOT RECOMMENDED
/// as it will cause the user to go into an endless loop to the App Store if the JSON results
/// update faster than the App Store CDN.
///
/// The `0` value is illustrated in this app as an example on how to change how quickly an alert is presented.
func hyperCriticalRulesExample() {
let siren = Siren.shared
siren.rulesManager = RulesManager(globalRules: .critical,
showAlertAfterCurrentVersionHasBeenReleasedForDays: 0)
siren.wail { results in
switch results {
case .success(let updateResults):
print("AlertAction ", updateResults.alertAction)
print("Localization ", updateResults.localization)
print("Model ", updateResults.model)
print("UpdateType ", updateResults.updateType)
case .failure(let error):
print(error.localizedDescription)
}
}
}
/// Major, Minor, Patch, and Revision specific rules implementations.
func updateSpecificRulesExample() {
let siren = Siren.shared
siren.rulesManager = RulesManager(majorUpdateRules: .critical,
minorUpdateRules: .annoying,
patchUpdateRules: .default,
revisionUpdateRules: Rules(promptFrequency: .weekly, forAlertType: .option))
siren.wail { results in
switch results {
case .success(let updateResults):
print("AlertAction ", updateResults.alertAction)
print("Localization ", updateResults.localization)
print("Model ", updateResults.model)
print("UpdateType ", updateResults.updateType)
case .failure(let error):
print(error.localizedDescription)
}
}
}
/// An example on how to present your own custom alert using Siren's localized Strings and version checking cadence.
func customAlertRulesExample() {
let siren = Siren.shared
// The key for using custom alerts is to set the `alertType` to `.none`.
// The `Results` type will return localized strings for your app's custom modal presentation.
// The `promptFrequency` allows you to customize how often Siren performs the version check before returning a non-error result back into your app, prompting your custom alert functionality.
let rules = Rules(promptFrequency: .immediately, forAlertType: .none)
siren.rulesManager = RulesManager(globalRules: rules)
siren.wail { results in
switch results {
case .success(let updateResults):
print("AlertAction ", updateResults.alertAction)
print("Localization ", updateResults.localization)
print("Model ", updateResults.model)
print("UpdateType ", updateResults.updateType)
case .failure(let error):
print(error.localizedDescription)
}
}
}
/// An example on how to change the App Store region that your app in which your app is available.
/// This should only be used if your app is not available in the US App Store.
/// This example function illustrates how this can be done by checking against the Russian App Store.
func appStoreCountryChangeExample() {
let siren = Siren.shared
siren.apiManager = APIManager(country: .russia)
siren.wail { results in
switch results {
case .success(let updateResults):
print("AlertAction ", updateResults.alertAction)
print("Localization ", updateResults.localization)
print("Model ", updateResults.model)
print("UpdateType ", updateResults.updateType)
case .failure(let error):
print(error.localizedDescription)
}
}
}
/// An example on how to customize multiple managers at once.
func complexExample() {
let siren = Siren.shared
siren.presentationManager = PresentationManager(alertTintColor: .brown,
appName: "Siren's Complex Rule Example App",
alertTitle: "Please, Update Now!",
skipButtonTitle: "Click here to skip!",
forceLanguageLocalization: .spanish)
siren.rulesManager = RulesManager(majorUpdateRules: .critical,
minorUpdateRules: .annoying,
patchUpdateRules: .default,
revisionUpdateRules: .relaxed)
siren.wail { results in
switch results {
case .success(let updateResults):
print("AlertAction ", updateResults.alertAction)
print("Localization ", updateResults.localization)
print("Model ", updateResults.model)
print("UpdateType ", updateResults.updateType)
case .failure(let error):
print(error.localizedDescription)
}
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

@@ -1,21 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10116" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="vXZ-lx-hvc">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="vXZ-lx-hvc">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="ufC-wZ-h7g">
<objects>
<viewController id="vXZ-lx-hvc" customClass="ViewController" customModule="Sample_App" customModuleProvider="target" sceneMemberID="viewController">
<viewController id="vXZ-lx-hvc" customClass="ViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="jyV-Pf-zRb"/>
<viewControllerLayoutGuide type="bottom" id="2fi-mo-0CV"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="kh9-bI-dsS">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="x5A-6p-PRh" sceneMemberID="firstResponder"/>
@@ -1,5 +1,15 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
@@ -29,6 +39,11 @@
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -15,9 +15,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
@@ -21,4 +21,3 @@ class ViewController: UIViewController {
}
}
+10
View File
@@ -0,0 +1,10 @@
platform :ios, '15.0'
inhibit_all_warnings!
use_frameworks!
target 'Example' do
pod 'Siren', :path => '../'
target 'Tests' do
end
end
+16
View File
@@ -0,0 +1,16 @@
PODS:
- Siren (6.0.2)
DEPENDENCIES:
- Siren (from `../`)
EXTERNAL SOURCES:
Siren:
:path: "../"
SPEC CHECKSUMS:
Siren: 1be92ef5775f9b61ebb294c79c59268ab0afcf5d
PODFILE CHECKSUM: 5800641824958ea506d6ae52e89b594fe8270c18
COCOAPODS: 1.11.2
+24
View File
@@ -0,0 +1,24 @@
{
"name": "Siren",
"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",
"authors": {
"Arthur Ariel Sabintsev": "arthur@sabintsev.com"
},
"description": "Notify your users when a new version of your iOS app is available, and prompt them with the App Store link.",
"platforms": {
"ios": "15.0",
"tvos": "15.0"
},
"source": {
"git": "https://github.com/ArtSabintsev/Siren.git",
"tag": "6.0.2"
},
"source_files": "Sources/**/*.swift",
"resources": "Sources/Siren.bundle",
"requires_arc": true,
"swift_version": "5.5"
}
+16
View File
@@ -0,0 +1,16 @@
PODS:
- Siren (6.0.2)
DEPENDENCIES:
- Siren (from `../`)
EXTERNAL SOURCES:
Siren:
:path: "../"
SPEC CHECKSUMS:
Siren: 1be92ef5775f9b61ebb294c79c59268ab0afcf5d
PODFILE CHECKSUM: 5800641824958ea506d6ae52e89b594fe8270c18
COCOAPODS: 1.11.2
+902
View File
@@ -0,0 +1,902 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
151BA7773369BE5FC2A1A56A0ADB1E11 /* PerformCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7637C46E7C27C83B4C31CECE3D6064B4 /* PerformCheck.swift */; };
158B5EA21F24D8A42B2C0DA33D6911D2 /* UIAlertControllerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F20FBAD7ADBFD07AF8183236B4ECE297 /* UIAlertControllerExtension.swift */; };
18AAE788DE1B28510F53F35A0E68214F /* AppStoreCountry.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCAD38316B970AACF9940545155FFAF8 /* AppStoreCountry.swift */; };
1D79DF28DA9C6AA8026CBFF47184B6AF /* AlertConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19D5FEFBCEC302A522182EEE37AD81B3 /* AlertConstants.swift */; };
268E0E6589DE799396C3FBF264AD3996 /* RulesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E841994E6AE2DF727221123E0ED744A /* RulesManager.swift */; };
300E952C78F6EA5BEBF5B5E31F3706E0 /* DateExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9220E906478C87C685A81A5177136643 /* DateExtension.swift */; };
32AEE3D9A55EC66EBCE39C3A38D01126 /* Pods-Example-Tests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 2F92A716E93EDF48D0C9EF3C5062B558 /* Pods-Example-Tests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
425B752B150AAEF5221916E9FC670153 /* KnownError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4681015D4D44EB9A4302B2A179FD809F /* KnownError.swift */; };
428DE866FE6650BC83086E281DAD66F2 /* BundleExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11BFB38B8D147BDF94B9415C0F2DE13A /* BundleExtension.swift */; };
45303C99CEDE9EBA4990949652F4B28D /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62176AC744B2DC815BA7CD121F4EA473 /* Model.swift */; };
487B8148F836C8A64C6ECBBE67126ECA /* Pods-Example-Tests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = AEAE97BBEB3D5E4F45CEC2708FAFB72C /* Pods-Example-Tests-dummy.m */; };
4B4BB6D6D4B49D976A961CEBCA97BC05 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; };
4ECA4FF1C7B4AC6DF846045C5B720A0B /* AlertAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF347B3A55392D1407E1A4ABC8114173 /* AlertAction.swift */; };
56AC6974308EB4B394AAF9B703DC7A47 /* Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB4D2B7323F8C610677B540FEEC7673C /* Localization.swift */; };
5B9E7420A0284E837C04012B528EAE4A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; };
6522773E85791CCB1A7256E5C3201E75 /* Pods-Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 850060B744F1FDFB6ADCAFD76D4D34EB /* Pods-Example-dummy.m */; };
66D1B530F0822D462D840C6E2428F9C0 /* Siren.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7B3EAF82CFAB96C6721BA02F97FC71B /* Siren.swift */; };
9952BF0ED5F6B7F18A07976BDD134D41 /* DataParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97602092A124F5A205482E90225B67EA /* DataParser.swift */; };
A1E89EF77BDD0C8D1EE8AAE743D82ED4 /* Siren-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 94DA749EC12B6582F7B5F8C0E50736F1 /* Siren-dummy.m */; };
A1EA2053268A5D5D9AC11C3D74D5BD4F /* Siren-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 2506E5646D43BCE53FBEE1AB44BF4871 /* Siren-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
A73E39544FF12C5E5E54F07B0A2F7F78 /* PresentationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B26CBDBDDF69163D512AED074B4549D /* PresentationManager.swift */; };
AE1B34BAF1974C7DDAF628092F663F7A /* UpdateResults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 567D8AAC664C44A23EBB5EC6B0AA4049 /* UpdateResults.swift */; };
C21F6BE2015F6B8C8540667C5C4EDCF0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; };
C609EB036330DECF2976CE62912E9745 /* SirenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 786A05732FE78B252DC56C9F78F693C0 /* SirenViewController.swift */; };
C988AA88E47FFA79D317BF4291B2A04D /* UserDefaultsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A8349F11EDA01F629C4C61E99CCFD91 /* UserDefaultsExtension.swift */; };
D95522B7A00F56B9510A8E58BB5AE8ED /* APIManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08A780E0CDE0D69B789468679AB277EA /* APIManager.swift */; };
E5F659EBC88C14C084176F93C9F0156D /* Rules.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1EABF799D1E792CA3E9194926E78605 /* Rules.swift */; };
F235A549B294F2E848529A1A93F852EB /* Pods-Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 90BF25316BE6972758B31C52602CE12C /* Pods-Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
FB731D70855188EDE196CEA745D6940A /* APIModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D06B1A9453346F0CDCD7A4DC41A4F92C /* APIModel.swift */; };
FF40E81B2B174F3584493809B90C6668 /* Siren.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 3CDA2F82B5CE0BD747E1FE8BA63539AD /* Siren.bundle */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
B52DE15DFA6D788DDC41A589FA9AD9E8 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
proxyType = 1;
remoteGlobalIDString = A0E2640B83527AE54205D7FDE9C5D930;
remoteInfo = Siren;
};
BF9CC9039B7878DA61A42FFBD3A22E9F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */;
proxyType = 1;
remoteGlobalIDString = A0E2640B83527AE54205D7FDE9C5D930;
remoteInfo = Siren;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
033A17C59E0896996DE69A71A44F74D3 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
07692E025EFBB5F5C9DD63817289A7F2 /* Pods-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Example.debug.xcconfig"; sourceTree = "<group>"; };
08A780E0CDE0D69B789468679AB277EA /* APIManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = APIManager.swift; sourceTree = "<group>"; };
11BFB38B8D147BDF94B9415C0F2DE13A /* BundleExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = BundleExtension.swift; sourceTree = "<group>"; };
17E70395B3CDD0B7EDA622612E2C3144 /* Siren.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Siren.framework; sourceTree = BUILT_PRODUCTS_DIR; };
19D5FEFBCEC302A522182EEE37AD81B3 /* AlertConstants.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AlertConstants.swift; sourceTree = "<group>"; };
1BA24BC1E607E24F1C9AED046EE27110 /* Pods-Example-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Example-Tests.release.xcconfig"; sourceTree = "<group>"; };
1C22073E7207FFF335D3A9EADE0DA51B /* Siren.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Siren.debug.xcconfig; sourceTree = "<group>"; };
1F667CC0E19EAF34E5A4119E2121F585 /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
2506E5646D43BCE53FBEE1AB44BF4871 /* Siren-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Siren-umbrella.h"; sourceTree = "<group>"; };
27809964D647C11D4B07299C7B264724 /* Pods-Example-Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Example-Tests.debug.xcconfig"; sourceTree = "<group>"; };
2C0257A9A3D8C5B62771A4DDEB17A0ED /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Example.release.xcconfig"; sourceTree = "<group>"; };
2F92A716E93EDF48D0C9EF3C5062B558 /* Pods-Example-Tests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Example-Tests-umbrella.h"; sourceTree = "<group>"; };
3CDA2F82B5CE0BD747E1FE8BA63539AD /* Siren.bundle */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "wrapper.plug-in"; name = Siren.bundle; path = Sources/Siren.bundle; sourceTree = "<group>"; };
3F4E87B2E26A88328CDC6588E37F2AD2 /* Siren-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Siren-prefix.pch"; sourceTree = "<group>"; };
4681015D4D44EB9A4302B2A179FD809F /* KnownError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = KnownError.swift; sourceTree = "<group>"; };
4E841994E6AE2DF727221123E0ED744A /* RulesManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = RulesManager.swift; sourceTree = "<group>"; };
5281882E9C6A7A11616D41DF41B0CC7A /* Pods-Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Example-acknowledgements.plist"; sourceTree = "<group>"; };
567D8AAC664C44A23EBB5EC6B0AA4049 /* UpdateResults.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = UpdateResults.swift; sourceTree = "<group>"; };
62176AC744B2DC815BA7CD121F4EA473 /* Model.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Model.swift; sourceTree = "<group>"; };
688C1754B2F8DFC0710F4772C4A75C32 /* Pods-Example-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Example-Info.plist"; sourceTree = "<group>"; };
6D859521A91F233E653F06300C561D0A /* Pods-Example-Tests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Example-Tests-acknowledgements.markdown"; sourceTree = "<group>"; };
6FE61F66C83C50497BB430E4C3C49CD6 /* Pods-Example-Tests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Example-Tests-Info.plist"; sourceTree = "<group>"; };
70689754D9C1D7660D29312893615F94 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
7637C46E7C27C83B4C31CECE3D6064B4 /* PerformCheck.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PerformCheck.swift; sourceTree = "<group>"; };
786A05732FE78B252DC56C9F78F693C0 /* SirenViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SirenViewController.swift; sourceTree = "<group>"; };
850060B744F1FDFB6ADCAFD76D4D34EB /* Pods-Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Example-dummy.m"; sourceTree = "<group>"; };
89F8A185DF29707E4DC9BB13872AF702 /* Siren.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; path = Siren.podspec; sourceTree = "<group>"; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
8B26CBDBDDF69163D512AED074B4549D /* PresentationManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PresentationManager.swift; sourceTree = "<group>"; };
8B636D1CA58AC29F35305FCC180DDAD8 /* Siren-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Siren-Info.plist"; sourceTree = "<group>"; };
90BF25316BE6972758B31C52602CE12C /* Pods-Example-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Example-umbrella.h"; sourceTree = "<group>"; };
9220E906478C87C685A81A5177136643 /* DateExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DateExtension.swift; sourceTree = "<group>"; };
94DA749EC12B6582F7B5F8C0E50736F1 /* Siren-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Siren-dummy.m"; sourceTree = "<group>"; };
97602092A124F5A205482E90225B67EA /* DataParser.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DataParser.swift; sourceTree = "<group>"; };
9A8349F11EDA01F629C4C61E99CCFD91 /* UserDefaultsExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = UserDefaultsExtension.swift; sourceTree = "<group>"; };
9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
A2D5633C9DFACF001D250AC90A2EAD23 /* Pods_Example_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
AB37C628ACFCAD98A383C821813EFBBF /* Pods-Example-Tests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Example-Tests-frameworks.sh"; sourceTree = "<group>"; };
AB4D2B7323F8C610677B540FEEC7673C /* Localization.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Localization.swift; sourceTree = "<group>"; };
AEAE97BBEB3D5E4F45CEC2708FAFB72C /* Pods-Example-Tests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Example-Tests-dummy.m"; sourceTree = "<group>"; };
AEB39A55C28B48D98B02090079C5C084 /* Pods-Example-Tests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Example-Tests-acknowledgements.plist"; sourceTree = "<group>"; };
B297160149C4B307A3DD5A8DDFC7EEF9 /* Siren.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Siren.modulemap; sourceTree = "<group>"; };
CCAD38316B970AACF9940545155FFAF8 /* AppStoreCountry.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AppStoreCountry.swift; sourceTree = "<group>"; };
D06B1A9453346F0CDCD7A4DC41A4F92C /* APIModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = APIModel.swift; sourceTree = "<group>"; };
D991827462FB11E20C03858A8A0EF766 /* Pods-Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-Example.modulemap"; sourceTree = "<group>"; };
DDB351CF336FC775897FB3DEFC1AECE1 /* Pods-Example-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Example-frameworks.sh"; sourceTree = "<group>"; };
EEF458E38855C5A2A0F70C968763EEAD /* Pods-Example-Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-Example-Tests.modulemap"; sourceTree = "<group>"; };
F1EABF799D1E792CA3E9194926E78605 /* Rules.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Rules.swift; sourceTree = "<group>"; };
F20FBAD7ADBFD07AF8183236B4ECE297 /* UIAlertControllerExtension.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = UIAlertControllerExtension.swift; sourceTree = "<group>"; };
F5743486693D7F303412A3018B0941CF /* Siren.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Siren.release.xcconfig; sourceTree = "<group>"; };
F7B3EAF82CFAB96C6721BA02F97FC71B /* Siren.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Siren.swift; path = Sources/Siren.swift; sourceTree = "<group>"; };
F924C881D2735430B1A17EDFF024E317 /* Pods-Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Example-acknowledgements.markdown"; sourceTree = "<group>"; };
FF347B3A55392D1407E1A4ABC8114173 /* AlertAction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AlertAction.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
19C68C00E0D92CD65F2917255ED5A50B /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4B4BB6D6D4B49D976A961CEBCA97BC05 /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
5E2E02FD05446E0D72F1A5C4F34A57DB /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C21F6BE2015F6B8C8540667C5C4EDCF0 /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D01825EFADF2015C2D6F895EE2B5C81A /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
5B9E7420A0284E837C04012B528EAE4A /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
108F8CE4A8FCBCCB97F2FAD6A5B6D6D2 /* Extensions */ = {
isa = PBXGroup;
children = (
11BFB38B8D147BDF94B9415C0F2DE13A /* BundleExtension.swift */,
9220E906478C87C685A81A5177136643 /* DateExtension.swift */,
F20FBAD7ADBFD07AF8183236B4ECE297 /* UIAlertControllerExtension.swift */,
9A8349F11EDA01F629C4C61E99CCFD91 /* UserDefaultsExtension.swift */,
);
name = Extensions;
path = Sources/Extensions;
sourceTree = "<group>";
};
1CB4D55DAEB98D0046DA84E18479FED9 /* View Controllers */ = {
isa = PBXGroup;
children = (
786A05732FE78B252DC56C9F78F693C0 /* SirenViewController.swift */,
);
name = "View Controllers";
path = "Sources/View Controllers";
sourceTree = "<group>";
};
578452D2E740E91742655AC8F1636D1F /* iOS */ = {
isa = PBXGroup;
children = (
73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */,
);
name = iOS;
sourceTree = "<group>";
};
62A567EC72AC1F16179364897645F180 /* Utilities */ = {
isa = PBXGroup;
children = (
97602092A124F5A205482E90225B67EA /* DataParser.swift */,
4681015D4D44EB9A4302B2A179FD809F /* KnownError.swift */,
);
name = Utilities;
path = Sources/Utilities;
sourceTree = "<group>";
};
79BF3B1D578C929414C256003C35CDDA /* Pods-Example-Tests */ = {
isa = PBXGroup;
children = (
EEF458E38855C5A2A0F70C968763EEAD /* Pods-Example-Tests.modulemap */,
6D859521A91F233E653F06300C561D0A /* Pods-Example-Tests-acknowledgements.markdown */,
AEB39A55C28B48D98B02090079C5C084 /* Pods-Example-Tests-acknowledgements.plist */,
AEAE97BBEB3D5E4F45CEC2708FAFB72C /* Pods-Example-Tests-dummy.m */,
AB37C628ACFCAD98A383C821813EFBBF /* Pods-Example-Tests-frameworks.sh */,
6FE61F66C83C50497BB430E4C3C49CD6 /* Pods-Example-Tests-Info.plist */,
2F92A716E93EDF48D0C9EF3C5062B558 /* Pods-Example-Tests-umbrella.h */,
27809964D647C11D4B07299C7B264724 /* Pods-Example-Tests.debug.xcconfig */,
1BA24BC1E607E24F1C9AED046EE27110 /* Pods-Example-Tests.release.xcconfig */,
);
name = "Pods-Example-Tests";
path = "Target Support Files/Pods-Example-Tests";
sourceTree = "<group>";
};
85FAA2FE23142B2837AABDED1ABBE431 /* Siren */ = {
isa = PBXGroup;
children = (
3CDA2F82B5CE0BD747E1FE8BA63539AD /* Siren.bundle */,
F7B3EAF82CFAB96C6721BA02F97FC71B /* Siren.swift */,
108F8CE4A8FCBCCB97F2FAD6A5B6D6D2 /* Extensions */,
96395B3494838F55CD3B289AE14E3EBC /* Managers */,
A2735ADBD845397D9F481076C17C1760 /* Models */,
DAE3F5037DE241FD14030F7285578362 /* Pod */,
C9A9CB18FAE1BDEE996F72E1BA74240D /* Support Files */,
62A567EC72AC1F16179364897645F180 /* Utilities */,
1CB4D55DAEB98D0046DA84E18479FED9 /* View Controllers */,
);
name = Siren;
path = ../..;
sourceTree = "<group>";
};
96395B3494838F55CD3B289AE14E3EBC /* Managers */ = {
isa = PBXGroup;
children = (
08A780E0CDE0D69B789468679AB277EA /* APIManager.swift */,
8B26CBDBDDF69163D512AED074B4549D /* PresentationManager.swift */,
4E841994E6AE2DF727221123E0ED744A /* RulesManager.swift */,
);
name = Managers;
path = Sources/Managers;
sourceTree = "<group>";
};
A2735ADBD845397D9F481076C17C1760 /* Models */ = {
isa = PBXGroup;
children = (
FF347B3A55392D1407E1A4ABC8114173 /* AlertAction.swift */,
19D5FEFBCEC302A522182EEE37AD81B3 /* AlertConstants.swift */,
D06B1A9453346F0CDCD7A4DC41A4F92C /* APIModel.swift */,
CCAD38316B970AACF9940545155FFAF8 /* AppStoreCountry.swift */,
AB4D2B7323F8C610677B540FEEC7673C /* Localization.swift */,
62176AC744B2DC815BA7CD121F4EA473 /* Model.swift */,
7637C46E7C27C83B4C31CECE3D6064B4 /* PerformCheck.swift */,
F1EABF799D1E792CA3E9194926E78605 /* Rules.swift */,
567D8AAC664C44A23EBB5EC6B0AA4049 /* UpdateResults.swift */,
);
name = Models;
path = Sources/Models;
sourceTree = "<group>";
};
A8A8EA9BC9538376CEF195F2EAAC8200 /* Targets Support Files */ = {
isa = PBXGroup;
children = (
E91BC7AD44E15DE8E857ACB38F588DF3 /* Pods-Example */,
79BF3B1D578C929414C256003C35CDDA /* Pods-Example-Tests */,
);
name = "Targets Support Files";
sourceTree = "<group>";
};
B9E413F3FEAF521324127A009A6039BA /* Products */ = {
isa = PBXGroup;
children = (
1F667CC0E19EAF34E5A4119E2121F585 /* Pods_Example.framework */,
A2D5633C9DFACF001D250AC90A2EAD23 /* Pods_Example_Tests.framework */,
17E70395B3CDD0B7EDA622612E2C3144 /* Siren.framework */,
);
name = Products;
sourceTree = "<group>";
};
C9A9CB18FAE1BDEE996F72E1BA74240D /* Support Files */ = {
isa = PBXGroup;
children = (
B297160149C4B307A3DD5A8DDFC7EEF9 /* Siren.modulemap */,
94DA749EC12B6582F7B5F8C0E50736F1 /* Siren-dummy.m */,
8B636D1CA58AC29F35305FCC180DDAD8 /* Siren-Info.plist */,
3F4E87B2E26A88328CDC6588E37F2AD2 /* Siren-prefix.pch */,
2506E5646D43BCE53FBEE1AB44BF4871 /* Siren-umbrella.h */,
1C22073E7207FFF335D3A9EADE0DA51B /* Siren.debug.xcconfig */,
F5743486693D7F303412A3018B0941CF /* Siren.release.xcconfig */,
);
name = "Support Files";
path = "Example/Pods/Target Support Files/Siren";
sourceTree = "<group>";
};
CA5CC6205CFA8B5868F65C2CE32900E5 /* Development Pods */ = {
isa = PBXGroup;
children = (
85FAA2FE23142B2837AABDED1ABBE431 /* Siren */,
);
name = "Development Pods";
sourceTree = "<group>";
};
CF1408CF629C7361332E53B88F7BD30C = {
isa = PBXGroup;
children = (
9D940727FF8FB9C785EB98E56350EF41 /* Podfile */,
CA5CC6205CFA8B5868F65C2CE32900E5 /* Development Pods */,
D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */,
B9E413F3FEAF521324127A009A6039BA /* Products */,
A8A8EA9BC9538376CEF195F2EAAC8200 /* Targets Support Files */,
);
sourceTree = "<group>";
};
D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */ = {
isa = PBXGroup;
children = (
578452D2E740E91742655AC8F1636D1F /* iOS */,
);
name = Frameworks;
sourceTree = "<group>";
};
DAE3F5037DE241FD14030F7285578362 /* Pod */ = {
isa = PBXGroup;
children = (
70689754D9C1D7660D29312893615F94 /* LICENSE */,
033A17C59E0896996DE69A71A44F74D3 /* README.md */,
89F8A185DF29707E4DC9BB13872AF702 /* Siren.podspec */,
);
name = Pod;
sourceTree = "<group>";
};
E91BC7AD44E15DE8E857ACB38F588DF3 /* Pods-Example */ = {
isa = PBXGroup;
children = (
D991827462FB11E20C03858A8A0EF766 /* Pods-Example.modulemap */,
F924C881D2735430B1A17EDFF024E317 /* Pods-Example-acknowledgements.markdown */,
5281882E9C6A7A11616D41DF41B0CC7A /* Pods-Example-acknowledgements.plist */,
850060B744F1FDFB6ADCAFD76D4D34EB /* Pods-Example-dummy.m */,
DDB351CF336FC775897FB3DEFC1AECE1 /* Pods-Example-frameworks.sh */,
688C1754B2F8DFC0710F4772C4A75C32 /* Pods-Example-Info.plist */,
90BF25316BE6972758B31C52602CE12C /* Pods-Example-umbrella.h */,
07692E025EFBB5F5C9DD63817289A7F2 /* Pods-Example.debug.xcconfig */,
2C0257A9A3D8C5B62771A4DDEB17A0ED /* Pods-Example.release.xcconfig */,
);
name = "Pods-Example";
path = "Target Support Files/Pods-Example";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
57B0EAD2BF26101AE4951B7571E127AC /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
F235A549B294F2E848529A1A93F852EB /* Pods-Example-umbrella.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
810C4E5C60D9DE47607703BE3EF5C570 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
32AEE3D9A55EC66EBCE39C3A38D01126 /* Pods-Example-Tests-umbrella.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
C1B2B775EC37DA6784A580EC336EB857 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
A1EA2053268A5D5D9AC11C3D74D5BD4F /* Siren-umbrella.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
0AEE99A309977BD12A049FF48AF9BA4B /* Pods-Example */ = {
isa = PBXNativeTarget;
buildConfigurationList = D3B82CA51562CEF224C9A4BB49C4984C /* Build configuration list for PBXNativeTarget "Pods-Example" */;
buildPhases = (
57B0EAD2BF26101AE4951B7571E127AC /* Headers */,
4FFB70C136C9E782741B288D15B85315 /* Sources */,
5E2E02FD05446E0D72F1A5C4F34A57DB /* Frameworks */,
1D93CD182681FF85B9578413C8D20386 /* Resources */,
);
buildRules = (
);
dependencies = (
5325AFA39850B8A702C4FAF857E8B547 /* PBXTargetDependency */,
);
name = "Pods-Example";
productName = Pods_Example;
productReference = 1F667CC0E19EAF34E5A4119E2121F585 /* Pods_Example.framework */;
productType = "com.apple.product-type.framework";
};
258F10561A9DF823C49949D6176054DD /* Pods-Example-Tests */ = {
isa = PBXNativeTarget;
buildConfigurationList = FF4C27B32F8578162520923AA315DD80 /* Build configuration list for PBXNativeTarget "Pods-Example-Tests" */;
buildPhases = (
810C4E5C60D9DE47607703BE3EF5C570 /* Headers */,
222B8840F0BDB57E0AAD162A4612C884 /* Sources */,
19C68C00E0D92CD65F2917255ED5A50B /* Frameworks */,
26CAC077D527B3E5B13B86D2CA4BFF44 /* Resources */,
);
buildRules = (
);
dependencies = (
8292FC67D3422DFD54E714A9A8FF469E /* PBXTargetDependency */,
);
name = "Pods-Example-Tests";
productName = Pods_Example_Tests;
productReference = A2D5633C9DFACF001D250AC90A2EAD23 /* Pods_Example_Tests.framework */;
productType = "com.apple.product-type.framework";
};
A0E2640B83527AE54205D7FDE9C5D930 /* Siren */ = {
isa = PBXNativeTarget;
buildConfigurationList = D32ED6FCE8895E74A4FB89FACB79DC86 /* Build configuration list for PBXNativeTarget "Siren" */;
buildPhases = (
C1B2B775EC37DA6784A580EC336EB857 /* Headers */,
D808E7A6F5C7F3EB841EB711DC313822 /* Sources */,
D01825EFADF2015C2D6F895EE2B5C81A /* Frameworks */,
15A1BDD07A3C42FFD26CA6341DED32EC /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = Siren;
productName = Siren;
productReference = 17E70395B3CDD0B7EDA622612E2C3144 /* Siren.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
BFDFE7DC352907FC980B868725387E98 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1240;
LastUpgradeCheck = 1340;
};
buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
Base,
en,
);
mainGroup = CF1408CF629C7361332E53B88F7BD30C;
productRefGroup = B9E413F3FEAF521324127A009A6039BA /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
0AEE99A309977BD12A049FF48AF9BA4B /* Pods-Example */,
258F10561A9DF823C49949D6176054DD /* Pods-Example-Tests */,
A0E2640B83527AE54205D7FDE9C5D930 /* Siren */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
15A1BDD07A3C42FFD26CA6341DED32EC /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
FF40E81B2B174F3584493809B90C6668 /* Siren.bundle in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
1D93CD182681FF85B9578413C8D20386 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
26CAC077D527B3E5B13B86D2CA4BFF44 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
222B8840F0BDB57E0AAD162A4612C884 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
487B8148F836C8A64C6ECBBE67126ECA /* Pods-Example-Tests-dummy.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
4FFB70C136C9E782741B288D15B85315 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6522773E85791CCB1A7256E5C3201E75 /* Pods-Example-dummy.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D808E7A6F5C7F3EB841EB711DC313822 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4ECA4FF1C7B4AC6DF846045C5B720A0B /* AlertAction.swift in Sources */,
1D79DF28DA9C6AA8026CBFF47184B6AF /* AlertConstants.swift in Sources */,
D95522B7A00F56B9510A8E58BB5AE8ED /* APIManager.swift in Sources */,
FB731D70855188EDE196CEA745D6940A /* APIModel.swift in Sources */,
18AAE788DE1B28510F53F35A0E68214F /* AppStoreCountry.swift in Sources */,
428DE866FE6650BC83086E281DAD66F2 /* BundleExtension.swift in Sources */,
9952BF0ED5F6B7F18A07976BDD134D41 /* DataParser.swift in Sources */,
300E952C78F6EA5BEBF5B5E31F3706E0 /* DateExtension.swift in Sources */,
425B752B150AAEF5221916E9FC670153 /* KnownError.swift in Sources */,
56AC6974308EB4B394AAF9B703DC7A47 /* Localization.swift in Sources */,
45303C99CEDE9EBA4990949652F4B28D /* Model.swift in Sources */,
151BA7773369BE5FC2A1A56A0ADB1E11 /* PerformCheck.swift in Sources */,
A73E39544FF12C5E5E54F07B0A2F7F78 /* PresentationManager.swift in Sources */,
E5F659EBC88C14C084176F93C9F0156D /* Rules.swift in Sources */,
268E0E6589DE799396C3FBF264AD3996 /* RulesManager.swift in Sources */,
66D1B530F0822D462D840C6E2428F9C0 /* Siren.swift in Sources */,
A1E89EF77BDD0C8D1EE8AAE743D82ED4 /* Siren-dummy.m in Sources */,
C609EB036330DECF2976CE62912E9745 /* SirenViewController.swift in Sources */,
158B5EA21F24D8A42B2C0DA33D6911D2 /* UIAlertControllerExtension.swift in Sources */,
AE1B34BAF1974C7DDAF628092F663F7A /* UpdateResults.swift in Sources */,
C988AA88E47FFA79D317BF4291B2A04D /* UserDefaultsExtension.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
5325AFA39850B8A702C4FAF857E8B547 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = Siren;
target = A0E2640B83527AE54205D7FDE9C5D930 /* Siren */;
targetProxy = B52DE15DFA6D788DDC41A589FA9AD9E8 /* PBXContainerItemProxy */;
};
8292FC67D3422DFD54E714A9A8FF469E /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = Siren;
target = A0E2640B83527AE54205D7FDE9C5D930 /* Siren */;
targetProxy = BF9CC9039B7878DA61A42FFBD3A22E9F /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
33693A1CC9F4648B54726664AFDE566F /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = F5743486693D7F303412A3018B0941CF /* Siren.release.xcconfig */;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = NO;
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_PREFIX_HEADER = "Target Support Files/Siren/Siren-prefix.pch";
INFOPLIST_FILE = "Target Support Files/Siren/Siren-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MODULEMAP_FILE = "Target Support Files/Siren/Siren.modulemap";
PRODUCT_MODULE_NAME = Siren;
PRODUCT_NAME = Siren;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
SWIFT_VERSION = 5.5;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
7AE7988F711FD5F0C3BBD5F5321193F9 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 1C22073E7207FFF335D3A9EADE0DA51B /* Siren.debug.xcconfig */;
buildSettings = {
CLANG_ENABLE_OBJC_WEAK = NO;
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_PREFIX_HEADER = "Target Support Files/Siren/Siren-prefix.pch";
INFOPLIST_FILE = "Target Support Files/Siren/Siren-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MODULEMAP_FILE = "Target Support Files/Siren/Siren.modulemap";
PRODUCT_MODULE_NAME = Siren;
PRODUCT_NAME = Siren;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
SWIFT_VERSION = 5.5;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
893704CF3A7D64225E29C0FC0B12E037 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 27809964D647C11D4B07299C7B264724 /* Pods-Example-Tests.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
CLANG_ENABLE_OBJC_WEAK = NO;
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = "Target Support Files/Pods-Example-Tests/Pods-Example-Tests-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
MODULEMAP_FILE = "Target Support Files/Pods-Example-Tests/Pods-Example-Tests.modulemap";
OTHER_LDFLAGS = "";
OTHER_LIBTOOLFLAGS = "";
PODS_ROOT = "$(SRCROOT)";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
90D4D09BCB6A4660E43ACBE9ECB6FE9A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"POD_CONFIGURATION_DEBUG=1",
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
STRIP_INSTALLED_PRODUCT = NO;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
SYMROOT = "${SRCROOT}/../build";
};
name = Debug;
};
9553C89E183877A5CB2F3C6801BEC129 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"POD_CONFIGURATION_RELEASE=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
STRIP_INSTALLED_PRODUCT = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 5.0;
SYMROOT = "${SRCROOT}/../build";
};
name = Release;
};
A3E9B9058E9A918CE0B415D30ED0A72D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 07692E025EFBB5F5C9DD63817289A7F2 /* Pods-Example.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
CLANG_ENABLE_OBJC_WEAK = NO;
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = "Target Support Files/Pods-Example/Pods-Example-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
MODULEMAP_FILE = "Target Support Files/Pods-Example/Pods-Example.modulemap";
OTHER_LDFLAGS = "";
OTHER_LIBTOOLFLAGS = "";
PODS_ROOT = "$(SRCROOT)";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
B0425CD0BFC3B46122E8E1CC4DB5B5B8 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 2C0257A9A3D8C5B62771A4DDEB17A0ED /* Pods-Example.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
CLANG_ENABLE_OBJC_WEAK = NO;
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = "Target Support Files/Pods-Example/Pods-Example-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
MODULEMAP_FILE = "Target Support Files/Pods-Example/Pods-Example.modulemap";
OTHER_LDFLAGS = "";
OTHER_LIBTOOLFLAGS = "";
PODS_ROOT = "$(SRCROOT)";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
B3B633944F03CF5ACE6C6619C915EC03 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 1BA24BC1E607E24F1C9AED046EE27110 /* Pods-Example-Tests.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
CLANG_ENABLE_OBJC_WEAK = NO;
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = "Target Support Files/Pods-Example-Tests/Pods-Example-Tests-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
MODULEMAP_FILE = "Target Support Files/Pods-Example-Tests/Pods-Example-Tests.modulemap";
OTHER_LDFLAGS = "";
OTHER_LIBTOOLFLAGS = "";
PODS_ROOT = "$(SRCROOT)";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = {
isa = XCConfigurationList;
buildConfigurations = (
90D4D09BCB6A4660E43ACBE9ECB6FE9A /* Debug */,
9553C89E183877A5CB2F3C6801BEC129 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
D32ED6FCE8895E74A4FB89FACB79DC86 /* Build configuration list for PBXNativeTarget "Siren" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7AE7988F711FD5F0C3BBD5F5321193F9 /* Debug */,
33693A1CC9F4648B54726664AFDE566F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
D3B82CA51562CEF224C9A4BB49C4984C /* Build configuration list for PBXNativeTarget "Pods-Example" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A3E9B9058E9A918CE0B415D30ED0A72D /* Debug */,
B0425CD0BFC3B46122E8E1CC4DB5B5B8 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
FF4C27B32F8578162520923AA315DD80 /* Build configuration list for PBXNativeTarget "Pods-Example-Tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
893704CF3A7D64225E29C0FC0B12E037 /* Debug */,
B3B633944F03CF5ACE6C6619C915EC03 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */;
}
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0820"
LastUpgradeVersion = "1340"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -14,10 +14,10 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8EC391801A58B465001C121E"
BuildableName = "SirenExample.app"
BlueprintName = "SirenExample"
ReferencedContainer = "container:SirenExample.xcodeproj">
BlueprintIdentifier = "258F10561A9DF823C49949D6176054DD"
BuildableName = "Pods_Example_Tests.framework"
BlueprintName = "Pods-Example-Tests"
ReferencedContainer = "container:Pods.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
@@ -28,28 +28,7 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8E3A6C031D07CB6F00A8B7CF"
BuildableName = "SirenExampleTests.xctest"
BlueprintName = "SirenExampleTests"
ReferencedContainer = "container:SirenExample.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8EC391801A58B465001C121E"
BuildableName = "SirenExample.app"
BlueprintName = "SirenExample"
ReferencedContainer = "container:SirenExample.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@@ -61,18 +40,6 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8EC391801A58B465001C121E"
BuildableName = "SirenExample.app"
BlueprintName = "SirenExample"
ReferencedContainer = "container:SirenExample.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
@@ -80,16 +47,15 @@
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8EC391801A58B465001C121E"
BuildableName = "SirenExample.app"
BlueprintName = "SirenExample"
ReferencedContainer = "container:SirenExample.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>
@@ -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 = "A0E2640B83527AE54205D7FDE9C5D930"
BuildableName = "Siren.framework"
BlueprintName = "Siren"
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 = "A0E2640B83527AE54205D7FDE9C5D930"
BuildableName = "Siren.framework"
BlueprintName = "Siren"
ReferencedContainer = "container:Pods.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,5 @@
#import <Foundation/Foundation.h>
@interface PodsDummy_Pods_Example_Tests : NSObject
@end
@implementation PodsDummy_Pods_Example_Tests
@end
@@ -0,0 +1,186 @@
#!/bin/sh
set -e
set -u
set -o pipefail
function on_error {
echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
}
trap 'on_error $LINENO' ERR
if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
# If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
# frameworks to, so exit 0 (signalling the script phase was successful).
exit 0
fi
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
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"
# 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
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
# Copies and strips a vendored framework
install_framework()
{
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
local source="${BUILT_PRODUCTS_DIR}/$1"
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
elif [ -r "$1" ]; then
local source="$1"
fi
local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [ -L "${source}" ]; then
echo "Symlinked..."
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[@]}" --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")"
binary="${destination}/${basename}.framework/${basename}"
if ! [ -r "$binary" ]; then
binary="${destination}/${basename}"
elif [ -L "${binary}" ]; then
echo "Destination binary is symlinked..."
dirname="$(dirname "${binary}")"
binary="${dirname}/$(readlink "${binary}")"
fi
# Strip invalid architectures so "fat" simulator / device frameworks work on device
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
strip_invalid_archs "$binary"
fi
# Resign the code if required by the build settings to avoid unstable apps
code_sign_if_enabled "${destination}/$(basename "$1")"
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
local swift_runtime_libs
swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u)
for lib in $swift_runtime_libs; do
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
code_sign_if_enabled "${destination}/${lib}"
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 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 .dSYM "$source")"
binary_name="$(ls "$source/Contents/Resources/DWARF")"
binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}"
# Strip invalid architectures from the dSYM.
if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
strip_invalid_archs "$binary" "$warn_missing_arch"
fi
if [[ $STRIP_BINARY_RETVAL == 0 ]]; then
# Move the stripped file into its final destination.
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.
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"
local destination="${BUILT_PRODUCTS_DIR}"
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"
}
# Signs a framework with the provided identity
code_sign_if_enabled() {
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
# Use the current code_sign_identity
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
code_sign_cmd="$code_sign_cmd &"
fi
echo "$code_sign_cmd"
eval "$code_sign_cmd"
fi
}
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/Siren/Siren.framework"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/Siren/Siren.framework"
fi
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
wait
fi
@@ -11,6 +11,6 @@
#endif
FOUNDATION_EXPORT double Pods_SirenExample_SirenExampleTestsVersionNumber;
FOUNDATION_EXPORT const unsigned char Pods_SirenExample_SirenExampleTestsVersionString[];
FOUNDATION_EXPORT double Pods_Example_TestsVersionNumber;
FOUNDATION_EXPORT const unsigned char Pods_Example_TestsVersionString[];
@@ -0,0 +1,16 @@
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) /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
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
@@ -0,0 +1,6 @@
framework module Pods_Example_Tests {
umbrella header "Pods-Example-Tests-umbrella.h"
export *
module * { export * }
}
@@ -0,0 +1,16 @@
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) /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
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
@@ -0,0 +1,5 @@
#import <Foundation/Foundation.h>
@interface PodsDummy_Pods_Example : NSObject
@end
@implementation PodsDummy_Pods_Example
@end
+186
View File
@@ -0,0 +1,186 @@
#!/bin/sh
set -e
set -u
set -o pipefail
function on_error {
echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
}
trap 'on_error $LINENO' ERR
if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
# If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
# frameworks to, so exit 0 (signalling the script phase was successful).
exit 0
fi
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
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"
# 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
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
# Copies and strips a vendored framework
install_framework()
{
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
local source="${BUILT_PRODUCTS_DIR}/$1"
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
elif [ -r "$1" ]; then
local source="$1"
fi
local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [ -L "${source}" ]; then
echo "Symlinked..."
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[@]}" --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")"
binary="${destination}/${basename}.framework/${basename}"
if ! [ -r "$binary" ]; then
binary="${destination}/${basename}"
elif [ -L "${binary}" ]; then
echo "Destination binary is symlinked..."
dirname="$(dirname "${binary}")"
binary="${dirname}/$(readlink "${binary}")"
fi
# Strip invalid architectures so "fat" simulator / device frameworks work on device
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
strip_invalid_archs "$binary"
fi
# Resign the code if required by the build settings to avoid unstable apps
code_sign_if_enabled "${destination}/$(basename "$1")"
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
local swift_runtime_libs
swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u)
for lib in $swift_runtime_libs; do
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
code_sign_if_enabled "${destination}/${lib}"
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 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 .dSYM "$source")"
binary_name="$(ls "$source/Contents/Resources/DWARF")"
binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}"
# Strip invalid architectures from the dSYM.
if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
strip_invalid_archs "$binary" "$warn_missing_arch"
fi
if [[ $STRIP_BINARY_RETVAL == 0 ]]; then
# Move the stripped file into its final destination.
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.
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"
local destination="${BUILT_PRODUCTS_DIR}"
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"
}
# Signs a framework with the provided identity
code_sign_if_enabled() {
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
# Use the current code_sign_identity
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
code_sign_cmd="$code_sign_cmd &"
fi
echo "$code_sign_cmd"
eval "$code_sign_cmd"
fi
}
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/Siren/Siren.framework"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/Siren/Siren.framework"
fi
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
wait
fi
@@ -1,5 +1,18 @@
#!/bin/sh
set -e
set -u
set -o pipefail
function on_error {
echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
}
trap 'on_error $LINENO' ERR
if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then
# If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy
# resources to, so exit 0 (signalling the script phase was successful).
exit 0
fi
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
@@ -8,7 +21,11 @@ RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
XCASSET_FILES=()
case "${TARGETED_DEVICE_FAMILY}" in
# 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
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
case "${TARGETED_DEVICE_FAMILY:-}" in
1,2)
TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
;;
@@ -21,6 +38,9 @@ case "${TARGETED_DEVICE_FAMILY}" in
3)
TARGET_DEVICE_ARGS="--target-device tv"
;;
4)
TARGET_DEVICE_ARGS="--target-device watch"
;;
*)
TARGET_DEVICE_ARGS="--target-device mac"
;;
@@ -41,29 +61,29 @@ EOM
fi
case $RESOURCE_PATH in
*.storyboard)
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.xib)
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.framework)
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
;;
*.xcdatamodel)
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\""
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
;;
*.xcdatamodeld)
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\""
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
;;
*.xcmappingmodel)
echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\""
echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
;;
*.xcassets)
@@ -71,11 +91,17 @@ EOM
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
;;
*)
echo "$RESOURCE_PATH"
echo "$RESOURCE_PATH" || true
echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
;;
esac
}
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_resource "${PODS_ROOT}/../../Sources/Siren.bundle"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
install_resource "${PODS_ROOT}/../../Sources/Siren.bundle"
fi
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
@@ -85,7 +111,7 @@ if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then
fi
rm -f "$RESOURCES_TO_COPY"
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ]
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ]
then
# Find all other xcassets (this unfortunately includes those of path pods and other targets).
OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
@@ -95,5 +121,9 @@ then
fi
done <<<"$OTHER_XCASSETS"
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
else
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist"
fi
fi
@@ -11,6 +11,6 @@
#endif
FOUNDATION_EXPORT double Pods_SirenExampleVersionNumber;
FOUNDATION_EXPORT const unsigned char Pods_SirenExampleVersionString[];
FOUNDATION_EXPORT double Pods_ExampleVersionNumber;
FOUNDATION_EXPORT const unsigned char Pods_ExampleVersionString[];
@@ -0,0 +1,16 @@
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) /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
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
@@ -0,0 +1,6 @@
framework module Pods_Example {
umbrella header "Pods-Example-umbrella.h"
export *
module * { export * }
}
@@ -0,0 +1,16 @@
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) /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
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
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.1.3</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
+9
View File
@@ -0,0 +1,9 @@
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Siren
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
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}/../..
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
@@ -16,8 +16,6 @@
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
+819
View File
@@ -0,0 +1,819 @@
//
// SirenTests.swift
// SirenTests
//
// Created by Arthur Sabintsev on 6/7/16.
// Copyright © 2016 Sabintsev iOS Projects. All rights reserved.
//
import XCTest
@testable import Siren
final class SirenTests: XCTestCase {
var siren: Siren = Siren.shared
}
// MARK: - API
extension SirenTests {
func testAPIDefaultsToUnitedStatesAppStore() {
XCTAssertEqual(siren.apiManager.country, AppStoreCountry.unitedStates)
}
}
// MARK: - Updates
extension SirenTests {
func testSingleDigitVersionUpdate() {
siren.currentInstalledVersion = "1"
XCTAssertTrue(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "2"))
XCTAssertTrue(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "2.0"))
XCTAssertTrue(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "2.0.0"))
XCTAssertTrue(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "2.0.0.0"))
XCTAssertFalse(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "0"))
XCTAssertFalse(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "0.9"))
XCTAssertFalse(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "0.0.9"))
XCTAssertFalse(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "0.0.0.9"))
}
func testDoubleDigitVersionUpdate() {
siren.currentInstalledVersion = "1.0"
XCTAssertTrue(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "2"))
XCTAssertTrue(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "2.0"))
XCTAssertTrue(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "2.0.0"))
XCTAssertTrue(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "2.0.0.0"))
XCTAssertFalse(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "0"))
XCTAssertFalse(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "0.9"))
XCTAssertFalse(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "0.0.9"))
XCTAssertFalse(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "0.0.0.9"))
}
func testTripleDigitVersionUpdate() {
siren.currentInstalledVersion = "1.0.0"
XCTAssertTrue(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "2"))
XCTAssertTrue(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "2.0"))
XCTAssertTrue(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "2.0.0"))
XCTAssertTrue(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "2.0.0.0"))
XCTAssertFalse(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "0"))
XCTAssertFalse(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "0.9"))
XCTAssertFalse(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "0.0.9"))
XCTAssertFalse(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "0.0.0.9"))
}
func testQuadrupleDigitVersionUpdate() {
siren.currentInstalledVersion = "1.0.0"
XCTAssertTrue(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "2"))
XCTAssertTrue(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "2.0"))
XCTAssertTrue(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "2.0.0"))
XCTAssertTrue(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "2.0.0.0"))
XCTAssertFalse(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "0"))
XCTAssertFalse(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "0.9"))
XCTAssertFalse(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "0.0.9"))
XCTAssertFalse(DataParser.isAppStoreVersionNewer(installedVersion: siren.currentInstalledVersion,
appStoreVersion: "0.0.0.9"))
}
}
// MARK: - Localization
extension SirenTests {
func testArabicLocalization() {
let language: Localization.Language = .arabic
// 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 testArmenianLocalization() {
let language: Localization.Language = .armenian
// 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 testBasqueLocalization() {
let language: Localization.Language = .basque
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Eguneratzea erabilgarri")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Hurrengo batean")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Bertsio honetatik jauzi egin")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Eguneratu")
}
func testChineseSimplifiedLocalization() {
let language: Localization.Language = .chineseSimplified
// 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 testChineseTraditionalLocalization() {
let language: Localization.Language = .chineseTraditional
// 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 testCroatianLocalization() {
let language: Localization.Language = .croatian
// Update Available
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")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Preskoči ovu verziju")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Ažuriraj")
}
func testCzechLocalization() {
let language: Localization.Language = .czech
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Aktualizace dostupná")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Příště")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Přeskočit tuto verzi")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Aktualizovat")
}
func testDanishLocalization() {
let language: Localization.Language = .danish
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Tilgængelig opdatering")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Næste gang")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Spring denne version over")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Opdater")
}
func testDutchLocalization() {
let language: Localization.Language = .dutch
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Update beschikbaar")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Volgende keer")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Sla deze versie over")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Updaten")
}
func testEstonianLocalization() {
let language: Localization.Language = .estonian
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Uuendus saadaval")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Järgmisel korral")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Jäta see version vahele")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Uuenda")
}
func testFinnishLocalization() {
let language: Localization.Language = .finnish
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Päivitys saatavilla")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Ensi kerralla")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Jätä tämä versio väliin")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Päivitys")
}
func testFrenchLocalization() {
let language: Localization.Language = .french
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Mise à jour disponible")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "La prochaine fois")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Sauter cette version")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Mettre à jour")
}
func testGermanLocalization() {
let language: Localization.Language = .german
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Update erhältlich")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Später")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Diese Version überspringen")
// 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), "Αναβάθμιση")
}
func testHebrewLocalization() {
let language: Localization.Language = .hebrew
// 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 testHungarianLocalization() {
let language: Localization.Language = .hungarian
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Új frissítés érhető el")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Később")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Ennél a verziónál ne figyelmeztessen")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Frissítés")
}
func testIndonesianLocalization() {
let language: Localization.Language = .indonesian
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Pembaruan Tersedia")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Lain kali")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Lewati versi ini")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Perbarui")
}
func testItalianLocalization() {
let language: Localization.Language = .italian
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Aggiornamento disponibile")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "La prossima volta")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Salta questa versione")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Aggiorna")
}
func testJapaneseLocalization() {
let language: Localization.Language = .japanese
// 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 testKoreanLocalization() {
let language: Localization.Language = .korean
// 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 testLatvianLocalization() {
let language: Localization.Language = .latvian
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Atjauninājums pieejams")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Nākamreiz")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Izlaist šo versiju")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Atjaunināt")
}
func testLithuanianLocalization() {
let language: Localization.Language = .lithuanian
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Atnaujinimas")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Kitą kartą")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Praleisti šią versiją")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Atnaujinti")
}
func testMalayLocalization() {
let language: Localization.Language = .malay
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Versi Terkini")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Lain kali")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Langkau versi ini")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Muat turun")
}
func testNorwegianLocalization() {
let language: Localization.Language = .norwegian
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Oppdatering tilgjengelig")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Neste gang")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Hopp over denne versjonen")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Oppdater")
}
func testPersianLocalization() {
let language: Localization.Language = .persian
// 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
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Aktualizacja dostępna")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Następnym razem")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Pomiń wersję")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Zaktualizuj")
}
func testPortugueseBrazilLocalization() {
let language: Localization.Language = .portugueseBrazil
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Atualização disponível")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Próxima vez")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Ignorar esta versão")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Atualizar")
}
func testPortuguesePortugalLocalization() {
let language: Localization.Language = .portuguesePortugal
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Nova actualização disponível")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Próxima vez")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Ignorar esta versão")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Actualizar")
}
func testRomanianLocalization() {
let language: Localization.Language = .romanian
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Actualizare disponibilă")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Data viitoare")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Ignor această versiune")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Actualizare")
}
func testRussianLocalization() {
let language: Localization.Language = .russian
// 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 testSerbianCyrillicLocalization() {
let language: Localization.Language = .serbianCyrillic
// 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 testSerbianLatinLocalization() {
let language: Localization.Language = .serbianLatin
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Ažuriranje dostupno")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Sledeći put")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Preskoči ovu verziju")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Ažuriraj")
}
func testSlovenianLocalization() {
let language: Localization.Language = .slovenian
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Posodobitev aplikacije")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Naslednjič")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Ne želim")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Namesti")
}
func testSpanishLocalization() {
let language: Localization.Language = .spanish
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Actualización disponible")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "La próxima vez")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Saltar esta versión")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Actualizar")
}
func testSwedishLocalization() {
let language: Localization.Language = .swedish
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Tillgänglig uppdatering")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Nästa gång")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Hoppa över den här versionen")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Uppdatera")
}
func testThaiLocalization() {
let language: Localization.Language = .thai
// 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 testTurkishLocalization() {
let language: Localization.Language = .turkish
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Güncelleme Mevcut")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Daha sonra")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Boşver")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Güncelle")
}
func testUkrainianLocalization() {
let language: Localization.Language = .ukrainian
// 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
// 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 testVietnameseLocalization() {
let language: Localization.Language = .vietnamese
// Update Available
XCTAssertEqual(Bundle.localizedString(forKey: "Update Available", andForceLocalization: language), "Cập nhật mới")
// Next time
XCTAssertEqual(Bundle.localizedString(forKey: "Next time", andForceLocalization: language), "Lần tới")
// Skip this version
XCTAssertEqual(Bundle.localizedString(forKey: "Skip this version", andForceLocalization: language), "Bỏ qua phiên bản này")
// Update
XCTAssertEqual(Bundle.localizedString(forKey: "Update", andForceLocalization: language), "Cập nhật")
}
}
-5
View File
@@ -1,5 +0,0 @@
# A sample Gemfile
source "https://rubygems.org"
gem "cocoapods", "1.1.1"
gem "jazzy"
-92
View File
@@ -1,92 +0,0 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (2.3.3)
activesupport (4.2.7.1)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
claide (1.0.1)
cocoapods (1.1.1)
activesupport (>= 4.0.2, < 5)
claide (>= 1.0.1, < 2.0)
cocoapods-core (= 1.1.1)
cocoapods-deintegrate (>= 1.0.1, < 2.0)
cocoapods-downloader (>= 1.1.2, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-stats (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.1.1, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored (~> 1.2)
escape (~> 0.0.4)
fourflusher (~> 2.0.1)
gh_inspector (~> 1.0)
molinillo (~> 0.5.1)
nap (~> 1.0)
xcodeproj (>= 1.3.3, < 2.0)
cocoapods-core (1.1.1)
activesupport (>= 4.0.2, < 5)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
cocoapods-deintegrate (1.0.1)
cocoapods-downloader (1.1.2)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.0)
cocoapods-stats (1.0.0)
cocoapods-trunk (1.1.1)
nap (>= 0.8, < 2.0)
netrc (= 0.7.8)
cocoapods-try (1.1.0)
colored (1.2)
escape (0.0.4)
fourflusher (2.0.1)
fuzzy_match (2.0.4)
gh_inspector (1.0.2)
i18n (0.7.0)
jazzy (0.7.4)
cocoapods (~> 1.0)
mustache (~> 0.99)
open4
redcarpet (~> 3.2)
rouge (~> 1.5)
sass (~> 3.4)
sqlite3 (~> 1.3)
xcinvoke (~> 0.3.0)
json (1.8.3)
liferaft (0.0.6)
minitest (5.9.1)
molinillo (0.5.3)
mustache (0.99.8)
nanaimo (0.2.2)
nap (1.1.0)
netrc (0.7.8)
open4 (1.3.4)
redcarpet (3.4.0)
rouge (1.11.1)
sass (3.4.23)
sqlite3 (1.3.13)
thread_safe (0.3.5)
tzinfo (1.2.2)
thread_safe (~> 0.1)
xcinvoke (0.3.0)
liferaft (~> 0.0.6)
xcodeproj (1.4.1)
CFPropertyList (~> 2.3.3)
activesupport (>= 3)
claide (>= 1.0.1, < 2.0)
colored (~> 1.2)
nanaimo (~> 0.2.0)
PLATFORMS
ruby
DEPENDENCIES
cocoapods (= 1.1.1)
jazzy
BUNDLED WITH
1.14.5
+6 -1
View File
@@ -1,5 +1,10 @@
// swift-tools-version:5.5
import PackageDescription
let package = Package(
name: "Siren"
name: "Siren",
platforms: [.iOS(.v13), .tvOS(.v13)],
products: [.library(name: "Siren", targets: ["Siren"])],
targets: [.target(name: "Siren", path: "Sources", resources: [.copy("Siren.bundle"), .copy("PrivacyInfo.xcprivacy")])],
swiftLanguageVersions: [.v5]
)
+163 -181
View File
@@ -1,236 +1,218 @@
# Siren
# Siren 🚨
### Notify users when a new version of your app is available and prompt them to upgrade.
[![CocoaPods](https://img.shields.io/cocoapods/v/Siren.svg)](https://cocoapods.org/pods/Siren) [![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![SwiftPM Compatible](https://img.shields.io/badge/SwiftPM-Compatible-brightgreen.svg)](https://swift.org/package-manager/) [![CocoaPods](https://img.shields.io/cocoapods/dt/Siren.svg)](https://cocoapods.org/pods/Siren) [![CocoaPods](https://img.shields.io/cocoapods/dm/Siren.svg)](https://cocoapods.org/pods/Siren)
![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)
---
# 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.
---
# Table of Contents
- [**Meta**](https://github.com/ArtSabintsev/Siren#meta)
- [About](https://github.com/ArtSabintsev/Siren#about)
- [Features](https://github.com/ArtSabintsev/Siren#features)
- [Screenshots](https://github.com/ArtSabintsev/Siren#screenshots)
- [Ports](https://github.com/ArtSabintsev/Siren#ports)
- [**Installation and Integration**](https://github.com/ArtSabintsev/Siren#installation-and-integration)
- [Installation Instructions](https://github.com/ArtSabintsev/Siren#installation-instructions)
- [Implementation Examples](https://github.com/ArtSabintsev/Siren#implementation-examples)
- [**Device-Specific Checks**](https://github.com/ArtSabintsev/Siren#device-specific-checks)
- [Localization](https://github.com/ArtSabintsev/Siren#localization)
- [Device Compatibility](https://github.com/ArtSabintsev/Siren#device-compatibility)
- [**Testing**](https://github.com/ArtSabintsev/Siren#testing)
- [Testing Siren Locally](https://github.com/ArtSabintsev/Siren#testing-siren-locally)
- [Words of Caution](https://github.com/ArtSabintsev/Siren#words-of-caution)
- [**App Submission**](https://github.com/ArtSabintsev/Siren#app-submission)
- [App Store Review](https://github.com/ArtSabintsev/Siren#app-store-review)
- [Phased Releases](https://github.com/ArtSabintsev/Siren#phased-releases)
- [**Attribution**](https://github.com/ArtSabintsev/Siren#attribution)
- [Special Thanks](https://github.com/ArtSabintsev/Siren#special-thanks)
- [Creator](https://github.com/ArtSabintsev/Siren#creator)
---
# Meta
## About
**Siren** checks a user's currently installed version of your iOS app against the version that is currently available in the App Store.
If a new version is available, an alert can be presented to the user informing them of the newer version, and giving them the option to update the application. Alternatively, Siren can notify your app programmatically, enabling you to inform the user through alternative means, such as a custom interface.
If a new version is available, a language localized alert can be presented to the user informing them of the newer version, and giving them the option to update the application. Alternatively, Siren can notify your app through alternative means, such as a custom user interface.
- Siren is built to work with the [**Semantic Versioning**](http://semver.org/) system.
- Semantic Versioning is a three number versioning system (e.g., 1.0.0)
- Siren also supports two-number versioning (e.g., 1.0) and four-number versioning (e.g., 1.0.0.0)
- Siren is actively maintained by [**Arthur Sabintsev**](http://github.com/ArtSabintsev) and [**Aaron Brager**](http://twitter.com/getaaron)
## README Translations
- [**简体中文**](README.zh_CN.md) (by [**Daniel Hu**](http://www.jianshu.com/u/d8bbc4831623))
## Ports
- Siren is a Swift language port of [**Harpy**](http://github.com/ArtSabintsev/Harpy), an Objective-C library that achieves the same functionality.
- Siren and Harpy are maintained by the same developers.
- This library was the inspiration for [**Egghead Games' Siren library**](https://github.com/eggheadgames/Siren), which achieves the same functionality with the Google Play store on the Android platform.
- This library was the inspiration for [**Gant Laborde's Siren library**](https://github.com/GantMan/react-native-siren), which achieves the same functionality for React Native projects (iOS/Android).
Siren is built to work with the [**Semantic Versioning**](https://semver.org/) system.
- Canonical Semantic Versioning uses a three number versioning system (e.g., 1.0.0)
- Siren also supports two-number versioning (e.g., 1.0) and four-number versioning (e.g., 1.0.0.0)
## Features
- [x] CocoaPods Support
- [x] Carthage Support
- [x] Swift Package Manager Support
- [x] Localized for 30+ languages (See **Localization**)
- [x] Pre-Update Device Compatibility Check (See **Device Compatibility**)
- [x] Three types of alerts (see **Screenshots**)
- [x] Optional delegate methods (see **Optional Delegate**)
- [x] Unit Tests!
### Current Features
- [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))
---
## Screenshots
- The **left picture** forces the user to update the app.
- The **center picture** gives the user the option to update the app.
- The **right picture** gives the user the option to skip the current update.
- These options are controlled by the `SirenAlertType` enum.
- These options are controlled by the `Rules.AlertType` enum.
<img src="https://github.com/ArtSabintsev/Harpy/blob/master/samplePictures/picForcedUpdate.png?raw=true" height=480">
<img src="https://github.com/ArtSabintsev/Harpy/blob/master/samplePictures/picOptionalUpdate.png?raw=true" height=480">
<img src="https://github.com/ArtSabintsev/Harpy/blob/master/samplePictures/picSkippedUpdate.png?raw=true" height=480">
<img src="https://github.com/ArtSabintsev/Siren/blob/master/Assets/picForcedUpdate.png?raw=true" height="480"><img src="https://github.com/ArtSabintsev/Siren/blob/master/Assets/picOptionalUpdate.png?raw=true" height="480"><img src="https://github.com/ArtSabintsev/Siren/blob/master/Assets/picSkippedUpdate.png?raw=true" height="480">
## Ports
- **Objective-C (iOS)**
- [**Harpy**](https://github.com/ArtSabintsev/Harpy)
- Siren was ported _from_ Harpy, as Siren and Harpy are maintained by the same developer.
- As of December 2018, Harpy has been deprecated in favor of Siren.
- **Java (Android)**
- [**Egghead Games' Siren library**](https://github.com/eggheadgames/Siren)
- The Siren Swift library inspired the Java library.
- **React Native (iOS)**
- [**Gant Laborde's Siren library**](https://github.com/GantMan/react-native-siren)
- The Siren Swift library inspired the React Native library.
---
# Installation and Integration
## Installation Instructions
| Swift Version | Branch Name | Will Continue to Receive Updates?
| ------------- | ------------- | -------------
| 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
| 3.2 | swift3.2 | No
| 3.1 | swift3.1 | No
| 2.3 | swift2.3 | No
### CocoaPods
For Swift 3 support:
```ruby
pod 'Siren'
```
For Swift 2.3 support:
```ruby
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift2.3'
```
For Swift 2.2 support:
```ruby
pod 'Siren', '0.9.5'
```
### Carthage
For Swift 3 support:
``` swift
github "ArtSabintsev/Siren"
```
For Swift 2.3 support:
``` swift
github "ArtSabintsev/Siren" "swift2.3"
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
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift3.2' # Swift 3.2
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift3.1' # Swift 3.1
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift2.3' # Swift 2.3
```
### Swift Package Manager
```swift
.Package(url: "https://github.com/ArtSabintsev/Siren.git", majorVersion: 1)
.Package(url: "https://github.com/ArtSabintsev/Siren.git", majorVersion: 6)
```
## Setup
Here's some commented sample code. Adapt this to meet your app's needs. For a full list of optional settings/preferences, please refer to https://github.com/ArtSabintsev/Siren/blob/master/Sample%20App/Sample%20App/AppDelegate.swift in the Sample Project.
```Swift
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
/* Siren code should go below window?.makeKeyAndVisible() */
// Siren is a singleton
let siren = Siren.shared
// Optional: Defaults to .Option
siren.alertType = <#SirenAlertType_Enum_Value#>
/*
Replace .Immediately with .Daily or .Weekly to specify a maximum daily or weekly frequency for version
checks.
*/
siren.checkVersion(checkType: .immediately)
return true
}
func applicationDidBecomeActive(application: UIApplication) {
/*
Perform daily (.Daily) or weekly (.Weekly) checks for new version of your app.
Useful if user returns to your app from the background after extended period of time.
Place in applicationDidBecomeActive(_:). */
Siren.shared.checkVersion(checkType: .daily)
}
func applicationWillEnterForeground(application: UIApplication) {
/*
Useful if user returns to your app from the background after being sent to the
App Store, but doesn't update their app before coming back to your app.
ONLY USE WITH SirenAlertType.Force
*/
Siren.shared.checkVersion(checkType: .immediately)
}
```
And you're all set!
### Prompting for Updates without Alerts
Some developers may want to display a less obtrusive custom interface, like a banner or small icon. To accomplish this, you can disable alert presentation by doing the following:
## Implementation Examples
Implementing Siren is as easy as adding two lines of code to your app in **either** `AppDelegate.swift` or `SceneDelegate.swift`:
### AppDelegate.swift Example
```swift
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
...
siren.delegate = self
siren.alertType = .None
...
}
import Siren // Line 1
import UIKit
extension AppDelegate: SirenDelegate {
// Returns a localized message to this delegate method upon performing a successful version check
func sirenDidDetectNewVersionWithoutAlert(message: String) {
print("\(message)")
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
window?.makeKeyAndVisible()
Siren.shared.wail() // Line 2
return true
}
}
```
Siren will call the `sirenDidDetectNewVersionWithoutAlert(message: String)` delegate method, passing a localized, suggested update string suitable for display. Implement this method to display your own messaging, optionally using `message`.
## Differentiated Alerts for Revision, Patch, Minor, and Major Updates
If you would like to set a different type of alert for revision, patch, minor, and/or major updates, simply add one or all of the following *optional* lines to your setup *before* calling the `checkVersion()` method:
### SceneDelegate.swift Example
```swift
/* Siren defaults to SirenAlertType.Option for all updates */
siren.shared.revisionUpdateAlertType = <#SirenAlertType_Enum_Value#>
siren.shared.patchUpdateAlertType = <#SirenAlertType_Enum_Value#>
siren.shared.minorUpdateAlertType = <#SirenAlertType_Enum_Value#>
siren.shared.majorUpdateAlertType = <#SirenAlertType_Enum_Value#>
```
import Siren // Line 1
import UIKit
## Optional Delegate and Delegate Methods
Six delegate methods allow you to handle or track the user's behavior. Each method has a default, empty implementation, effectively making each of these methods optional.
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
``` swift
public protocol SirenDelegate: class {
func sirenDidShowUpdateDialog(alertType: SirenAlertType) // User presented with update dialog
func sirenUserDidLaunchAppStore() // User did click on button that launched App Store.app
func sirenUserDidSkipVersion() // User did click on button that skips version update
func sirenUserDidCancel() // User did click on button that cancels update dialog
func sirenDidFailVersionCheck(error: NSError) // Siren failed to perform version check (may return system-level error)
func sirenDidDetectNewVersionWithoutAlert(message: String) // Siren performed version check and did not display alert
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
window?.makeKeyAndVisible()
Siren.shared.wail() // Line 2
return true
}
}
```
Siren also has plenty of customization options. All examples can be found in the Example Project's [**AppDelegate**](https://github.com/ArtSabintsev/Siren/blob/master/Example/Example/AppDelegate.swift) file. Uncomment the example you'd like to test.
---
# Device-Specific Checks
## Localization
Siren is localized for
- Arabic
- Armenian
- Basque
- Chinese (Simplified and Traditional)
- Danish
- Dutch
- English
- Estonian
- Finnish
- French
- German
- Greek
- Hebrew
- Hungarian
- Indonesian
- Italian
- Japanese
- Korean
- Latvian
- Lithuanian
- Malay
- Norwegian (Bokmål)
- Polish
- Portuguese (Brazil and Portugal)
- Russian
- Serbian (Cyrillic and Latin)
- Slovenian
- Swedish
- Spanish
- Thai
- Turkish
- Vietnamese
Siren is localized for the following languages:
You may want the update dialog to *always* appear in a certain language, ignoring iOS's language setting (e.g. apps released in a specific country).
Arabic, Armenian, Basque, Chinese (Simplified and Traditional), Croatian, Czech, Danish, Dutch, English, Estonian, Finnish, French, German, Greek, Hebrew, Hungarian, Indonesian, Italian, Japanese, Korean, Latvian, Lithuanian, Malay, Norwegian (Bokmål), Persian (Afghanistan, Iran, Persian), Polish, Portuguese (Brazil and Portugal), Romanian, Russian, Serbian (Cyrillic and Latin), Slovenian, Spanish, Swedish, Thai, Turkish, Ukrainian, Urdu, Vietnamese
You can enable it like this:
If your user's device is set to one of the supported locales, an update message will appear in that language. If a locale is not supported, than the message will appear in English.
You may want the update dialog to *always* appear in a certain language, ignoring the user's device-specific setting. You can enable it like so:
```swift
Siren.shared.forceLanguageLocalization = SirenLanguageType.<#SirenLanguageType_Enum_Value#>
// In this example, we force the `Russian` language.
Siren.shared.presentationManager = PresentationManager(forceLanguageLocalization: .russian)
```
## Device Compatibility
If an app update is available, Siren checks to make sure that the version of iOS on the user's device is compatible the one that is required by the app update. For example, if a user has iOS 9 installed on their device, but the app update requires iOS 10, an alert will not be shown. This takes care of the *false positive* case regarding app updating.
If an app update is available, Siren checks to make sure that the version of iOS on the user's device is compatible with the one that is required by the app update. For example, if a user has iOS 11 installed on their device, but the app update requires iOS 12, an alert will not be shown. This takes care of the *false positive* case regarding app updating.
## Testing Siren
Temporarily change the version string in Xcode (within the `.xcodeproj`) to an older version than the one that's currently available in the App Store. Afterwards, build and run your app, and you should see the alert.
---
If you currently don't have an app in the store, change your bundleID to one that is already in the store. In the sample app packaged with this library, we use the [iTunes Connect Mobile](https://itunes.apple.com/us/app/itunes-connect/id376771144?mt=8) app's bundleID: `com.apple.itunesconnect.mobile`.
# Testing
For your convenience, you may turn on debugging statements by setting `self.debugEnabled = true` before calling the `checkVersion()` method.
## Testing Siren Locally
Temporarily change the version string in Xcode (within the `.xcodeproj` file) to an older version than the one that's currently available in the App Store. Afterwards, build and run your app, and you should see the alert.
## App Store Submissions
If you currently don't have an app in the store, change your bundleID to one that is already in the store. In the sample app packaged with this library, we use Facebook's Bundle ID: `com.facebook.Facebook`.
## Words of Caution
Occasionally, the iTunes JSON will update faster than the App Store CDN, meaning the JSON may state that the new version of the app has been released, while no new binary is made available for download via the App Store. It is for this reason that Siren will, by default, wait 1 day (24 hours) after the JSON has been updated to prompt the user to update. To change the default setting, please modify the value of `showAlertAfterCurrentVersionHasBeenReleasedForDays`.
---
# App Submission
## App Store Review
The App Store reviewer will **not** see the alert. The version in the App Store will always be older than the version being reviewed.
## Created and maintained by
[Arthur Ariel Sabintsev](http://www.sabintsev.com/) & [Aaron Brager](http://twitter.com/getaaron)
## Phased Releases
In 2017, Apple announced the [ability to rollout app updates gradually (a.k.a. Phased Releases)](https://itunespartner.apple.com/en/apps/faq/Managing%20Your%20Apps_Submission%20Process). Siren will continue to work as it has in the past, presenting an update modal to _all_ users. If you opt-in to a phased rollout for a specific version, you have a few choices:
- You can leave Siren configured as normal. Phased rollout will continue to auto-update apps. Since all users can still manually update your app directly from the App Store, Siren will ignore the phased rollout and will prompt users to update.
- You can set `showAlertAfterCurrentVersionHasBeenReleasedForDays` to `7`, and Siren will not prompt any users until the latest version is 7 days old, after the phased rollout is complete.
- You can remotely disable Siren until the rollout is done using your own API / backend logic.
---
# Attribution
## Special Thanks
A massive shout-out and thank you goes to the following folks:
- [Aaron Brager](https://twitter.com/@getaaron) for motivating me and assisting me in building the initial proof-of-concept of Siren (based on [Harpy](https:github.com/ArtSabintsev/Harpy)) back in 2015. Without him, Siren may never have been built.
- All of [Harpy's Contributors](https://github.com/ArtSabintsev/Harpy/graphs/contributors) for helping building the feature set from 2012-2015 that was used as the basis for the first version of Siren.
- All of [Siren's Contributors](https://github.com/ArtSabintsev/Siren/graphs/contributors) for helping make Siren as powerful and bug-free as it currently is today.
## Creator
[Arthur Ariel Sabintsev](http://www.sabintsev.com/)
-232
View File
@@ -1,232 +0,0 @@
# Siren [English](README.md)
### 当您的 app 有新版本可用时提示用户进行更新。
[![Travis-CI](https://travis-ci.org/ArtSabintsev/Siren.svg?branch=master)](https://travis-ci.org/ArtSabintsev/Siren) [![CocoaPods](https://img.shields.io/cocoapods/v/Siren.svg)](https://cocoapods.org/pods/Siren) [![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![SwiftPM Compatible](https://img.shields.io/badge/SwiftPM-Compatible-brightgreen.svg)](https://swift.org/package-manager/) [![CocoaPods](https://img.shields.io/cocoapods/dt/Siren.svg)](https://cocoapods.org/pods/Siren) [![CocoaPods](https://img.shields.io/cocoapods/dm/Siren.svg)](https://cocoapods.org/pods/Siren)
---
## 关于
**Siren** 用于检测用户当前安装版本是否是 App Store 上的最新可用版本。
当 app 有更新时,Siren 会弹出提示框,用户可根据提示框提供的选项进行更新。或者您也可以根据 Siren 发出的消息来自定义通知用户的方式,比如您可以提供一个自定义的提示框。
- Siren 可配合 [**Semantic Versioning**](http://semver.org/) 系统使用
- Semantic 版本系统由三位数字标识 (比如,1.0.0)
- Siren 同时支持两位数字标识 (比如,1.0)
- Siren 同时支持四位数字标识 (比如,1.0.0.0)
- Siren 当前处于活跃维护状态,由[**Arthur Sabintsev**](http://github.com/ArtSabintsev) 和 [**Aaron Brager**](http://twitter.com/getaaron) 进行维护。
## Ports
- [**Harpy**](http://github.com/ArtSabintsev/Harpy) 是 Objective-C 实现的版本更新检查库,Siren 是 Harpy 的 swift 版本。
- Siren 和 Harpy 是由相同的开发者维护。
- 安卓平台 Play Store 上的 [**Egghead Games' Siren library**](https://github.com/eggheadgames/Siren) 库使用了和 Siren 相同的原理实现了版本更新检测。
- 针对 React Native 项目 (iOS/Android) 的 [**Gant Laborde's Siren library**](https://github.com/GantMan/react-native-siren) 库使用了和 Siren 相同的原理实现了版本更新检测。
## 特点
- [x] 支持 Cocoapods
- [x] 支持 Carthage
- [x] 支持 Swift 包管理器
- [x] 30+ 语言本地化 (查看**本地化**)
- [x] 设备兼容性检测 (查看**设备兼容性**)
- [x] 三种类型的弹出提示框 (查看**截图**)
- [x] 可选代理方法 (查看**可选代理**)
- [x] 单元测试!
## 截图
- **左图** 强制用户更新
- **中间** 给用户提供更新选项
- **右图** 给用户提供更新和跳过更新选项
- 这些选项对应着 `SirenAlertType` 枚举类型
<img src="https://github.com/ArtSabintsev/Harpy/blob/master/samplePictures/picForcedUpdate.png?raw=true" height=480">
<img src="https://github.com/ArtSabintsev/Harpy/blob/master/samplePictures/picOptionalUpdate.png?raw=true" height=480">
<img src="https://github.com/ArtSabintsev/Harpy/blob/master/samplePictures/picSkippedUpdate.png?raw=true" height=480">
## 安装指南
### CocoaPods
Swift 3 版本:
```ruby
pod 'Siren'
```
Swift 2.3 版本:
```ruby
pod 'Siren', :git => 'https://github.com/ArtSabintsev/Siren.git', :branch => 'swift2.3'
```
Swift 2.2 版本:
```ruby
pod 'Siren', '0.9.5'
```
### Carthage
FSwift 3 版本:
``` swift
github "ArtSabintsev/Siren"
```
Swift 2.3 版本:
``` swift
github "ArtSabintsev/Siren" "swift2.3"
```
### Swift 包管理器
```swift
.Package(url: "https://github.com/ArtSabintsev/Siren.git", majorVersion: 1)
```
## 使用
下面是一些示例代码。请根据您的需求进行修改。更详细的使用说明请参考示例项目中的 https://github.com/ArtSabintsev/Siren/blob/master/Sample%20App/Sample%20App/AppDelegate.swift。
```Swift
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
/* Siren code should go below window?.makeKeyAndVisible() */
// Siren is a singleton
let siren = Siren.sharedInstance
// Optional: Defaults to .Option
siren.alertType = <#SirenAlertType_Enum_Value#>
/*
Replace .Immediately with .Daily or .Weekly to specify a maximum daily or weekly frequency for version
checks.
*/
siren.checkVersion(checkType: .immediately)
return true
}
func applicationDidBecomeActive(application: UIApplication) {
/*
Perform daily (.Daily) or weekly (.Weekly) checks for new version of your app.
Useful if user returns to your app from the background after extended period of time.
Place in applicationDidBecomeActive(_:). */
Siren.sharedInstance.checkVersion(checkType: .daily)
}
func applicationWillEnterForeground(application: UIApplication) {
/*
Useful if user returns to your app from the background after being sent to the
App Store, but doesn't update their app before coming back to your app.
ONLY USE WITH SirenAlertType.Force
*/
Siren.sharedInstance.checkVersion(checkType: .immediately)
}
```
### 使用非弹出提示框进行提示
您可以使用顶部条幅等更友好的方式进行提示。首先,您需要通过下面代码禁用弹出提示框:
```swift
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
...
siren.delegate = self
siren.alertType = .None
...
}
extension AppDelegate: SirenDelegate {
// 当检测到有更新可用时向该代理方法传递一个本地化的提示信息
func sirenDidDetectNewVersionWithoutAlert(message: String) {
print("\(message)")
}
}
```
Siren 会调用 `sirenDidDetectNewVersionWithoutAlert(message: String)` 代理方法,该方法传递了一个本地化的更新提示信息作为参数。您可以使用该参数作为提示信息,也可以使用自定义的提示信息。
## 为修订版,补丁,小版本,大版本设置不同的提示框类型
您可以为修订版,补丁,小版本,大版本等设置不同提示框类型,只需要在 `checkVersion()` 方法前调用进行如下设置即可:
```swift
/* Siren defaults to SirenAlertType.Option for all updates */
siren.sharedInstance().revisionUpdateAlertType = <#SirenAlertType_Enum_Value#>
siren.sharedInstance().patchUpdateAlertType = <#SirenAlertType_Enum_Value#>
siren.sharedInstance().minorUpdateAlertType = <#SirenAlertType_Enum_Value#>
siren.sharedInstance().majorUpdateAlertType = <#SirenAlertType_Enum_Value#>
```
##可选代理和代理方法
您可以通过下面六个代理方法跟踪用户进行的操作。
``` swift
public protocol SirenDelegate: class {
func sirenDidShowUpdateDialog(alertType: SirenAlertType) // 弹出更新提示框
func sirenUserDidLaunchAppStore() // 用户点击去 app store 更新
func sirenUserDidSkipVersion() // 用户点击跳过此次更新
func sirenUserDidCancel() // 用户点击取消更新
func sirenDidFailVersionCheck(error: NSError) // 检查更新失败(可能返回系统级别的错误)
func sirenDidDetectNewVersionWithoutAlert(message: String) // 检测到更新但不弹出提示框
}
```
## 本地化
Siren 为以下国家做了本地化
- Arabic
- Armenian
- Basque
- Chinese (Simplified and Traditional)
- Danish
- Dutch
- English
- Estonian
- Finnish
- French
- German
- Greek
- Hebrew
- Hungarian
- Indonesian
- Italian
- Japanese
- Korean
- Latvian
- Lithuanian
- Malay
- Norwegian (Bokmål)
- Polish
- Portuguese (Brazil and Portugal)
- Russian
- Serbian (Cyrillic and Latin)
- Slovenian
- Swedish
- Spanish
- Thai
- Turkish
- Vietnamese
您可以通过以下代码忽略 iOS 系统语言设置,为弹出框设置固定语言。
```swift
Siren.sharedInstance.forceLanguageLocalization = SirenLanguageType.<#SirenLanguageType_Enum_Value#>
```
## 设备兼容性
当有更新可用时,Siren 会检测用户的 iOS 版本号是否符合更新需求。比如,用户的系统是 iOS 9,但此次更新只针对 iOS 10,这时是不会出现弹出提示框。
## 测试
测试时,需要暂时将 Xcode 里(`.xcodeproj` 文件) 的版本号修改为比当前苹果商店中的可用版本号大。这样编译运行 app 时,您就可以看到弹出提示框。
如果您尚未发布过 App,把 bundleID 修改为一个 app store 已经存在的 bundleID。在示例项目中,我们使用了 [iTunes Connect Mobile](https://itunes.apple.com/us/app/itunes-connect/id376771144?mt=8) 的 bundleID`com.apple.itunesconnect.mobile`。
为方便调试,您可以在调用 `checkVersion()` 方法前通过 `self.debugEnabled = true` 来开启调试模式。
## 提交至 App Store
因为商店里的可用版本总是比提交审核的版本老,所以苹果商店审核人员在审核时是**不会**弹出提示框的。
##创建维护人员
[Arthur Ariel Sabintsev](http://www.sabintsev.com/) & [Aaron Brager](http://twitter.com/getaaron)
## 翻译人员
[Daniel Hu](http://www.jianshu.com/u/d8bbc4831623)
+17 -17
View File
@@ -1,23 +1,23 @@
Pod::Spec.new do |s|
# Version
s.version = "6.1.3"
s.swift_version = "5.5"
# Meta
s.name = "Siren"
s.version = "1.2.0"
s.summary = "Notify users when a new version of your iOS app is available, and prompt them with the App Store link.."
s.description = <<-DESC
Siren is checks a users currently installed version of your iOS app against the version that is currently available in the App Store. If a new version is available, an instance of UIAlertController can be presented to the user informing them of the newer version, and giving them the option to update the application. Alternatively, Siren can notify your app programmatically, enabling you to inform the user through alternative means, such as a custom interface.
Siren is built to work with the Semantic Versioning system.
Siren is a Swift port of Harpy, an Objective-C library that achieves the same functionality.
Siren is actively maintained by Arthur Sabintsev and Aaron Brager.
DESC
s.summary = "Notify users that a new version of your iOS app is available, and prompt them with the App Store link."
s.homepage = "https://github.com/ArtSabintsev/Siren"
s.license = "MIT"
s.authors = { "Arthur Ariel Sabintsev" => "arthur@sabintsev.com", "Aaron Brager" => "getaaron@gmail.com" }
s.platform = :ios, "8.0"
s.source = { :git => "https://github.com/ArtSabintsev/Siren.git", :tag => s.version.to_s }
s.source_files = 'Siren/Siren.swift'
s.resources = 'Siren/Siren.bundle'
s.requires_arc = true
s.authors = { "Arthur Ariel Sabintsev" => "arthur@sabintsev.com" }
s.description = <<-DESC
Notify your users when a new version of your iOS app is available, and prompt them with the App Store link.
DESC
# Compatibility & Sources
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
-751
View File
@@ -1,751 +0,0 @@
//
// Siren.swift
// Siren
//
// Created by Arthur Sabintsev on 1/3/15.
// Copyright (c) 2015 Sabintsev iOS Projects. All rights reserved.
//
import UIKit
// MARK: - SirenDelegate Protocol
/// Delegate that handles all codepaths for Siren upon version check completion.
public protocol SirenDelegate: class {
/// User presented with update dialog
func sirenDidShowUpdateDialog(alertType: SirenAlertType)
/// User did click on button that launched App Store.app
func sirenUserDidLaunchAppStore()
/// User did click on button that skips version update
func sirenUserDidSkipVersion()
/// User did click on button that cancels update dialog
func sirenUserDidCancel()
/// Siren failed to perform version check (may return system-level error)
func sirenDidFailVersionCheck(error: NSError)
/// Siren performed version check and did not display alert
func sirenDidDetectNewVersionWithoutAlert(message: String)
/// Siren performed version check and latest version is installed
func sirenLatestVersionInstalled()
}
// MARK: - SirenDelegate Protocol Extension
public extension SirenDelegate {
func sirenDidShowUpdateDialog(alertType: SirenAlertType) {}
func sirenUserDidLaunchAppStore() {}
func sirenUserDidSkipVersion() {}
func sirenUserDidCancel() {}
func sirenDidFailVersionCheck(error: NSError) {}
func sirenDidDetectNewVersionWithoutAlert(message: String) {}
func sirenLatestVersionInstalled() {}
}
/// Determines the type of alert to present after a successful version check has been performed.
public enum SirenAlertType {
/// Forces user to update your app (1 button alert).
case force
/// (DEFAULT) Presents user with option to update app now or at next launch (2 button alert).
case option
/// Presents user with option to update the app now, at next launch, or to skip this version all together (3 button alert).
case skip
/// Doesn't show the alert, but instead returns a localized message for use in a custom UI within the sirenDidDetectNewVersionWithoutAlert() delegate method.
case none
}
/// Determines the frequency in which the the version check is performed.
///
public enum SirenVersionCheckType: Int {
/// Version check performed every time the app is launched.
case immediately = 0
/// Version check performed once a day.
case daily = 1
/// Version check performed once a week.
case weekly = 7
}
/// Determines the available languages in which the update message and alert button titles should appear.
///
/// 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()
public enum SirenLanguageType: String {
case Arabic = "ar"
case Armenian = "hy"
case Basque = "eu"
case ChineseSimplified = "zh-Hans"
case ChineseTraditional = "zh-Hant"
case Croatian = "hr"
case Danish = "da"
case Dutch = "nl"
case English = "en"
case Estonian = "et"
case Finnish = "fi"
case French = "fr"
case German = "de"
case Greek = "el"
case Hebrew = "he"
case Hungarian = "hu"
case Indonesian = "id"
case Italian = "it"
case Japanese = "ja"
case Korean = "ko"
case Latvian = "lv"
case Lithuanian = "lt"
case Malay = "ms"
case Norwegian = "nb-NO"
case Polish = "pl"
case PortugueseBrazil = "pt"
case PortuguesePortugal = "pt-PT"
case Russian = "ru"
case SerbianCyrillic = "sr-Cyrl"
case SerbianLatin = "sr-Latn"
case Slovenian = "sl"
case Spanish = "es"
case Swedish = "sv"
case Thai = "th"
case Turkish = "tr"
case Vietnamese = "vi"
}
/// Siren-specific Error Codes
private enum SirenErrorCode: Int {
case malformedURL = 1000
case recentlyCheckedAlready
case noUpdateAvailable
case appStoreDataRetrievalFailure
case appStoreJSONParsingFailure
case appStoreOSVersionNumberFailure
case appStoreOSVersionUnsupported
case appStoreVersionNumberFailure
case appStoreVersionArrayFailure
case appStoreAppIDFailure
}
/// Siren-specific Throwable Errors
private enum SirenError: Error {
case malformedURL
case missingBundleIdOrAppId
}
/// Siren-specific UserDefaults Keys
private enum SirenUserDefaults: String {
/// Key that stores the timestamp of the last version check in UserDefaults
case StoredVersionCheckDate
/// Key that stores the version that a user decided to skip in UserDefaults.
case StoredSkippedVersion
}
// MARK: - Siren
/// The Siren Class. A singleton that is initialized using the shared() method.
public final class Siren: NSObject {
///Current installed version of your app
fileprivate var currentInstalledVersion: String? = {
return Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String
}()
/// The error domain for all errors created by Siren
public let SirenErrorDomain = "Siren Error Domain"
/// The SirenDelegate variable, which should be set if you'd like to be notified:
///
/// When a user views or interacts with the alert
/// - sirenDidShowUpdateDialog(alertType: SirenAlertType)
/// - sirenUserDidLaunchAppStore()
/// - sirenUserDidSkipVersion()
/// - sirenUserDidCancel()
///
/// When a new version has been detected, and you would like to present a localized message in a custom UI
/// - sirenDidDetectNewVersionWithoutAlert(message: String)
public weak var delegate: SirenDelegate?
/// The debug flag, which is disabled by default.
/// When enabled, a stream of println() statements are logged to your console when a version check is performed.
public lazy var debugEnabled = false
/// Determines the type of alert that should be shown.
/// See the SirenAlertType enum for full details.
public var alertType = SirenAlertType.option {
didSet {
majorUpdateAlertType = alertType
minorUpdateAlertType = alertType
patchUpdateAlertType = alertType
revisionUpdateAlertType = alertType
}
}
/// Determines the type of alert that should be shown for major version updates: A.b.c
/// Defaults to SirenAlertType.Option.
/// See the SirenAlertType enum for full details.
public lazy var majorUpdateAlertType = SirenAlertType.option
/// Determines the type of alert that should be shown for minor version updates: a.B.c
/// Defaults to SirenAlertType.Option.
/// See the SirenAlertType enum for full details.
public lazy var minorUpdateAlertType = SirenAlertType.option
/// Determines the type of alert that should be shown for minor patch updates: a.b.C
/// Defaults to SirenAlertType.Option.
/// See the SirenAlertType enum for full details.
public lazy var patchUpdateAlertType = SirenAlertType.option
/// Determines the type of alert that should be shown for revision updates: a.b.c.D
/// Defaults to SirenAlertType.Option.
/// See the SirenAlertType enum for full details.
public lazy var revisionUpdateAlertType = SirenAlertType.option
/// The name of your app.
/// By default, it's set to the name of the app that's stored in your plist.
public lazy var appName: String = Bundle.main.bestMatchingAppName()
/// The region or country of an App Store in which your app is available.
/// By default, all version checks are performed against the US App Store.
/// If your app is not available in the US App Store, set it to the identifier of at least one App Store within which it is available.
public var countryCode: String?
/// Overrides the default localization of a user's device when presenting the update message and button titles in the alert.
/// See the SirenLanguageType enum for more details.
public var forceLanguageLocalization: SirenLanguageType?
/// Overrides the tint color for UIAlertController.
public var alertControllerTintColor: UIColor?
/// When this is set, the alert will only show up if the current version has already been released for X days
public var showAlertAfterCurrentVersionHasBeenReleasedForDays: Int?
/// The current version of your app that is available for download on the App Store
public fileprivate(set) var currentAppStoreVersion: String?
fileprivate var appID: Int?
fileprivate var lastVersionCheckPerformedOnDate: Date?
fileprivate lazy var alertViewIsVisible: Bool = false
fileprivate var updaterWindow: UIWindow?
/// The App's Singleton
public static let shared = Siren()
@available(*, deprecated: 1.2.0, unavailable, renamed: "shared")
public static let sharedInstance = Siren()
override init() {
lastVersionCheckPerformedOnDate = UserDefaults.standard.object(forKey: SirenUserDefaults.StoredVersionCheckDate.rawValue) as? Date
}
/// Checks the currently installed version of your app against the App Store.
/// The default check is against the US App Store, but if your app is not listed in the US,
/// you should set the `countryCode` property before calling this method. Please refer to the countryCode property for more information.
///
/// - Parameters:
/// - checkType: The frequency in days in which you want a check to be performed. Please refer to the SirenVersionCheckType enum for more details.
public func checkVersion(checkType: SirenVersionCheckType) {
guard let _ = Bundle.bundleID() else {
printMessage(message: "Please make sure that you have set a `Bundle Identifier` in your project.")
return
}
if checkType == .immediately {
performVersionCheck()
} else {
guard let lastVersionCheckPerformedOnDate = lastVersionCheckPerformedOnDate else {
performVersionCheck()
return
}
if days(since: lastVersionCheckPerformedOnDate) >= checkType.rawValue {
performVersionCheck()
} else {
postError(.recentlyCheckedAlready, underlyingError: nil)
}
}
}
}
// MARK: - Helpers (Networking)
private extension Siren {
func performVersionCheck() {
do {
let url = try iTunesURLFromString()
let request = URLRequest(url: url, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: 30)
let task = URLSession.shared.dataTask(with: request, completionHandler: { [unowned self] (data, _, error) in
if let error = error {
self.postError(.appStoreDataRetrievalFailure, underlyingError: error)
} else {
guard let data = data else {
self.postError(.appStoreDataRetrievalFailure, underlyingError: nil)
return
}
do {
let jsonData = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments)
guard let appData = jsonData as? [String: Any],
self.isUpdateCompatibleWithDeviceOS(appData: appData) else {
self.postError(.appStoreJSONParsingFailure, underlyingError: nil)
return
}
DispatchQueue.main.async {
// Print iTunesLookup results from appData
self.printMessage(message: "JSON results: \(appData)")
// Process Results (e.g., extract current version that is available on the AppStore)
self.processVersionCheck(withResults: appData)
}
} catch let error as NSError {
self.postError(.appStoreDataRetrievalFailure, underlyingError: error)
}
}
})
task.resume()
} catch let error as NSError {
postError(.malformedURL, underlyingError: error)
}
}
func processVersionCheck(withResults results: [String: Any]) {
storeVersionCheckDate() // Store version comparison date
guard let allResults = results["results"] as? [[String: Any]] else {
self.postError(.appStoreVersionNumberFailure, underlyingError: nil)
return
}
/// Condition satisfied when app not in App Store
guard !allResults.isEmpty else {
postError(.appStoreDataRetrievalFailure, underlyingError: nil)
return
}
guard let appID = allResults.first?["trackId"] as? Int else {
postError(.appStoreAppIDFailure, underlyingError: nil)
return
}
self.appID = appID
guard let currentAppStoreVersion = allResults.first?["version"] as? String else {
self.postError(.appStoreVersionArrayFailure, underlyingError: nil)
return
}
self.currentAppStoreVersion = currentAppStoreVersion
guard isAppStoreVersionNewer() else {
delegate?.sirenLatestVersionInstalled()
postError(.noUpdateAvailable, underlyingError: nil)
return
}
guard let alertDays = showAlertAfterCurrentVersionHasBeenReleasedForDays else {
showAlertIfCurrentAppStoreVersionNotSkipped()
return
}
guard let currentVersionReleaseDate = allResults.first?["currentVersionReleaseDate"] as? String,
let daysSinceRelease = days(since: currentVersionReleaseDate),
daysSinceRelease >= alertDays else {
return
}
showAlertIfCurrentAppStoreVersionNotSkipped()
showAlertAfterCurrentVersionHasBeenReleasedForDays = nil
}
func iTunesURLFromString() throws -> URL {
var components = URLComponents()
components.scheme = "https"
components.host = "itunes.apple.com"
components.path = "/lookup"
var items: [URLQueryItem] = [URLQueryItem(name: "bundleId", value: Bundle.bundleID())]
if let countryCode = countryCode {
let item = URLQueryItem(name: "country", value: countryCode)
items.append(item)
}
components.queryItems = items
guard let url = components.url, !url.absoluteString.isEmpty else {
throw SirenError.malformedURL
}
return url
}
}
// MARK: - Helpers (Alert)
private extension Siren {
func showAlertIfCurrentAppStoreVersionNotSkipped() {
alertType = setAlertType()
guard let previouslySkippedVersion = UserDefaults.standard.object(forKey: SirenUserDefaults.StoredSkippedVersion.rawValue) as? String else {
showAlert()
return
}
if let currentAppStoreVersion = currentAppStoreVersion, currentAppStoreVersion != previouslySkippedVersion {
showAlert()
}
}
func showAlert() {
let updateAvailableMessage = Bundle().localizedString(stringKey: "Update Available", forceLanguageLocalization: forceLanguageLocalization)
let newVersionMessage = localizedNewVersionMessage()
let alertController = UIAlertController(title: updateAvailableMessage, message: newVersionMessage, preferredStyle: .alert)
if let alertControllerTintColor = alertControllerTintColor {
alertController.view.tintColor = alertControllerTintColor
}
switch alertType {
case .force:
alertController.addAction(updateAlertAction())
case .option:
alertController.addAction(nextTimeAlertAction())
alertController.addAction(updateAlertAction())
case .skip:
alertController.addAction(nextTimeAlertAction())
alertController.addAction(updateAlertAction())
alertController.addAction(skipAlertAction())
case .none:
delegate?.sirenDidDetectNewVersionWithoutAlert(message: newVersionMessage)
}
if alertType != .none && !alertViewIsVisible {
alertController.show()
alertViewIsVisible = true
delegate?.sirenDidShowUpdateDialog(alertType: alertType)
}
}
func updateAlertAction() -> UIAlertAction {
let title = localizedUpdateButtonTitle()
let action = UIAlertAction(title: title, style: .default) { [unowned self] _ in
self.hideWindow()
self.launchAppStore()
self.delegate?.sirenUserDidLaunchAppStore()
self.alertViewIsVisible = false
return
}
return action
}
func nextTimeAlertAction() -> UIAlertAction {
let title = localizedNextTimeButtonTitle()
let action = UIAlertAction(title: title, style: .default) { [unowned self] _ in
self.hideWindow()
self.delegate?.sirenUserDidCancel()
self.alertViewIsVisible = false
return
}
return action
}
func skipAlertAction() -> UIAlertAction {
let title = localizedSkipButtonTitle()
let action = UIAlertAction(title: title, style: .default) { [unowned self] _ in
if let currentAppStoreVersion = self.currentAppStoreVersion {
UserDefaults.standard.set(currentAppStoreVersion, forKey: SirenUserDefaults.StoredSkippedVersion.rawValue)
UserDefaults.standard.synchronize()
}
self.hideWindow()
self.delegate?.sirenUserDidSkipVersion()
self.alertViewIsVisible = false
return
}
return action
}
func setAlertType() -> SirenAlertType {
guard let currentInstalledVersion = currentInstalledVersion,
let currentAppStoreVersion = currentAppStoreVersion else {
return .option
}
let oldVersion = (currentInstalledVersion).characters.split {$0 == "."}.map { String($0) }.map {Int($0) ?? 0}
let newVersion = (currentAppStoreVersion).characters.split {$0 == "."}.map { String($0) }.map {Int($0) ?? 0}
guard let newVersionFirst = newVersion.first, let oldVersionFirst = oldVersion.first else {
return alertType // Default value is .Option
}
if newVersionFirst > oldVersionFirst { // A.b.c.d
alertType = majorUpdateAlertType
} else if newVersion.count > 1 && (oldVersion.count <= 1 || newVersion[1] > oldVersion[1]) { // a.B.c.d
alertType = minorUpdateAlertType
} else if newVersion.count > 2 && (oldVersion.count <= 2 || newVersion[2] > oldVersion[2]) { // a.b.C.d
alertType = patchUpdateAlertType
} else if newVersion.count > 3 && (oldVersion.count <= 3 || newVersion[3] > oldVersion[3]) { // a.b.c.D
alertType = revisionUpdateAlertType
}
return alertType
}
}
// MARK: - Helpers (Localization)
private extension Siren {
func localizedNewVersionMessage() -> String {
let newVersionMessageToLocalize = "A new version of %@ is available. Please update to version %@ now."
let newVersionMessage = Bundle().localizedString(stringKey: newVersionMessageToLocalize, forceLanguageLocalization: forceLanguageLocalization)
guard let currentAppStoreVersion = currentAppStoreVersion else {
return String(format: newVersionMessage, appName, "Unknown")
}
return String(format: newVersionMessage, appName, currentAppStoreVersion)
}
func localizedUpdateButtonTitle() -> String {
return Bundle().localizedString(stringKey: "Update", forceLanguageLocalization: forceLanguageLocalization)
}
func localizedNextTimeButtonTitle() -> String {
return Bundle().localizedString(stringKey: "Next time", forceLanguageLocalization: forceLanguageLocalization)
}
func localizedSkipButtonTitle() -> String {
return Bundle().localizedString(stringKey: "Skip this version", forceLanguageLocalization: forceLanguageLocalization)
}
}
// MARK: - Helpers (Version)
private extension Siren {
func isAppStoreVersionNewer() -> Bool {
var newVersionExists = false
if let currentInstalledVersion = currentInstalledVersion,
let currentAppStoreVersion = currentAppStoreVersion,
(currentInstalledVersion.compare(currentAppStoreVersion, options: .numeric) == .orderedAscending) {
newVersionExists = true
}
return newVersionExists
}
func storeVersionCheckDate() {
lastVersionCheckPerformedOnDate = Date()
if let lastVersionCheckPerformedOnDate = lastVersionCheckPerformedOnDate {
UserDefaults.standard.set(lastVersionCheckPerformedOnDate, forKey: SirenUserDefaults.StoredVersionCheckDate.rawValue)
UserDefaults.standard.synchronize()
}
}
}
// MARK: - Helpers (Date)
private extension Siren {
static func setupDateFormatter() -> DateFormatter {
let dateformatter = DateFormatter()
dateformatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
return dateformatter
}
func days(since date: Date) -> Int {
let calendar = Calendar.current
let components = calendar.dateComponents([.day], from: date, to: Date())
return components.day!
}
func days(since dateString: String) -> Int? {
let dateformatter = Siren.setupDateFormatter()
guard let releaseDate = dateformatter.date(from: dateString) else { return nil }
return days(since: releaseDate)
}
}
// MARK: - Helpers (Misc.)
private extension Siren {
func isUpdateCompatibleWithDeviceOS(appData: [String: Any]) -> Bool {
guard let results = appData["results"] as? [[String: Any]],
let requiredOSVersion = results.first?["minimumOsVersion"] as? String else {
postError(.appStoreOSVersionNumberFailure, underlyingError: nil)
return false
}
let systemVersion = UIDevice.current.systemVersion
if systemVersion.compare(requiredOSVersion, options: .numeric) == .orderedDescending ||
systemVersion.compare(requiredOSVersion, options: .numeric) == .orderedSame {
return true
} else {
postError(.appStoreOSVersionUnsupported, underlyingError: nil)
return false
}
}
func hideWindow() {
if let updaterWindow = updaterWindow {
updaterWindow.isHidden = true
self.updaterWindow = nil
}
}
func launchAppStore() {
guard let appID = appID else {
return
}
let iTunesString = "https://itunes.apple.com/app/id\(appID)"
let iTunesURL = URL(string: iTunesString)
DispatchQueue.main.async {
UIApplication.shared.openURL(iTunesURL!)
}
}
func printMessage(message: String) {
if debugEnabled {
print("[Siren] \(message)")
}
}
}
// MARK: - UIAlertController Extension
private extension UIAlertController {
func show() {
let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = ViewController()
window.windowLevel = UIWindowLevelAlert + 1
Siren.shared.updaterWindow = window
window.makeKeyAndVisible()
window.rootViewController!.present(self, animated: true, completion: nil)
}
class ViewController: UIViewController {
override var preferredStatusBarStyle: UIStatusBarStyle { return UIApplication.shared.statusBarStyle }
}
}
// MARK: - Bundle Extension
private extension Bundle {
class func bundleID() -> String? {
return Bundle.main.bundleIdentifier
}
func sirenBundlePath() -> String {
return Bundle(for: Siren.self).path(forResource: "Siren", ofType: "bundle") as String!
}
func sirenForcedBundlePath(forceLanguageLocalization: SirenLanguageType) -> String {
let path = sirenBundlePath()
let name = forceLanguageLocalization.rawValue
return Bundle(path: path)!.path(forResource: name, ofType: "lproj")!
}
func localizedString(stringKey: String, forceLanguageLocalization: SirenLanguageType?) -> String {
var path: String
let table = "SirenLocalizable"
if let forceLanguageLocalization = forceLanguageLocalization {
path = sirenForcedBundlePath(forceLanguageLocalization: forceLanguageLocalization)
} else {
path = sirenBundlePath()
}
return Bundle(path: path)!.localizedString(forKey: stringKey, value: stringKey, table: table)
}
func bestMatchingAppName() -> String {
let bundleDisplayName = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String
let bundleName = Bundle.main.object(forInfoDictionaryKey: kCFBundleNameKey as String) as? String
return bundleDisplayName ?? bundleName ?? ""
}
}
// MARK: - Error Handling
private extension Siren {
func postError(_ code: SirenErrorCode, underlyingError: Error?) {
let description: String
switch code {
case .malformedURL:
description = "The iTunes URL is malformed. Please leave an issue on http://github.com/ArtSabintsev/Siren with as many details as possible."
case .recentlyCheckedAlready:
description = "Not checking the version, because it already checked recently."
case .noUpdateAvailable:
description = "No new update available."
case .appStoreDataRetrievalFailure:
description = "Error retrieving App Store data as an error was returned."
case .appStoreJSONParsingFailure:
description = "Error parsing App Store JSON data."
case .appStoreOSVersionNumberFailure:
description = "Error retrieving iOS version number as there was no data returned."
case .appStoreOSVersionUnsupported:
description = "The version of iOS on the device is lower than that of the one required by the app verison update."
case .appStoreVersionNumberFailure:
description = "Error retrieving App Store version number as there was no data returned."
case .appStoreVersionArrayFailure:
description = "Error retrieving App Store verson number as results.first does not contain a 'version' key."
case .appStoreAppIDFailure:
description = "Error retrieving trackId as results.first does not contain a 'trackId' key."
}
var userInfo: [String: Any] = [NSLocalizedDescriptionKey: description]
if let underlyingError = underlyingError {
userInfo[NSUnderlyingErrorKey] = underlyingError
}
let error = NSError(domain: SirenErrorDomain, code: code.rawValue, userInfo: userInfo)
delegate?.sirenDidFailVersionCheck(error: error)
printMessage(message: error.localizedDescription)
}
}
// MARK: - Helpers (Testing Target)
extension Siren {
func testSetCurrentInstalledVersion(version: String) {
currentInstalledVersion = version
}
func testSetAppStoreVersion(version: String) {
currentAppStoreVersion = version
}
func testIsAppStoreVersionNewer() -> Bool {
return isAppStoreVersionNewer()
}
}
extension Bundle {
func testLocalizedString(stringKey: String, forceLanguageLocalization: SirenLanguageType?) -> String {
return Bundle().localizedString(stringKey: stringKey, forceLanguageLocalization: forceLanguageLocalization)
}
}
-11
View File
@@ -1,11 +0,0 @@
platform :ios, '8.0'
use_frameworks!
inhibit_all_warnings!
target 'SirenExample' do
pod 'Siren', path: '../'
target 'SirenExampleTests' do
end
end
-16
View File
@@ -1,16 +0,0 @@
PODS:
- Siren (1.1.3)
DEPENDENCIES:
- Siren (from `../`)
EXTERNAL SOURCES:
Siren:
:path: "../"
SPEC CHECKSUMS:
Siren: dd12320dbe4976110ba828daab294e870b5795e2
PODFILE CHECKSUM: d1753e112639b625980f2d1b039eecd20315dedd
COCOAPODS: 1.2.0
-22
View File
@@ -1,22 +0,0 @@
{
"name": "Siren",
"version": "1.1.3",
"summary": "Notify users when a new version of your iOS app is available, and prompt them with the App Store link..",
"description": "Siren is checks a users currently installed version of your iOS app against the version that is currently available in the App Store. If a new version is available, an instance of UIAlertController can be presented to the user informing them of the newer version, and giving them the option to update the application. Alternatively, Siren can notify your app programmatically, enabling you to inform the user through alternative means, such as a custom interface.\n\nSiren is built to work with the Semantic Versioning system.\nSiren is a Swift port of Harpy, an Objective-C library that achieves the same functionality.\nSiren is actively maintained by Arthur Sabintsev and Aaron Brager.",
"homepage": "https://github.com/ArtSabintsev/Siren",
"license": "MIT",
"authors": {
"Arthur Ariel Sabintsev": "arthur@sabintsev.com",
"Aaron Brager": "getaaron@gmail.com"
},
"platforms": {
"ios": "8.0"
},
"source": {
"git": "https://github.com/ArtSabintsev/Siren.git",
"tag": "1.1.3"
},
"source_files": "Siren/Siren.swift",
"resources": "Siren/Siren.bundle",
"requires_arc": true
}
-16
View File
@@ -1,16 +0,0 @@
PODS:
- Siren (1.1.3)
DEPENDENCIES:
- Siren (from `../`)
EXTERNAL SOURCES:
Siren:
:path: "../"
SPEC CHECKSUMS:
Siren: dd12320dbe4976110ba828daab294e870b5795e2
PODFILE CHECKSUM: d1753e112639b625980f2d1b039eecd20315dedd
COCOAPODS: 1.2.0
-745
View File
@@ -1,745 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
0E7BA99DE523639BD20B30B0134572AB /* Siren.bundle in Resources */ = {isa = PBXBuildFile; fileRef = D0014954D53F1D742A31F698F34CA2FA /* Siren.bundle */; };
30588A9130FFD572AB8831B9C60A99C1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CBB3DE36805AF21409EC968A9691732F /* Foundation.framework */; };
3759EF897BA4CACEB7941777E3B7115C /* Siren-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 44110C84D89B6618B7D70B38C7E1F770 /* Siren-dummy.m */; };
53319B5B6A45DD5644478F5160676424 /* Pods-SirenExample-SirenExampleTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 811896840A2787CFB46C2310A53A61F8 /* Pods-SirenExample-SirenExampleTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
630DD393A56F48DC0D04F264FC5FC06C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CBB3DE36805AF21409EC968A9691732F /* Foundation.framework */; };
68363971D3CADD37023DB530882846B5 /* Pods-SirenExample-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 01F63F3FA74F496BD1757CC39A6CDE06 /* Pods-SirenExample-dummy.m */; };
972C2B7D49424E952ADED9CE497F6A90 /* Pods-SirenExample-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = CC12787058394FD29AE9BCA4E3D1727E /* Pods-SirenExample-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
9A89CCD81830867B82A5F24D08274F46 /* Siren-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 8F8E9DBD02CCFA3452DDBD132A0E8AE2 /* Siren-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
9D0ADFFB3FA43EC9D7957953C53B9F5D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CBB3DE36805AF21409EC968A9691732F /* Foundation.framework */; };
C243378AF1E6AA8C1F4A055F92AEAD90 /* Pods-SirenExample-SirenExampleTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A15F5047D149392B98A1D3FFB32E3A4 /* Pods-SirenExample-SirenExampleTests-dummy.m */; };
E9998E36AF890AF72E5742E5D35E37B1 /* Siren.swift in Sources */ = {isa = PBXBuildFile; fileRef = D717B436DF14DF1E0DCBD0AF437C09AB /* Siren.swift */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
07C4A910A6F4389EA84F3DD736F6BABC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
proxyType = 1;
remoteGlobalIDString = F377050F8D65BE603C2BA14DA95CC655;
remoteInfo = Siren;
};
6A86CB36CD46ACA47E8B6FB7C34292A7 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
proxyType = 1;
remoteGlobalIDString = F377050F8D65BE603C2BA14DA95CC655;
remoteInfo = Siren;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
01F63F3FA74F496BD1757CC39A6CDE06 /* Pods-SirenExample-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-SirenExample-dummy.m"; sourceTree = "<group>"; };
05EAEC8DBCD47FC65AA093945738F34C /* Siren-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Siren-prefix.pch"; sourceTree = "<group>"; };
06EB936D712088E22B6E97B31B296F82 /* Pods-SirenExample-SirenExampleTests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = "Pods-SirenExample-SirenExampleTests.modulemap"; sourceTree = "<group>"; };
0D0210F2E3B2C420D60816EA1F4B60A3 /* Pods-SirenExample-SirenExampleTests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SirenExample-SirenExampleTests-resources.sh"; sourceTree = "<group>"; };
0FC35D96177537EBA534D9CE3C60128E /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
227909DC6A327071DCF67332B557A68B /* Pods-SirenExample-SirenExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SirenExample-SirenExampleTests.debug.xcconfig"; sourceTree = "<group>"; };
29FA8FA37537DC30F4FF73E641B53852 /* Pods_SirenExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_SirenExample.framework; path = "Pods-SirenExample.framework"; sourceTree = BUILT_PRODUCTS_DIR; };
44110C84D89B6618B7D70B38C7E1F770 /* Siren-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Siren-dummy.m"; sourceTree = "<group>"; };
6940A5DB9FD30F6807D9DB98903784E6 /* Pods-SirenExample-SirenExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SirenExample-SirenExampleTests.release.xcconfig"; sourceTree = "<group>"; };
72B98520097CCDF5AB37CC050C681C62 /* Pods-SirenExample-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SirenExample-resources.sh"; sourceTree = "<group>"; };
7706AF9C75B4D2D5A1EF17FDAB9FAB97 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
808037DA7796F9F2C91DB46EFD4EBD2C /* Pods-SirenExample-SirenExampleTests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SirenExample-SirenExampleTests-frameworks.sh"; sourceTree = "<group>"; };
811896840A2787CFB46C2310A53A61F8 /* Pods-SirenExample-SirenExampleTests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-SirenExample-SirenExampleTests-umbrella.h"; sourceTree = "<group>"; };
84E88040F3DB6C8058D250199BEB0763 /* Pods-SirenExample.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = "Pods-SirenExample.modulemap"; sourceTree = "<group>"; };
8C2450C82854EDC40DA0834D0E79D9CC /* Siren.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Siren.framework; path = Siren.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8F8E9DBD02CCFA3452DDBD132A0E8AE2 /* Siren-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Siren-umbrella.h"; sourceTree = "<group>"; };
93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
93B3213D473E21275342FCE16C2C2918 /* Pods-SirenExample-SirenExampleTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-SirenExample-SirenExampleTests-acknowledgements.markdown"; sourceTree = "<group>"; };
96B8ECA9F086963CB8B616B2AC86BF19 /* Pods-SirenExample-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-SirenExample-acknowledgements.markdown"; sourceTree = "<group>"; };
9A15F5047D149392B98A1D3FFB32E3A4 /* Pods-SirenExample-SirenExampleTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-SirenExample-SirenExampleTests-dummy.m"; sourceTree = "<group>"; };
9D88CFEB6BB172591B08EBAA9BF1C081 /* Pods-SirenExample-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-SirenExample-acknowledgements.plist"; sourceTree = "<group>"; };
A33DC21230D06D0BB102A7F232AC0264 /* Pods-SirenExample-SirenExampleTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-SirenExample-SirenExampleTests-acknowledgements.plist"; sourceTree = "<group>"; };
AF1F066539B2AAC069B495BE2E1E0763 /* Pods-SirenExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SirenExample.debug.xcconfig"; sourceTree = "<group>"; };
B7F4561C5D552454DF92EB5241EC9A1E /* Pods-SirenExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SirenExample.release.xcconfig"; sourceTree = "<group>"; };
C63B0D8D086556F73F63E24D6AB5F1D8 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CBB3DE36805AF21409EC968A9691732F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
CC12787058394FD29AE9BCA4E3D1727E /* Pods-SirenExample-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-SirenExample-umbrella.h"; sourceTree = "<group>"; };
D0014954D53F1D742A31F698F34CA2FA /* Siren.bundle */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "wrapper.plug-in"; path = Siren.bundle; sourceTree = "<group>"; };
D701BD97BBDB45336E43D2B953E3070C /* Siren.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Siren.xcconfig; sourceTree = "<group>"; };
D717B436DF14DF1E0DCBD0AF437C09AB /* Siren.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Siren.swift; sourceTree = "<group>"; };
D7EB1862B7D8C3DAFE334DA8EE8C6945 /* Siren.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = Siren.modulemap; sourceTree = "<group>"; };
E6F743D475CC0841AD243851CE90F30D /* Pods_SirenExample_SirenExampleTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_SirenExample_SirenExampleTests.framework; path = "Pods-SirenExample-SirenExampleTests.framework"; sourceTree = BUILT_PRODUCTS_DIR; };
F54A454AD472895FB273B44F0F8A4485 /* Pods-SirenExample-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SirenExample-frameworks.sh"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
39DAC4CA1AF3DEBD5670F7B1C9D217AD /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
30588A9130FFD572AB8831B9C60A99C1 /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
558DEC84F818D4F9482BB60887732CC8 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9D0ADFFB3FA43EC9D7957953C53B9F5D /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
9CEDC49C4CDE8EBD117319BF12D5D844 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
630DD393A56F48DC0D04F264FC5FC06C /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
0AE78A7160A8E0FB0AA815851735C01C /* Support Files */ = {
isa = PBXGroup;
children = (
0FC35D96177537EBA534D9CE3C60128E /* Info.plist */,
D7EB1862B7D8C3DAFE334DA8EE8C6945 /* Siren.modulemap */,
D701BD97BBDB45336E43D2B953E3070C /* Siren.xcconfig */,
44110C84D89B6618B7D70B38C7E1F770 /* Siren-dummy.m */,
05EAEC8DBCD47FC65AA093945738F34C /* Siren-prefix.pch */,
8F8E9DBD02CCFA3452DDBD132A0E8AE2 /* Siren-umbrella.h */,
);
name = "Support Files";
path = "SirenExample/Pods/Target Support Files/Siren";
sourceTree = "<group>";
};
0D77725886F905A3134CE0F0F05994AC /* Pods-SirenExample-SirenExampleTests */ = {
isa = PBXGroup;
children = (
C63B0D8D086556F73F63E24D6AB5F1D8 /* Info.plist */,
06EB936D712088E22B6E97B31B296F82 /* Pods-SirenExample-SirenExampleTests.modulemap */,
93B3213D473E21275342FCE16C2C2918 /* Pods-SirenExample-SirenExampleTests-acknowledgements.markdown */,
A33DC21230D06D0BB102A7F232AC0264 /* Pods-SirenExample-SirenExampleTests-acknowledgements.plist */,
9A15F5047D149392B98A1D3FFB32E3A4 /* Pods-SirenExample-SirenExampleTests-dummy.m */,
808037DA7796F9F2C91DB46EFD4EBD2C /* Pods-SirenExample-SirenExampleTests-frameworks.sh */,
0D0210F2E3B2C420D60816EA1F4B60A3 /* Pods-SirenExample-SirenExampleTests-resources.sh */,
811896840A2787CFB46C2310A53A61F8 /* Pods-SirenExample-SirenExampleTests-umbrella.h */,
227909DC6A327071DCF67332B557A68B /* Pods-SirenExample-SirenExampleTests.debug.xcconfig */,
6940A5DB9FD30F6807D9DB98903784E6 /* Pods-SirenExample-SirenExampleTests.release.xcconfig */,
);
name = "Pods-SirenExample-SirenExampleTests";
path = "Target Support Files/Pods-SirenExample-SirenExampleTests";
sourceTree = "<group>";
};
2729F15752C52BBE3890E34FD0E8D2F3 /* Siren */ = {
isa = PBXGroup;
children = (
504E44BB61475170B4D4CCD0C911C74C /* Resources */,
CE606984792280F905C98BA85EEEEBF2 /* Siren */,
0AE78A7160A8E0FB0AA815851735C01C /* Support Files */,
);
name = Siren;
path = ../..;
sourceTree = "<group>";
};
40D2098AE3353F905BA5E2FB76EEC58C /* Targets Support Files */ = {
isa = PBXGroup;
children = (
E3F5580373AE923EA42F5CE1C043AE87 /* Pods-SirenExample */,
0D77725886F905A3134CE0F0F05994AC /* Pods-SirenExample-SirenExampleTests */,
);
name = "Targets Support Files";
sourceTree = "<group>";
};
504E44BB61475170B4D4CCD0C911C74C /* Resources */ = {
isa = PBXGroup;
children = (
FF15571CFCA5216313FAFB9024B7F768 /* Siren */,
);
name = Resources;
sourceTree = "<group>";
};
7531C8F8DE19F1AA3C8A7AC97A91DC29 /* iOS */ = {
isa = PBXGroup;
children = (
CBB3DE36805AF21409EC968A9691732F /* Foundation.framework */,
);
name = iOS;
sourceTree = "<group>";
};
768925493F6C39D21B7AC7DB7571D43F /* Development Pods */ = {
isa = PBXGroup;
children = (
2729F15752C52BBE3890E34FD0E8D2F3 /* Siren */,
);
name = "Development Pods";
sourceTree = "<group>";
};
7928ACCA4A5A970E7332BEF54649055C /* Products */ = {
isa = PBXGroup;
children = (
29FA8FA37537DC30F4FF73E641B53852 /* Pods_SirenExample.framework */,
E6F743D475CC0841AD243851CE90F30D /* Pods_SirenExample_SirenExampleTests.framework */,
8C2450C82854EDC40DA0834D0E79D9CC /* Siren.framework */,
);
name = Products;
sourceTree = "<group>";
};
7DB346D0F39D3F0E887471402A8071AB = {
isa = PBXGroup;
children = (
93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */,
768925493F6C39D21B7AC7DB7571D43F /* Development Pods */,
BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */,
7928ACCA4A5A970E7332BEF54649055C /* Products */,
40D2098AE3353F905BA5E2FB76EEC58C /* Targets Support Files */,
);
sourceTree = "<group>";
};
BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */ = {
isa = PBXGroup;
children = (
7531C8F8DE19F1AA3C8A7AC97A91DC29 /* iOS */,
);
name = Frameworks;
sourceTree = "<group>";
};
CE606984792280F905C98BA85EEEEBF2 /* Siren */ = {
isa = PBXGroup;
children = (
D717B436DF14DF1E0DCBD0AF437C09AB /* Siren.swift */,
);
name = Siren;
path = Siren;
sourceTree = "<group>";
};
E3F5580373AE923EA42F5CE1C043AE87 /* Pods-SirenExample */ = {
isa = PBXGroup;
children = (
7706AF9C75B4D2D5A1EF17FDAB9FAB97 /* Info.plist */,
84E88040F3DB6C8058D250199BEB0763 /* Pods-SirenExample.modulemap */,
96B8ECA9F086963CB8B616B2AC86BF19 /* Pods-SirenExample-acknowledgements.markdown */,
9D88CFEB6BB172591B08EBAA9BF1C081 /* Pods-SirenExample-acknowledgements.plist */,
01F63F3FA74F496BD1757CC39A6CDE06 /* Pods-SirenExample-dummy.m */,
F54A454AD472895FB273B44F0F8A4485 /* Pods-SirenExample-frameworks.sh */,
72B98520097CCDF5AB37CC050C681C62 /* Pods-SirenExample-resources.sh */,
CC12787058394FD29AE9BCA4E3D1727E /* Pods-SirenExample-umbrella.h */,
AF1F066539B2AAC069B495BE2E1E0763 /* Pods-SirenExample.debug.xcconfig */,
B7F4561C5D552454DF92EB5241EC9A1E /* Pods-SirenExample.release.xcconfig */,
);
name = "Pods-SirenExample";
path = "Target Support Files/Pods-SirenExample";
sourceTree = "<group>";
};
FF15571CFCA5216313FAFB9024B7F768 /* Siren */ = {
isa = PBXGroup;
children = (
D0014954D53F1D742A31F698F34CA2FA /* Siren.bundle */,
);
name = Siren;
path = Siren;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
00BD08CC6C6D9FB1307D9AD95AC89FBB /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
972C2B7D49424E952ADED9CE497F6A90 /* Pods-SirenExample-umbrella.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
742C9A2DCFA45E5FC55356EFAEADBFE4 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
53319B5B6A45DD5644478F5160676424 /* Pods-SirenExample-SirenExampleTests-umbrella.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
CC3789A31F2C448EBFAF19AC9C5073CD /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
9A89CCD81830867B82A5F24D08274F46 /* Siren-umbrella.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
1FFFC6665702A536DA8B71D457111929 /* Pods-SirenExample */ = {
isa = PBXNativeTarget;
buildConfigurationList = 6D516D5B2CB2C0CE924AC888F4B408B8 /* Build configuration list for PBXNativeTarget "Pods-SirenExample" */;
buildPhases = (
E4168386B9EA06817797B7B0040D75FC /* Sources */,
9CEDC49C4CDE8EBD117319BF12D5D844 /* Frameworks */,
00BD08CC6C6D9FB1307D9AD95AC89FBB /* Headers */,
);
buildRules = (
);
dependencies = (
974A2F6E5516D44C4E6F9D703E58A754 /* PBXTargetDependency */,
);
name = "Pods-SirenExample";
productName = "Pods-SirenExample";
productReference = 29FA8FA37537DC30F4FF73E641B53852 /* Pods_SirenExample.framework */;
productType = "com.apple.product-type.framework";
};
3BC8BA787C45E7AEF4B28C74EC112CED /* Pods-SirenExample-SirenExampleTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 8B57CB2B73D806C7091596E89616B79A /* Build configuration list for PBXNativeTarget "Pods-SirenExample-SirenExampleTests" */;
buildPhases = (
E6F1882A74A86779DC6AA6465E67C39F /* Sources */,
39DAC4CA1AF3DEBD5670F7B1C9D217AD /* Frameworks */,
742C9A2DCFA45E5FC55356EFAEADBFE4 /* Headers */,
);
buildRules = (
);
dependencies = (
B0B0AF4DD52E604CCA76915E505F6B5A /* PBXTargetDependency */,
);
name = "Pods-SirenExample-SirenExampleTests";
productName = "Pods-SirenExample-SirenExampleTests";
productReference = E6F743D475CC0841AD243851CE90F30D /* Pods_SirenExample_SirenExampleTests.framework */;
productType = "com.apple.product-type.framework";
};
F377050F8D65BE603C2BA14DA95CC655 /* Siren */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1EB440CE5696E51689BCA479ADEC2AB7 /* Build configuration list for PBXNativeTarget "Siren" */;
buildPhases = (
C932072B5B65FAD8D7636FC06279876D /* Sources */,
558DEC84F818D4F9482BB60887732CC8 /* Frameworks */,
015FED238AEBE98A1D97D0C38CBFEFD4 /* Resources */,
CC3789A31F2C448EBFAF19AC9C5073CD /* Headers */,
);
buildRules = (
);
dependencies = (
);
name = Siren;
productName = Siren;
productReference = 8C2450C82854EDC40DA0834D0E79D9CC /* Siren.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
D41D8CD98F00B204E9800998ECF8427E /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0730;
LastUpgradeCheck = 0700;
};
buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 7DB346D0F39D3F0E887471402A8071AB;
productRefGroup = 7928ACCA4A5A970E7332BEF54649055C /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
1FFFC6665702A536DA8B71D457111929 /* Pods-SirenExample */,
3BC8BA787C45E7AEF4B28C74EC112CED /* Pods-SirenExample-SirenExampleTests */,
F377050F8D65BE603C2BA14DA95CC655 /* Siren */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
015FED238AEBE98A1D97D0C38CBFEFD4 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0E7BA99DE523639BD20B30B0134572AB /* Siren.bundle in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
C932072B5B65FAD8D7636FC06279876D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3759EF897BA4CACEB7941777E3B7115C /* Siren-dummy.m in Sources */,
E9998E36AF890AF72E5742E5D35E37B1 /* Siren.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
E4168386B9EA06817797B7B0040D75FC /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
68363971D3CADD37023DB530882846B5 /* Pods-SirenExample-dummy.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
E6F1882A74A86779DC6AA6465E67C39F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C243378AF1E6AA8C1F4A055F92AEAD90 /* Pods-SirenExample-SirenExampleTests-dummy.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
974A2F6E5516D44C4E6F9D703E58A754 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = Siren;
target = F377050F8D65BE603C2BA14DA95CC655 /* Siren */;
targetProxy = 07C4A910A6F4389EA84F3DD736F6BABC /* PBXContainerItemProxy */;
};
B0B0AF4DD52E604CCA76915E505F6B5A /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = Siren;
target = F377050F8D65BE603C2BA14DA95CC655 /* Siren */;
targetProxy = 6A86CB36CD46ACA47E8B6FB7C34292A7 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
015A368F878AC3E2CEAE21DDE8026304 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGNING_REQUIRED = NO;
COPY_PHASE_STRIP = NO;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"POD_CONFIGURATION_DEBUG=1",
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
ONLY_ACTIVE_ARCH = YES;
PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/;
STRIP_INSTALLED_PRODUCT = NO;
SYMROOT = "${SRCROOT}/../build";
};
name = Debug;
};
2EEE68A74396488FD57C730C0DBA7A52 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = AF1F066539B2AAC069B495BE2E1E0763 /* Pods-SirenExample.debug.xcconfig */;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = "Target Support Files/Pods-SirenExample/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
MODULEMAP_FILE = "Target Support Files/Pods-SirenExample/Pods-SirenExample.modulemap";
MTL_ENABLE_DEBUG_INFO = YES;
OTHER_LDFLAGS = "";
OTHER_LIBTOOLFLAGS = "";
PODS_ROOT = "$(SRCROOT)";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = Pods_SirenExample;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
42A50A383A8E8850974C2E8D234CFBE6 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 227909DC6A327071DCF67332B557A68B /* Pods-SirenExample-SirenExampleTests.debug.xcconfig */;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = "Target Support Files/Pods-SirenExample-SirenExampleTests/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
MODULEMAP_FILE = "Target Support Files/Pods-SirenExample-SirenExampleTests/Pods-SirenExample-SirenExampleTests.modulemap";
MTL_ENABLE_DEBUG_INFO = YES;
OTHER_LDFLAGS = "";
OTHER_LIBTOOLFLAGS = "";
PODS_ROOT = "$(SRCROOT)";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = Pods_SirenExample_SirenExampleTests;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
44CDBB6D11DE06DB64D6268622BDC47E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGNING_REQUIRED = NO;
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_PREPROCESSOR_DEFINITIONS = (
"POD_CONFIGURATION_RELEASE=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/;
STRIP_INSTALLED_PRODUCT = NO;
SYMROOT = "${SRCROOT}/../build";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
4E806380BB7D1FF45C6A92D165FE4278 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = B7F4561C5D552454DF92EB5241EC9A1E /* Pods-SirenExample.release.xcconfig */;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = "Target Support Files/Pods-SirenExample/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
MODULEMAP_FILE = "Target Support Files/Pods-SirenExample/Pods-SirenExample.modulemap";
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_LDFLAGS = "";
OTHER_LIBTOOLFLAGS = "";
PODS_ROOT = "$(SRCROOT)";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = Pods_SirenExample;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
540F4677321802316973717ADEBCF5FE /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = D701BD97BBDB45336E43D2B953E3070C /* Siren.xcconfig */;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREFIX_HEADER = "Target Support Files/Siren/Siren-prefix.pch";
INFOPLIST_FILE = "Target Support Files/Siren/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MODULEMAP_FILE = "Target Support Files/Siren/Siren.modulemap";
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_NAME = Siren;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
DAA6945BB69713DE6FADCB8E8B45897A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 6940A5DB9FD30F6807D9DB98903784E6 /* Pods-SirenExample-SirenExampleTests.release.xcconfig */;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = "Target Support Files/Pods-SirenExample-SirenExampleTests/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
MODULEMAP_FILE = "Target Support Files/Pods-SirenExample-SirenExampleTests/Pods-SirenExample-SirenExampleTests.modulemap";
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_LDFLAGS = "";
OTHER_LIBTOOLFLAGS = "";
PODS_ROOT = "$(SRCROOT)";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = Pods_SirenExample_SirenExampleTests;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
FA836D6905D6CDBEDD835412E0AED44C /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = D701BD97BBDB45336E43D2B953E3070C /* Siren.xcconfig */;
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREFIX_HEADER = "Target Support Files/Siren/Siren-prefix.pch";
INFOPLIST_FILE = "Target Support Files/Siren/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MODULEMAP_FILE = "Target Support Files/Siren/Siren.modulemap";
MTL_ENABLE_DEBUG_INFO = YES;
PRODUCT_NAME = Siren;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1EB440CE5696E51689BCA479ADEC2AB7 /* Build configuration list for PBXNativeTarget "Siren" */ = {
isa = XCConfigurationList;
buildConfigurations = (
FA836D6905D6CDBEDD835412E0AED44C /* Debug */,
540F4677321802316973717ADEBCF5FE /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = {
isa = XCConfigurationList;
buildConfigurations = (
015A368F878AC3E2CEAE21DDE8026304 /* Debug */,
44CDBB6D11DE06DB64D6268622BDC47E /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
6D516D5B2CB2C0CE924AC888F4B408B8 /* Build configuration list for PBXNativeTarget "Pods-SirenExample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2EEE68A74396488FD57C730C0DBA7A52 /* Debug */,
4E806380BB7D1FF45C6A92D165FE4278 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
8B57CB2B73D806C7091596E89616B79A /* Build configuration list for PBXNativeTarget "Pods-SirenExample-SirenExampleTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
42A50A383A8E8850974C2E8D234CFBE6 /* Debug */,
DAA6945BB69713DE6FADCB8E8B45897A /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
}
@@ -1,5 +0,0 @@
#import <Foundation/Foundation.h>
@interface PodsDummy_Pods_SirenExample_SirenExampleTests : NSObject
@end
@implementation PodsDummy_Pods_SirenExample_SirenExampleTests
@end
@@ -1,99 +0,0 @@
#!/bin/sh
set -e
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
install_framework()
{
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
local source="${BUILT_PRODUCTS_DIR}/$1"
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
elif [ -r "$1" ]; then
local source="$1"
fi
local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [ -L "${source}" ]; then
echo "Symlinked..."
source="$(readlink "${source}")"
fi
# use filter instead of exclude so missing patterns dont' throw errors
echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
local basename
basename="$(basename -s .framework "$1")"
binary="${destination}/${basename}.framework/${basename}"
if ! [ -r "$binary" ]; then
binary="${destination}/${basename}"
fi
# Strip invalid architectures so "fat" simulator / device frameworks work on device
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
strip_invalid_archs "$binary"
fi
# Resign the code if required by the build settings to avoid unstable apps
code_sign_if_enabled "${destination}/$(basename "$1")"
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
local swift_runtime_libs
swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]})
for lib in $swift_runtime_libs; do
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
code_sign_if_enabled "${destination}/${lib}"
done
fi
}
# Signs a framework with the provided identity
code_sign_if_enabled() {
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
# Use the current code_sign_identitiy
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'"
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
code_sign_cmd="$code_sign_cmd &"
fi
echo "$code_sign_cmd"
eval "$code_sign_cmd"
fi
}
# Strip invalid architectures
strip_invalid_archs() {
binary="$1"
# Get architectures for current file
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
stripped=""
for arch in $archs; do
if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
stripped="$stripped $arch"
fi
done
if [[ "$stripped" ]]; then
echo "Stripped $binary of architectures:$stripped"
fi
}
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "$BUILT_PRODUCTS_DIR/Siren/Siren.framework"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "$BUILT_PRODUCTS_DIR/Siren/Siren.framework"
fi
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
wait
fi
@@ -1,99 +0,0 @@
#!/bin/sh
set -e
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
> "$RESOURCES_TO_COPY"
XCASSET_FILES=()
case "${TARGETED_DEVICE_FAMILY}" in
1,2)
TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
;;
1)
TARGET_DEVICE_ARGS="--target-device iphone"
;;
2)
TARGET_DEVICE_ARGS="--target-device ipad"
;;
3)
TARGET_DEVICE_ARGS="--target-device tv"
;;
*)
TARGET_DEVICE_ARGS="--target-device mac"
;;
esac
install_resource()
{
if [[ "$1" = /* ]] ; then
RESOURCE_PATH="$1"
else
RESOURCE_PATH="${PODS_ROOT}/$1"
fi
if [[ ! -e "$RESOURCE_PATH" ]] ; then
cat << EOM
error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script.
EOM
exit 1
fi
case $RESOURCE_PATH in
*.storyboard)
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.xib)
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.framework)
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
;;
*.xcdatamodel)
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\""
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
;;
*.xcdatamodeld)
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\""
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
;;
*.xcmappingmodel)
echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\""
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
;;
*.xcassets)
ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH"
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
;;
*)
echo "$RESOURCE_PATH"
echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
;;
esac
}
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then
mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
fi
rm -f "$RESOURCES_TO_COPY"
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ]
then
# Find all other xcassets (this unfortunately includes those of path pods and other targets).
OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
while read line; do
if [[ $line != "${PODS_ROOT}*" ]]; then
XCASSET_FILES+=("$line")
fi
done <<<"$OTHER_XCASSETS"
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
fi
@@ -1,10 +0,0 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Siren"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Siren/Siren.framework/Headers"
OTHER_LDFLAGS = $(inherited) -framework "Siren"
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}/Pods
@@ -1,6 +0,0 @@
framework module Pods_SirenExample_SirenExampleTests {
umbrella header "Pods-SirenExample-SirenExampleTests-umbrella.h"
export *
module * { export * }
}
@@ -1,10 +0,0 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Siren"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Siren/Siren.framework/Headers"
OTHER_LDFLAGS = $(inherited) -framework "Siren"
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}/Pods
@@ -1,5 +0,0 @@
#import <Foundation/Foundation.h>
@interface PodsDummy_Pods_SirenExample : NSObject
@end
@implementation PodsDummy_Pods_SirenExample
@end
@@ -1,99 +0,0 @@
#!/bin/sh
set -e
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
install_framework()
{
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
local source="${BUILT_PRODUCTS_DIR}/$1"
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
elif [ -r "$1" ]; then
local source="$1"
fi
local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [ -L "${source}" ]; then
echo "Symlinked..."
source="$(readlink "${source}")"
fi
# use filter instead of exclude so missing patterns dont' throw errors
echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
local basename
basename="$(basename -s .framework "$1")"
binary="${destination}/${basename}.framework/${basename}"
if ! [ -r "$binary" ]; then
binary="${destination}/${basename}"
fi
# Strip invalid architectures so "fat" simulator / device frameworks work on device
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
strip_invalid_archs "$binary"
fi
# Resign the code if required by the build settings to avoid unstable apps
code_sign_if_enabled "${destination}/$(basename "$1")"
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
local swift_runtime_libs
swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]})
for lib in $swift_runtime_libs; do
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
code_sign_if_enabled "${destination}/${lib}"
done
fi
}
# Signs a framework with the provided identity
code_sign_if_enabled() {
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
# Use the current code_sign_identitiy
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'"
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
code_sign_cmd="$code_sign_cmd &"
fi
echo "$code_sign_cmd"
eval "$code_sign_cmd"
fi
}
# Strip invalid architectures
strip_invalid_archs() {
binary="$1"
# Get architectures for current file
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
stripped=""
for arch in $archs; do
if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
stripped="$stripped $arch"
fi
done
if [[ "$stripped" ]]; then
echo "Stripped $binary of architectures:$stripped"
fi
}
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "$BUILT_PRODUCTS_DIR/Siren/Siren.framework"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "$BUILT_PRODUCTS_DIR/Siren/Siren.framework"
fi
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
wait
fi
@@ -1,10 +0,0 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Siren"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Siren/Siren.framework/Headers"
OTHER_LDFLAGS = $(inherited) -framework "Siren"
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}/Pods
@@ -1,6 +0,0 @@
framework module Pods_SirenExample {
umbrella header "Pods-SirenExample-umbrella.h"
export *
module * { export * }
}
@@ -1,10 +0,0 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Siren"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Siren/Siren.framework/Headers"
OTHER_LDFLAGS = $(inherited) -framework "Siren"
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}/Pods
@@ -1,10 +0,0 @@
CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/Siren
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public"
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}/../..
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
-100
View File
@@ -1,100 +0,0 @@
//
// AppDelegate.swift
// Siren
//
// Created by Arthur Sabintsev on 1/3/15.
// Copyright (c) 2015 Sabintsev iOS Projects. All rights reserved.
//
import UIKit
import Siren
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
window?.makeKeyAndVisible()
setupSiren()
return true
}
func setupSiren() {
let siren = Siren.shared
// Optional
siren.delegate = self
// Optional
siren.debugEnabled = true
// Optional
siren.appName = "Test App Name"
// Optional - Defaults to .Option
// siren.alertType = .Option // or .Force, .Skip, .None
// Optional - Can set differentiated Alerts for Major, Minor, Patch, and Revision Updates (Must be called AFTER siren.alertType, if you are using siren.alertType)
siren.majorUpdateAlertType = .option
siren.minorUpdateAlertType = .option
siren.patchUpdateAlertType = .option
siren.revisionUpdateAlertType = .option
// Optional - Sets all messages to appear in Spanish. Siren supports many other languages, not just English and Russian.
// siren.forceLanguageLocalization = .Russian
// Optional - Set this variable if your app is not available in the U.S. App Store. List of codes: https://developer.apple.com/library/content/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Appendices/AppStoreTerritories.html
// siren.countryCode = ""
// Optional - Set this variable if you would only like to show an alert if your app has been available on the store for a few days. The number 5 is used as an example.
// siren.showAlertAfterCurrentVersionHasBeenReleasedForDays = 5
// Required
siren.checkVersion(checkType: .immediately)
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
Siren.shared.checkVersion(checkType: .immediately)
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
Siren.shared.checkVersion(checkType: .daily)
}
}
extension AppDelegate: SirenDelegate
{
func sirenDidShowUpdateDialog(alertType: SirenAlertType) {
print(#function, alertType)
}
func sirenUserDidCancel() {
print(#function)
}
func sirenUserDidSkipVersion() {
print(#function)
}
func sirenUserDidLaunchAppStore() {
print(#function)
}
func sirenDidFailVersionCheck(error: NSError) {
print(#function, error)
}
func sirenLatestVersionInstalled() {
print(#function, "Latest version of app is installed")
}
// This delegate method is only hit when alertType is initialized to .none
func sirenDidDetectNewVersionWithoutAlert(message: String) {
print(#function, "\(message)")
}
}
@@ -1,736 +0,0 @@
//
// SirenTests.swift
// SirenTests
//
// Created by Arthur Sabintsev on 6/7/16.
// Copyright © 2016 Sabintsev iOS Projects. All rights reserved.
//
import XCTest
@testable import Siren
class SirenTests: XCTestCase {
let siren = Siren.shared
}
// MARK: - Updates
extension SirenTests {
func testSingleDigitVersionUpdate() {
siren.testSetCurrentInstalledVersion(version: "1")
siren.testSetAppStoreVersion(version: "2")
XCTAssertTrue(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "2.0")
XCTAssertTrue(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "2.0.0")
XCTAssertTrue(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "2.0.0.0")
XCTAssertTrue(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "0")
XCTAssertFalse(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "0.9")
XCTAssertFalse(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "0.0.9")
XCTAssertFalse(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "0.0.0.9")
XCTAssertFalse(siren.testIsAppStoreVersionNewer())
}
func testDoubleDigitVersionUpdate() {
siren.testSetCurrentInstalledVersion(version: "1.0")
siren.testSetAppStoreVersion(version: "2")
XCTAssertTrue(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "2.0")
XCTAssertTrue(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "2.0.0")
XCTAssertTrue(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "2.0.0.0")
XCTAssertTrue(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "0")
XCTAssertFalse(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "0.9")
XCTAssertFalse(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "0.0.9")
XCTAssertFalse(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "0.0.0.9")
XCTAssertFalse(siren.testIsAppStoreVersionNewer())
}
func testTripleDigitVersionUpdate() {
siren.testSetCurrentInstalledVersion(version: "1.0.0")
siren.testSetAppStoreVersion(version: "2")
XCTAssertTrue(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "2.0")
XCTAssertTrue(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "2.0.0")
XCTAssertTrue(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "2.0.0.0")
XCTAssertTrue(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "0")
XCTAssertFalse(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "0.9")
XCTAssertFalse(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "0.0.9")
XCTAssertFalse(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "0.0.0.9")
XCTAssertFalse(siren.testIsAppStoreVersionNewer())
}
func testQuadrupleDigitVersionUpdate() {
siren.testSetCurrentInstalledVersion(version: "1.0.0")
siren.testSetAppStoreVersion(version: "2")
XCTAssertTrue(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "2.0")
XCTAssertTrue(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "2.0.0")
XCTAssertTrue(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "2.0.0.0")
XCTAssertTrue(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "0")
XCTAssertFalse(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "0.9")
XCTAssertFalse(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "0.0.9")
XCTAssertFalse(siren.testIsAppStoreVersionNewer())
siren.testSetAppStoreVersion(version: "0.0.0.9")
XCTAssertFalse(siren.testIsAppStoreVersionNewer())
}
}
// MARK: - Localization
extension SirenTests {
func testArabicLocalization() {
let language: SirenLanguageType = .Arabic
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "التجديد متوفر")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "المرة التالية")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "تخطى عن هذه النسخة")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "تجديد")
}
func testArmenianLocalization() {
let language: SirenLanguageType = .Armenian
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Թարմացումը հասանելի Է")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Հաջորդ անգամ")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Բաց թողնել այս տարբերակը")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Թարմացնել")
}
func testBasqueLocalization() {
let language: SirenLanguageType = .Basque
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Eguneratzea erabilgarri")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Hurrengo batean")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Bertsio honetatik jauzi egin")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Eguneratu")
}
func testChineseSimplifiedLocalization() {
let language: SirenLanguageType = .ChineseSimplified
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "更新可用")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "下一次")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "跳过此版本")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "更新")
}
func testChineseTraditionalLocalization() {
let language: SirenLanguageType = .ChineseTraditional
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "有更新可用")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "下次")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "跳過此版本")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "更新")
}
func testCroatianLocalization() {
let language: SirenLanguageType = .Croatian
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Nova ažuriranje je stigla")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Sljedeći put")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Preskoči ovu verziju")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Ažuriraj")
}
func testDanishLocalization() {
let language: SirenLanguageType = .Danish
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Tilgængelig opdatering")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Næste gang")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Spring denne version over")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Opdater")
}
func testDutchLocalization() {
let language: SirenLanguageType = .Dutch
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Update Beschikbaar")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Volgende keer")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Sla deze versie over")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Updaten")
}
func testEstonianLocalization() {
let language: SirenLanguageType = .Estonian
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Uuendus saadaval")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Järgmisel korral")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Jäta see version vahele")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Uuenda")
}
func testFinnishLocalization() {
let language: SirenLanguageType = .Finnish
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Päivitys saatavilla")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Ensi kerralla")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Jätä tämä versio väliin")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Päivitys")
}
func testFrenchLocalization() {
let language: SirenLanguageType = .French
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Mise à jour disponible")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "La prochaine fois")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Sauter cette version")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Mettre à jour")
}
func testGermanLocalization() {
let language: SirenLanguageType = .German
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Update erhältlich")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Später")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Diese Version überspringen")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Update")
}
func testGreekLocalization() {
let language: SirenLanguageType = .Greek
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Διαθέσιμη Ενημέρωση")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Άλλη φορά")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Αγνόησε αυτήν την έκδοση")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Αναβάθμιση")
}
func testHebrewLocalization() {
let language: SirenLanguageType = .Hebrew
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "עדכון זמין")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "בפעם הבאה")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "דלג על גרסה זו")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "עדכן")
}
func testHungarianLocalization() {
let language: SirenLanguageType = .Hungarian
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Új frissítés érhető el")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Később")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Ennél a verziónál ne figyelmeztessen")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Frissítés")
}
func testIndonesianLocalization() {
let language: SirenLanguageType = .Indonesian
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Pembaruan Tersedia")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Lain kali")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Lewati versi ini")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Perbarui")
}
func testItalianLocalization() {
let language: SirenLanguageType = .Italian
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Aggiornamento disponibile")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "La prossima volta")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Salta questa versione")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Aggiorna")
}
func testJapaneseLocalization() {
let language: SirenLanguageType = .Japanese
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "更新が利用可能")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "次回")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "このバージョンをスキップ")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "更新")
}
func testKoreanLocalization() {
let language: SirenLanguageType = .Korean
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "업데이트 가능")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "다음에")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "이 버전 건너뜀")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "업데이트")
}
func testLatvianLocalization() {
let language: SirenLanguageType = .Latvian
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Atjauninājums pieejams")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Nākamreiz")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Izlaist šo versiju")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Atjaunināt")
}
func testLithuanianLocalization() {
let language: SirenLanguageType = .Lithuanian
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Atnaujinimas")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Kitą kartą")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Praleisti šią versiją")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Atnaujinti")
}
func testMalayLocalization() {
let language: SirenLanguageType = .Malay
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Versi Terkini")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Lain kali")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Langkau versi ini")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Muat turun")
}
func testNorwegianLocalization() {
let language: SirenLanguageType = .Norwegian
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Oppdatering tilgjengelig")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Neste gang")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Hopp over denne versjonen")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Oppdater")
}
func testPolishLocalization() {
let language: SirenLanguageType = .Polish
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Aktualizacja dostępna")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Następnym razem")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Pomiń wersję")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Zaktualizuj")
}
func testPortugueseBrazilLocalization() {
let language: SirenLanguageType = .PortugueseBrazil
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Atualização disponível")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Próxima vez")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Ignorar esta versão")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Atualizar")
}
func testPortuguesePortugalLocalization() {
let language: SirenLanguageType = .PortuguesePortugal
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Nova actualização disponível")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Próxima vez")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Ignorar esta versão")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Actualizar")
}
func testRussianLocalization() {
let language: SirenLanguageType = .Russian
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Доступно обновление")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "В следующий раз")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Пропустить эту версию")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Обновить")
}
func testSerbianCyrillicLocalization() {
let language: SirenLanguageType = .SerbianCyrillic
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Ажурирање доступно")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Следећи пут")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Прескочи ову верзију")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Ажурирај")
}
func testSerbianLatinLocalization() {
let language: SirenLanguageType = .SerbianLatin
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Ažuriranje dostupno")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Sledeći put")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Preskoči ovu verziju")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Ažuriraj")
}
func testSlovenianLocalization() {
let language: SirenLanguageType = .Slovenian
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Posodobitev aplikacije")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Naslednjič")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Ne želim")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Namesti")
}
func testSpanishLocalization() {
let language: SirenLanguageType = .Spanish
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Actualización disponible")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "La próxima vez")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Saltar esta versión")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Actualizar")
}
func testSwedishLocalization() {
let language: SirenLanguageType = .Swedish
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Tillgänglig uppdatering")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Nästa gång")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Hoppa över den här versionen")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Uppdatera")
}
func testThaiLocalization() {
let language: SirenLanguageType = .Thai
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "มีการอัพเดท")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "ไว้คราวหน้า")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "ข้ามเวอร์ชั่นนี้")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "อัพเดท")
}
func testTurkishLocalization() {
let language: SirenLanguageType = .Turkish
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Güncelleme Mevcut")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Daha sonra")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Boşver")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Güncelle")
}
func testVietnameseLocalization() {
let language: SirenLanguageType = .Vietnamese
siren.forceLanguageLocalization = language
// Update Available
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update Available", forceLanguageLocalization: language), "Cập nhật mới")
// Next time
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Next time", forceLanguageLocalization: language), "Lần tới")
// Skip this version
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Skip this version", forceLanguageLocalization: language), "Bỏ qua phiên bản này")
// Update
XCTAssertEqual(Bundle().testLocalizedString(stringKey: "Update", forceLanguageLocalization: language), "Cập nhật")
}
}
+115
View File
@@ -0,0 +1,115 @@
//
// BundleExtension.swift
// Siren
//
// Created by Arthur Sabintsev on 3/17/17.
// Copyright © 2017 Sabintsev iOS Projects. All rights reserved.
//
import Foundation
// `Bundle` Extension for Siren.
extension Bundle {
/// Constants used in the `Bundle` extension.
struct Constants {
/// Constant for the `.bundle` file extension.
static let bundleExtension = "bundle"
/// Constant for `CFBundleDisplayName`.
static let displayName = "CFBundleDisplayName"
/// Constant for the default US English localization.
static let englishLocalization = "en"
/// Constant for the project file extension.
static let projectExtension = "lproj"
/// Constant for `CFBundleShortVersionString`.
static let shortVersionString = "CFBundleShortVersionString"
/// Constant for the localization table.
static let table = "SirenLocalizable"
}
/// Fetches the current version of the app.
///
/// - Returns: The current installed version of the app.
final class func version() -> String? {
return Bundle.main.object(forInfoDictionaryKey: Constants.shortVersionString) as? String
}
/// Returns the localized string for a given default string.
///
/// By default, the English language localization is used.
/// If the device's localization is set to another locale, that local's language is used if it's supported by Siren.
/// If `forcedLanguage` is set to `true`, the chosen language is shown for all devices, irrespective of their device's localization.
///
///
/// - Parameters:
/// - key: The default string used to search the localization table for a specific translation.
/// - forcedLanguage: Returns
/// - Returns: The localized string for a given key.
final class func localizedString(forKey key: String, andForceLocalization forcedLanguage: Localization.Language?) -> String {
guard var path = sirenBundlePath() else {
return key
}
if let deviceLangauge = deviceLanguage(),
let devicePath = sirenForcedBundlePath(forceLanguageLocalization: deviceLangauge) {
path = devicePath
}
if let forcedLanguage = forcedLanguage,
let forcedPath = sirenForcedBundlePath(forceLanguageLocalization: forcedLanguage) {
path = forcedPath
}
return Bundle(path: path)?.localizedString(forKey: key, value: key, table: Constants.table) ?? key
}
/// The appropriate name for the app to be displayed in the update alert.
///
/// Siren checks `CFBundleDisplayName` first. It then falls back to
/// to `kCFBundleNameKey` and ultimately to an empty string
/// if the aforementioned values are nil.
///
/// - Returns: The name of the app.
final class func bestMatchingAppName() -> String {
let bundleDisplayName = Bundle.main.object(forInfoDictionaryKey: Constants.displayName) as? String
let bundleName = Bundle.main.object(forInfoDictionaryKey: kCFBundleNameKey as String) as? String
return bundleDisplayName ?? bundleName ?? ""
}
}
private extension Bundle {
/// The path to Siren's localization `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`.
///
/// - Parameter forceLanguageLocalization: The language localization that should be searched for in Siren's localization `bundle`.
/// - Returns: The path to the forced language localization.
final class func sirenForcedBundlePath(forceLanguageLocalization: Localization.Language) -> String? {
guard let path = sirenBundlePath() else { return nil }
let name = forceLanguageLocalization.rawValue
return Bundle(path: path)?.path(forResource: name, ofType: Constants.projectExtension)
}
/// The user's preferred language based on their device's localization.
///
/// - Returns: The user's preferred language.
final class func deviceLanguage() -> Localization.Language? {
guard let preferredLocalization = Bundle.main.preferredLocalizations.first,
preferredLocalization != Constants.englishLocalization,
let preferredLanguage = Localization.Language(rawValue: preferredLocalization) else {
return nil
}
return preferredLanguage
}
}
+40
View File
@@ -0,0 +1,40 @@
//
// DateExtension.swift
// Siren
//
// Created by Arthur Sabintsev on 3/21/17.
// Copyright © 2017 Sabintsev iOS Projects. All rights reserved.
//
import Foundation
// `Date` Extension for Siren.
extension Date {
/// The amount of days passed from a specific source date.
///
/// - Parameter date: The source date.
/// - Returns: The amount of days passed since the source date.
static func days(since date: Date) -> Int {
let calendar = Calendar.current
let components = calendar.dateComponents([.day], from: date, to: Date())
return components.day ?? 0
}
/// The amount of days passed from a specific source date string.
///
/// - Parameters:
/// - dateString: The source date string.
/// - Returns: The amount of days passed since the source date.
static func days(since dateString: String) -> Int? {
let dateformatter = DateFormatter()
dateformatter.locale = Locale(identifier: "en_US_POSIX")
dateformatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
dateformatter.timeZone = TimeZone(secondsFromGMT: 0)
guard let date = dateformatter.date(from: dateString) else {
return nil
}
return days(since: date)
}
}
@@ -0,0 +1,28 @@
//
// UIAlertControllerExtension.swift
// Siren
//
// Created by Arthur Sabintsev on 3/17/17.
// Copyright © 2017 Sabintsev iOS Projects. All rights reserved.
//
import UIKit
// `UIAlertController` Extension for Siren.
extension UIAlertController {
/// Presents Siren's `UIAlertController` in a new `UIWindow`.
///
/// - Parameter window: The `UIWindow` that _should_ reference Siren's `UIAlertController`.
func show(window: UIWindow) {
guard !self.isBeingPresented else { return }
window.makeKeyAndVisible()
window.rootViewController?.present(self, animated: true, completion: nil)
}
/// Hides Siren's `UIAlertController` within a given window.
///
/// - Parameter window: The `UIWindow` that references Siren's `UIAlertController`.
func hide(window: UIWindow) {
window.isHidden = true
}
}
@@ -0,0 +1,43 @@
//
// UserDefaultsExtension.swift
// Siren
//
// Created by Arthur Sabintsev on 9/25/18.
// Copyright © 2018 Sabintsev iOS Projects. All rights reserved.
//
import Foundation
// `UserDefaults` Extension for Siren.
extension UserDefaults {
/// Siren-specific `UserDefaults` Keys
private enum SirenKeys: String {
/// Key that notifies Siren to perform a version check and present
/// the Siren alert the next time the user launches the app.
case PerformVersionCheckOnSubsequentLaunch
/// Key that stores the timestamp of the last version check.
case StoredVersionCheckDate
/// Key that stores the version that a user decided to skip.
case StoredSkippedVersion
}
/// Sets and Gets a `UserDefault` around storing a version that the user wants to skip updating.
static var storedSkippedVersion: String? {
get {
return standard.string(forKey: SirenKeys.StoredSkippedVersion.rawValue)
} set {
standard.set(newValue, forKey: SirenKeys.StoredSkippedVersion.rawValue)
}
}
/// Sets and Gets a `UserDefault` around the last time the user was presented a version update alert.
static var alertPresentationDate: Date? {
get {
return standard.object(forKey: SirenKeys.StoredVersionCheckDate.rawValue) as? Date
} set {
standard.set(newValue, forKey: SirenKeys.StoredVersionCheckDate.rawValue)
}
}
}
+141
View File
@@ -0,0 +1,141 @@
//
// APIManager.swift
// Siren
//
// Created by Arthur Sabintsev on 11/24/18.
// Copyright © 2018 Sabintsev iOS Projects. All rights reserved.
//
import Foundation
/// APIManager for Siren
public struct APIManager {
/// Constants used in the `APIManager`.
private struct Constants {
/// Constant for the `bundleId` parameter in the iTunes Lookup API request.
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 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`.
///
/// The version check is performed against the US App Store.
public static let `default` = APIManager()
}
extension APIManager {
/// 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.
///
/// - Parameter countryCode: The raw country code for the App Store in which the app is available.
public init(countryCode: String?) {
self.init(country: .init(code: countryCode))
}
/// Creates and performs a URLRequest against the iTunes Lookup API.
///
/// - 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)
let (data, response) = try await URLSession.shared.data(for: request)
return try processVersionCheckResults(withData: data, response: response)
} catch {
throw error
}
}
/// Parses and maps the the results from the iTunes Lookup API request.
///
/// - Parameters:
/// - data: The JSON data returned from the request.
/// - response: The response metadata returned from the request.
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 {
throw KnownError.appStoreDataRetrievalEmptyResults
}
return apiModel
} catch {
throw KnownError.appStoreJSONParsingFailure(underlyingError: error)
}
}
/// Creates the URL that points to the iTunes Lookup API.
///
/// - Returns: The iTunes Lookup API URL.
/// - Throws: An error if the URL cannot be created.
private func makeITunesURL() throws -> URL {
var components = URLComponents()
components.scheme = "https"
components.host = "itunes.apple.com"
components.path = "/lookup"
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
guard let url = components.url, !url.absoluteString.isEmpty else {
throw KnownError.malformedURL
}
return url
}
}
+252
View File
@@ -0,0 +1,252 @@
//
// PresentationManager.swift
// Siren
//
// Created by Arthur Sabintsev on 12/6/17.
// Copyright © 2017 Sabintsev iOS Projects. All rights reserved.
//
import UIKit
/// PresentationManager for Siren
public class PresentationManager {
/// Return results or errors obtained from performing a version check with Siren.
typealias CompletionHandler = (AlertAction, String?) -> Void
/// The localization data structure that will be used to construct localized strings for the update alert.
let localization: Localization
/// The tint color of the `UIAlertController` buttons.
let tintColor: UIColor?
/// The descriptive update message of the `UIAlertController`.
let alertMessage: String
/// The main message of the `UIAlertController`.
let alertTitle: String
/// The "Next time" button text of the `UIAlertController`.
let nextTimeButtonTitle: String
/// The "Skip this version" button text of the `UIAlertController`.
let skipButtonTitle: String
/// The "Update" button text of the `UIAlertController`.
let updateButtonTitle: String
/// The instance of the `UIAlertController` used to present the update alert.
var alertController: UIAlertController?
/// The `UIWindow` instance that presents the `SirenViewController`.
private lazy var updaterWindow = createWindow()
/// `PresentationManager`'s public initializer.
///
/// - 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.
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) {
self.alertTitle = alertTitle
self.alertMessage = alertMessage
self.localization = Localization(appName: appName, andForceLanguageLocalization: forceLanguage)
self.nextTimeButtonTitle = nextTimeButtonTitle
self.updateButtonTitle = updateButtonTitle
self.skipButtonTitle = skipButtonTitle
self.tintColor = tintColor
}
/// The default `PresentationManager`.
///
/// 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.
public static let `default` = PresentationManager()
}
// MARK: - Alert Lifecycle
extension PresentationManager {
/// Constructs the localized update alert `UIAlertController` object.
///
/// - Parameters:
/// - rules: The rules that are used to define the type of alert that should be presented.
/// - currentAppStoreVersion: The current version of the app in the App Store.
/// - handler: The completion handler that returns the an `AlertAction` depending on the type of action the end-user took.
func presentAlert(withRules rules: Rules,
forCurrentAppStoreVersion currentAppStoreVersion: String,
completion handler: CompletionHandler?) {
UserDefaults.alertPresentationDate = Date()
// Alert Title
let alertTitle: String
if self.alertTitle == AlertConstants.alertTitle {
alertTitle = localization.alertTitle()
} else {
alertTitle = self.alertTitle
}
// Alert Message
let alertMessage: String
if self.alertMessage == AlertConstants.alertMessage {
alertMessage = localization.alertMessage(forCurrentAppStoreVersion: currentAppStoreVersion)
} else {
alertMessage = self.alertMessage
}
alertController = UIAlertController(title: alertTitle,
message: alertMessage,
preferredStyle: .alert)
if let tintColor = tintColor {
alertController?.view.tintColor = tintColor
}
switch rules.alertType {
case .force:
alertController?.addAction(updateAlertAction(completion: handler))
case .option:
alertController?.addAction(nextTimeAlertAction(completion: handler))
alertController?.addAction(updateAlertAction(completion: handler))
case .skip:
alertController?.addAction(updateAlertAction(completion: handler))
alertController?.addAction(nextTimeAlertAction(completion: handler))
alertController?.addAction(skipAlertAction(forCurrentAppStoreVersion: currentAppStoreVersion, completion: handler))
case .none:
handler?(.unknown, nil)
}
// If the alertType is .none, an alert will not be presented.
// If the `updaterWindow` is not hidden, then an alert is already presented.
// The latter prevents `UIAlertController`'s from appearing on top of each other.
if rules.alertType != .none, let updaterWindow = updaterWindow, updaterWindow.isHidden {
alertController?.show(window: updaterWindow)
} else {
// This is a safety precaution to avoid multiple windows from presenting on top of each other.
cleanUp()
}
}
/// Removes the `alertController` from memory.
func cleanUp() {
guard let updaterWindow = updaterWindow else { return }
alertController?.hide(window: updaterWindow)
alertController?.dismiss(animated: true, completion: nil)
updaterWindow.resignKey()
}
}
// MARK: - Alert Actions
private extension PresentationManager {
/// The `UIAlertAction` that is executed when the `Update` option is selected.
///
/// - Parameters:
/// - handler: The completion handler that returns the `.update` option.
/// - Returns: The `Update` alert action.
func updateAlertAction(completion handler: CompletionHandler?) -> UIAlertAction {
let title: String
if updateButtonTitle == AlertConstants.updateButtonTitle {
title = localization.updateButtonTitle()
} else {
title = updateButtonTitle
}
let action = UIAlertAction(title: title, style: .default) { _ in
self.cleanUp()
handler?(.appStore, nil)
return
}
return action
}
/// The `UIAlertAction` that is executed when the `Next time` option is selected.
///
/// - Parameters:
/// - handler: The completion handler that returns the `.nextTime` option.
/// - Returns: The `Next time` alert action.
func nextTimeAlertAction(completion handler: CompletionHandler?) -> UIAlertAction {
let title: String
if nextTimeButtonTitle == AlertConstants.nextTimeButtonTitle {
title = localization.nextTimeButtonTitle()
} else {
title = nextTimeButtonTitle
}
let action = UIAlertAction(title: title, style: .default) { _ in
self.cleanUp()
handler?(.nextTime, nil)
return
}
return action
}
/// The `UIAlertAction` that is executed when the `Skip this version` option is selected.
///
/// - Parameters:
/// - currentAppStoreVersion: The current version of the app in the App Store.
/// - handler: The completion handler that returns the `.skip` option.
/// - Returns: The `Skip this version` alert action.
func skipAlertAction(forCurrentAppStoreVersion currentAppStoreVersion: String, completion handler: CompletionHandler?) -> UIAlertAction {
let title: String
if skipButtonTitle == AlertConstants.skipButtonTitle {
title = localization.skipButtonTitle()
} else {
title = skipButtonTitle
}
let action = UIAlertAction(title: title, style: .default) { _ in
self.cleanUp()
handler?(.skip, currentAppStoreVersion)
return
}
return action
}
}
// MARK: - Helpers
private extension PresentationManager {
private func createWindow() -> UIWindow? {
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, tvOS 13.0, *)
private func getFirstForegroundScene() -> UIWindowScene? {
let connectedScenes = UIApplication.shared.connectedScenes
if let windowActiveScene = connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
return windowActiveScene
} else if let windowInactiveScene = connectedScenes.first(where: { $0.activationState == .foregroundInactive }) as? UIWindowScene {
return windowInactiveScene
} else {
return nil
}
}
}
+126
View File
@@ -0,0 +1,126 @@
//
// RulesManager.swift
// Siren
//
// Created by Arthur Sabintsev on 12/1/18.
// Copyright © 2018 Sabintsev iOS Projects. All rights reserved.
//
import Foundation
/// RulesManager for Siren
public struct RulesManager {
/// The alert will only show up if the current version has already been released for X days.
///
/// This value defaults to 1 day (in `RulesManager`'s initializer) to avoid an issue where
/// Apple updates the JSON faster than the app binary propogates to the App Store.
let releasedForDays: Int
/// The `Rules` that should be used when the App Store version of the app signifies that it is a **major** version update (A.b.c.d).
var majorUpdateRules: Rules
/// The `Rules` that should be used when the App Store version of the app signifies that it is a **minor** version update (a.B.c.d).
var minorUpdateRules: Rules
/// The `Rules` that should be used when the App Store version of the app signifies that it is a **patch** version update (a.b.C.d).
var patchUpdateRules: Rules
/// The `Rules` that should be used when the App Store version of the app signifies that it is a **revision** version update (a.b.c.D).
var revisionUpdateRules: Rules
/// 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.
///
/// 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.
///
/// - Warning: Setting `releasedForDays` to _0 days_ causes the alert to appear right away, even if the binary isn't available.
/// If this value is set to _0 days_, and an `AlertType` of type `.force` is set, it will cause your app to infinitely send the
/// end-user to the App Store to download a version that's not there and lock them out of your application until the binary is
/// is available to be downloaded.
///
/// - 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
public init(majorUpdateRules: Rules = .default,
minorUpdateRules: Rules = .default,
patchUpdateRules: Rules = .default,
revisionUpdateRules: Rules = .default,
showAlertAfterCurrentVersionHasBeenReleasedForDays releasedForDays: Int = 1) {
self.majorUpdateRules = majorUpdateRules
self.minorUpdateRules = minorUpdateRules
self.patchUpdateRules = patchUpdateRules
self.revisionUpdateRules = revisionUpdateRules
self.releasedForDays = releasedForDays
}
/// 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.
///
/// 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.
///
/// - Warning: Setting `releasedForDays` to _0 days_ causes the alert to appear right away, even if the binary isn't available.
/// If this value is set to _0 days_, and an `AlertType` of type `.force` is set, it will cause your app to infinitely send the
/// end-user to the App Store to download a version that's not there and lock them out of your application until the binary is
/// is available to be downloaded.
///
/// - 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
public init(globalRules rules: Rules = .default,
showAlertAfterCurrentVersionHasBeenReleasedForDays releasedForDays: Int = 1) {
self.init(majorUpdateRules: rules,
minorUpdateRules: rules,
patchUpdateRules: rules,
revisionUpdateRules: rules,
showAlertAfterCurrentVersionHasBeenReleasedForDays: releasedForDays)
}
/// Returns the appropriate update rules based on the type of version that is returned from the API.
///
/// - Parameters: type: The type of app update.
/// - Throws: The `noUpdateAvailable` error since this is the only way a valie of `unknown` can occur.
/// - Returns: The appropriate rule based on the type of app update that is returned by the API.
func loadRulesForUpdateType(_ type: UpdateType) throws -> Rules {
switch type {
case .major: return majorUpdateRules
case .minor: return minorUpdateRules
case .patch: return patchUpdateRules
case .revision: return revisionUpdateRules
case .unknown: throw KnownError.noUpdateAvailable
}
}
/// The default `RulesManager`.
///
/// By default, the `Rules.default` rule is used for all update typs.
public static let `default` = RulesManager(globalRules: .default)
}
// MARK: - RulesManager-related Constants
extension RulesManager {
/// Informs Siren of the type of update that is available so that
/// the appropriate ruleset is used to present the update alert.
///
/// - 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.
public enum UpdateType: String {
/// Major release available: A.b.c.d
case major
/// Minor release available: a.B.c.d
case minor
/// Patch release available: a.b.C.d
case patch
/// Revision release available: a.b.c.D
case revision
/// No information available about the update.
case unknown
}
}
+53
View File
@@ -0,0 +1,53 @@
//
// APIModel.swift
// Siren
//
// Created by Arthur Sabintsev on 8/6/17.
// Copyright © 2017 Sabintsev iOS Projects. All rights reserved.
//
import Foundation
/// Model representing a selection of results from the iTunes Lookup API.
struct APIModel: Decodable {
/// Codable Coding Keys for the Top-Level iTunes Lookup API JSON response.
private enum CodingKeys: String, CodingKey {
/// The results JSON key.
case results
}
/// The array of results objects from the iTunes Lookup API.
let results: [Results]
/// The Results object from the the iTunes Lookup API.
struct Results: Decodable {
/// Codable Coding Keys for the Results array in the iTunes Lookup API JSON response.
private enum CodingKeys: String, CodingKey {
/// The appID JSON key.
case appID = "trackId"
/// The current version release date JSON key.
case currentVersionReleaseDate
/// The minimum device iOS version compatibility JSON key.
case minimumOSVersion = "minimumOsVersion"
/// The release notes JSON key.
case releaseNotes
/// The current App Store version JSON key.
case version
}
/// The app's App ID.
let appID: Int
/// The release date for the latest version of the app.
let currentVersionReleaseDate: String
/// The minimum version of iOS that the current version of the app requires.
let minimumOSVersion: String
/// The releases notes from the latest version of the app.
let releaseNotes: String?
/// The latest version of the app.
let version: String
}
}
+21
View File
@@ -0,0 +1,21 @@
//
// AlertAction.swift
// Siren
//
// Created by Arthur Sabintsev on 12/1/18.
// Copyright © 2018 Sabintsev iOS Projects. All rights reserved.
//
import Foundation
/// The `UIAlertController` button that was pressed upon being presented an update alert.
public enum AlertAction {
/// The user clicked on the `Update` option, which took them to the app's App Store page.
case appStore
/// The user clicked on the `Next Time` option, which dismissed the alert.
case nextTime
/// The user clicked on the `Skip this version` option, which dismissed the alert.
case skip
/// (Default) The user never chose an option. This is returned when an error is thrown by Siren.
case unknown
}
+27
View File
@@ -0,0 +1,27 @@
//
// AlertConstants.swift
// Siren
//
// Created by Arthur Sabintsev on 12/18/18.
// Copyright © 2018 Sabintsev iOS Projects. All rights reserved.
//
import Foundation
/// The default constants used for the update alert's messaging.
public struct AlertConstants {
/// The text that conveys the message that there is an app update available
public static let alertMessage = "A new version of %@ is available. Please update to version %@ now."
/// The alert title which defaults to *Update Available*.
public static let alertTitle = "Update Available"
/// The button text that conveys the message that the user should be prompted to update next time the app launches.
public static let nextTimeButtonTitle = "Next time"
/// The text that conveys the message that the the user wants to skip this version update.
public static let skipButtonTitle = "Skip this version"
/// The button text that conveys the message that the user would like to update the app right away.
public static let updateButtonTitle = "Update"
}
+213
View File
@@ -0,0 +1,213 @@
//
// AppStoreCountry.swift
// Siren
//
// Created by Harlan Kellaway on 11/9/20.
// Copyright © 2020 Sabintsev iOS Projects. All rights reserved.
//
import Foundation
/// Region or country of an App Store in which an app can be available.
///
/// [List of country codes](https://help.apple.com/app-store-connect/#/dev997f9cf7c)
public struct AppStoreCountry {
/// Raw country code. ex. "US" for United States.
public let code: String?
}
extension AppStoreCountry {
public static let afghanistan: AppStoreCountry = "AFG"
public static let unitedArabEmirates: AppStoreCountry = "AE"
public static let antiguaAndBarbuda: AppStoreCountry = "AG"
public static let anguilla: AppStoreCountry = "AI"
public static let albania: AppStoreCountry = "AL"
public static let armenia: AppStoreCountry = "AM"
public static let angola: AppStoreCountry = "AO"
public static let argentina: AppStoreCountry = "AR"
public static let austria: AppStoreCountry = "AT"
public static let australia: AppStoreCountry = "AU"
public static let azerbaijan: AppStoreCountry = "AZ"
public static let barbados: AppStoreCountry = "BB"
public static let belgium: AppStoreCountry = "BE"
public static let bosniaAndHerzegovina: AppStoreCountry = "BIH"
public static let burkinaFaso: AppStoreCountry = "BF"
public static let bulgaria: AppStoreCountry = "BG"
public static let bahrain: AppStoreCountry = "BH"
public static let benin: AppStoreCountry = "BJ"
public static let bermuda: AppStoreCountry = "BM"
public static let brunei: AppStoreCountry = "BN"
public static let bolivia: AppStoreCountry = "BO"
public static let brazil: AppStoreCountry = "BR"
public static let bahamas: AppStoreCountry = "BS"
public static let bhutan: AppStoreCountry = "BT"
public static let botswana: AppStoreCountry = "BW"
public static let belarus: AppStoreCountry = "BY"
public static let belize: AppStoreCountry = "BZ"
public static let cameroon: AppStoreCountry = "CMR"
public static let canada: AppStoreCountry = "CA"
public static let congoRepublic: AppStoreCountry = "CG"
public static let switzerland: AppStoreCountry = "CH"
public static let coteDIvoire: AppStoreCountry = "CIV"
public static let chile: AppStoreCountry = "CL"
public static let china: AppStoreCountry = "CN"
public static let colombia: AppStoreCountry = "CO"
public static let congoDemocraticRepublic: AppStoreCountry = "COD"
public static let costaRica: AppStoreCountry = "CR"
public static let capeVerde: AppStoreCountry = "CV"
public static let cyprus: AppStoreCountry = "CY"
public static let czechRepublic: AppStoreCountry = "CZ"
public static let germany: AppStoreCountry = "DE"
public static let denmark: AppStoreCountry = "DK"
public static let dominica: AppStoreCountry = "DM"
public static let dominicanRepublic: AppStoreCountry = "DO"
public static let algeria: AppStoreCountry = "DZ"
public static let ecuador: AppStoreCountry = "EC"
public static let estonia: AppStoreCountry = "EE"
public static let egypt: AppStoreCountry = "EG"
public static let spain: AppStoreCountry = "ES"
public static let finland: AppStoreCountry = "FI"
public static let fiji: AppStoreCountry = "FJ"
public static let micronesia: AppStoreCountry = "FM"
public static let france: AppStoreCountry = "FR"
public static let gabon: AppStoreCountry = "GAB"
public static let unitedKingdom: AppStoreCountry = "GB"
public static let grenada: AppStoreCountry = "GD"
public static let georgia: AppStoreCountry = "GEO"
public static let ghana: AppStoreCountry = "GH"
public static let gambia: AppStoreCountry = "GM"
public static let greece: AppStoreCountry = "GR"
public static let guatemala: AppStoreCountry = "GT"
public static let guineaBissau: AppStoreCountry = "GW"
public static let guyana: AppStoreCountry = "GY"
public static let hongKong: AppStoreCountry = "HK"
public static let honduras: AppStoreCountry = "HN"
public static let croatia: AppStoreCountry = "HR"
public static let hungary: AppStoreCountry = "HU"
public static let indonesia: AppStoreCountry = "ID"
public static let ireland: AppStoreCountry = "IE"
public static let israel: AppStoreCountry = "IL"
public static let india: AppStoreCountry = "IN"
public static let iraq: AppStoreCountry = "IRQ"
public static let iceland: AppStoreCountry = "IS"
public static let italy: AppStoreCountry = "IT"
public static let jamaica: AppStoreCountry = "JM"
public static let jordan: AppStoreCountry = "JO"
public static let japan: AppStoreCountry = "JP"
public static let kenya: AppStoreCountry = "KE"
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"
public static let laos: AppStoreCountry = "LA"
public static let lebanon: AppStoreCountry = "LB"
public static let libya: AppStoreCountry = "LBY"
public static let stLucia: AppStoreCountry = "LC"
public static let sriLanka: AppStoreCountry = "LK"
public static let liberia: AppStoreCountry = "LR"
public static let lithuania: AppStoreCountry = "LT"
public static let luxembourg: AppStoreCountry = "LU"
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"
public static let myanmar: AppStoreCountry = "MMR"
public static let mongolia: AppStoreCountry = "MN"
public static let montenegro: AppStoreCountry = "MNE"
public static let macau: AppStoreCountry = "MO"
public static let mauritania: AppStoreCountry = "MR"
public static let montserrat: AppStoreCountry = "MS"
public static let malta: AppStoreCountry = "MT"
public static let mauritius: AppStoreCountry = "MU"
public static let malawi: AppStoreCountry = "MW"
public static let mexico: AppStoreCountry = "MX"
public static let malaysia: AppStoreCountry = "MY"
public static let mozambique: AppStoreCountry = "MZ"
public static let namibia: AppStoreCountry = "NA"
public static let niger: AppStoreCountry = "NE"
public static let nigeria: AppStoreCountry = "NG"
public static let nicaragua: AppStoreCountry = "NI"
public static let netherlands: AppStoreCountry = "NL"
public static let norway: AppStoreCountry = "NO"
public static let nepal: AppStoreCountry = "NP"
public static let nauru: AppStoreCountry = "NRU"
public static let newZealand: AppStoreCountry = "NZ"
public static let oman: AppStoreCountry = "OM"
public static let panama: AppStoreCountry = "PA"
public static let peru: AppStoreCountry = "PE"
public static let papuaNewGuinea: AppStoreCountry = "PG"
public static let philippines: AppStoreCountry = "PH"
public static let pakistan: AppStoreCountry = "PK"
public static let poland: AppStoreCountry = "PL"
public static let portugal: AppStoreCountry = "PT"
public static let palau: AppStoreCountry = "PW"
public static let paraguay: AppStoreCountry = "PY"
public static let qatar: AppStoreCountry = "QA"
public static let romania: AppStoreCountry = "RO"
public static let russia: AppStoreCountry = "RU"
public static let rwanda: AppStoreCountry = "RWA"
public static let saudiArabia: AppStoreCountry = "SA"
public static let solomonIslands: AppStoreCountry = "SB"
public static let seychelles: AppStoreCountry = "SC"
public static let sweden: AppStoreCountry = "SE"
public static let singapore: AppStoreCountry = "SG"
public static let slovenia: AppStoreCountry = "SI"
public static let slovakia: AppStoreCountry = "SK"
public static let sierraLeone: AppStoreCountry = "SL"
public static let senegal: AppStoreCountry = "SN"
public static let suriname: AppStoreCountry = "SR"
public static let serbia: AppStoreCountry = "SRB"
public static let saoTomeAndPrincipe: AppStoreCountry = "ST"
public static let elSalvador: AppStoreCountry = "SV"
public static let swaziland: AppStoreCountry = "SZ"
public static let turksAndCaicosIslands: AppStoreCountry = "TC"
public static let chad: AppStoreCountry = "TD"
public static let thailand: AppStoreCountry = "TH"
public static let tajikistan: AppStoreCountry = "TJ"
public static let turkmenistan: AppStoreCountry = "TM"
public static let tunisia: AppStoreCountry = "TN"
public static let tonga: AppStoreCountry = "TON"
public static let turkey: AppStoreCountry = "TR"
public static let trinidadAndTobago: AppStoreCountry = "TT"
public static let taiwan: AppStoreCountry = "TW"
public static let tanzania: AppStoreCountry = "TZ"
public static let ukraine: AppStoreCountry = "UA"
public static let uganda: AppStoreCountry = "UG"
public static let unitedStates: AppStoreCountry = "US"
public static let uruguay: AppStoreCountry = "UY"
public static let uzbekistan: AppStoreCountry = "UZ"
public static let stVincentAndTheGrenadines: AppStoreCountry = "VC"
public static let venezuela: AppStoreCountry = "VE"
public static let britishVirginIslands: AppStoreCountry = "VG"
public static let vietnam: AppStoreCountry = "VN"
public static let vanuatu: AppStoreCountry = "VUT"
public static let kosovo: AppStoreCountry = "XKS"
public static let yemen: AppStoreCountry = "YE"
public static let southAfrica: AppStoreCountry = "ZA"
public static let zambia: AppStoreCountry = "ZMB"
public static let zimbabwe: AppStoreCountry = "ZW"
}
extension AppStoreCountry: Equatable { }
/// Adds ability to equate instances of `AppStoreCountry` to each other.
/// - Parameters:
/// - lhs: First instance of`AppStoreCountry`
/// - rhs: Second instance of`AppStoreCountry`
/// - Returns: `true` if instances are equal. Otherwise, `false`.
public func == (lhs: AppStoreCountry, rhs: AppStoreCountry) -> Bool {
return lhs.code?.uppercased() == rhs.code?.uppercased()
}
extension AppStoreCountry: ExpressibleByStringLiteral {
/// Allows for `AppStoreCountry` to be initialized by a string literal.
/// - Parameter value: An instance of `AppStoreCountry` that can be represented as a `String`.
public init(stringLiteral value: StringLiteralType) {
self.init(code: value)
}
}

Some files were not shown because too many files have changed in this diff Show More