Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: Iterable/iterable-swift-sdk
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 6.3.3
Choose a base ref
...
head repository: Iterable/iterable-swift-sdk
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Loading
Showing with 17,353 additions and 5,574 deletions.
  1. +6 −0 .editorconfig
  2. +103 −16 .github/workflows/build-and-test.yml
  3. +18 −16 .github/workflows/e2e.yml
  4. +62 −0 .github/workflows/ios-sdk-release.yml
  5. +109 −0 .github/workflows/prepare-for-release.yml
  6. +10 −0 .gitignore
  7. +519 −69 CHANGELOG.md
  8. +7 −0 Gemfile
  9. +294 −0 Gemfile.lock
  10. +7 −6 Iterable-iOS-AppExtensions.podspec
  11. +8 −6 Iterable-iOS-SDK.podspec
  12. +13 −8 README.md
  13. +138 −0 fastlane/Fastfile
  14. +6 −0 fastlane/Pluginfile
  15. +22 −0 notification-extension/ITBNotificationServiceExtension.swift
  16. +99 −34 notification-extension/NotificationContentParser.swift
  17. +1 −0 notification-extension/NotificationExtensionConstants.swift
  18. +6 −6 sample-apps/objc-sample-app/objc-sample-app.xcodeproj/project.pbxproj
  19. +2 −2 sample-apps/objc-sample-app/objc-sample-app/AppDelegate.m
  20. +2 −1 sample-apps/objc-sample-app/objc-sample-app/CoffeeViewController.m
  21. +2 −2 sample-apps/objc-sample-app/objc-sample-app/objc-sample-app.entitlements
  22. +124 −8 sample-apps/swift-sample-app/swift-sample-app.xcodeproj/project.pbxproj
  23. +78 −0 ...t-sample-app/swift-sample-app.xcodeproj/xcshareddata/xcschemes/internal-swift-sample-app.xcscheme
  24. +1 −1 sample-apps/swift-sample-app/swift-sample-app/AppDelegate.swift
  25. +140 −20 sample-apps/swift-sample-app/swift-sample-app/Base.lproj/Main.storyboard
  26. +7 −0 sample-apps/swift-sample-app/swift-sample-app/CoffeeListTableViewController.swift
  27. +148 −0 sample-apps/swift-sample-app/swift-sample-app/EmbeddedMessages/EmbeddedMessagesViewController.swift
  28. +14 −0 sample-apps/swift-sample-app/swift-sample-app/EmbeddedMessages/IterableCardViewCell.swift
  29. +123 −0 sample-apps/swift-sample-app/swift-sample-app/EmbeddedMessages/embeddedmessages.json
  30. +2 −2 sample-apps/swift-sample-app/swift-sample-app/swift-sample-app.entitlements
  31. +8 −0 sample-apps/swiftui-sample-app/README.md
  32. +31 −0 sample-apps/swiftui-sample-app/notification-extension/Info.plist
  33. +5 −0 sample-apps/swiftui-sample-app/notification-extension/NotificationService.swift
  34. +562 −0 sample-apps/swiftui-sample-app/swiftui-sample-app.xcodeproj/project.pbxproj
  35. +7 −0 ...apps/swiftui-sample-app/swiftui-sample-app.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  36. +8 −0 ...sample-app/swiftui-sample-app.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  37. +26 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/AppModel.swift
  38. +116 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/Contents.json
  39. BIN ...ps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
  40. BIN ...ps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
  41. BIN ...ps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
  42. BIN ...ps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
  43. BIN ...ps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
  44. BIN ...ps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
  45. BIN ...ps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
  46. BIN .../swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x-1.png
  47. BIN ...e-apps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/Icon-App20x20.png
  48. BIN ...pps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/Icon-App20x20@2x.png
  49. BIN ...e-apps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/Icon-App29x29.png
  50. BIN ...pps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/Icon-App29x29@2x.png
  51. BIN ...e-apps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/Icon-App40x40.png
  52. BIN ...pps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/Icon-App40x40@2x.png
  53. BIN ...e-apps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/Icon-App76x76.png
  54. BIN ...pps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/Icon-App76x76@2x.png
  55. BIN ...apps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/Icon-App83.5@2x.png
  56. BIN ...pps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/AppIcon.appiconset/iTunesArtwork@2x.png
  57. +12 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/Black.imageset/Contents.json
  58. BIN sample-apps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/Black.imageset/th.jpeg
  59. +12 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/Cappuccino.imageset/Contents.json
  60. BIN sample-apps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/Cappuccino.imageset/th-1.jpeg
  61. +6 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/Contents.json
  62. +12 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/Latte.imageset/Contents.json
  63. BIN sample-apps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/Latte.imageset/Unknown-1.jpeg
  64. +12 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/Mocha.imageset/Contents.json
  65. BIN sample-apps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/Mocha.imageset/Unknown.jpeg
  66. +12 −0 ...le-apps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/iterableLogo.imageset/Contents.json
  67. BIN ...apps/swiftui-sample-app/swiftui-sample-app/Assets.xcassets/iterableLogo.imageset/iterableLogo.pdf
  68. +40 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/Coffee.swift
  69. +56 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/DeeplinkHandler.swift
  70. +54 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/Info.plist
  71. +75 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/IterableHelper.swift
  72. +46 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/MainApp.swift
  73. +45 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/Notifications.swift
  74. +6 −0 ...-apps/swiftui-sample-app/swiftui-sample-app/Preview Content/Preview Assets.xcassets/Contents.json
  75. +31 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/Views/CoffeeListView.swift
  76. +48 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/Views/CoffeeRow.swift
  77. +47 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/Views/CoffeeView.swift
  78. +70 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/Views/ContentView.swift
  79. +82 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/Views/LoginView.swift
  80. +10 −0 sample-apps/swiftui-sample-app/swiftui-sample-app/swiftui-sample-app.entitlements
  81. +1 −0 script.sh
  82. +12 −9 scripts/create-xcframework-zips.sh
  83. +1,100 −0 scripts/process_xcresult.py
  84. +1,096 −595 swift-sdk.xcodeproj/project.pbxproj
  85. +0 −16 swift-sdk.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
  86. +8 −11 swift-sdk.xcodeproj/xcshareddata/xcschemes/endpoint-tests.xcscheme
  87. +1 −1 swift-sdk.xcodeproj/xcshareddata/xcschemes/inbox-ui-tests-app.xcscheme
  88. +0 −157 swift-sdk.xcodeproj/xcshareddata/xcschemes/ios9-tests.xcscheme
  89. +1 −1 swift-sdk.xcodeproj/xcshareddata/xcschemes/swift-sdk-parallel.xcscheme
  90. +16 −4 swift-sdk.xcodeproj/xcshareddata/xcschemes/swift-sdk.xcscheme
  91. +1 −1 swift-sdk.xcodeproj/xcshareddata/xcschemes/ui-tests-app.xcscheme
  92. +64 −4 swift-sdk/{ → Core}/Constants.swift
  93. 0 swift-sdk/{ → Core/Models}/CommerceItem.swift
  94. 0 swift-sdk/{ → Core/Models}/IterableAction.swift
  95. 0 swift-sdk/{ → Core/Models}/IterableActionContext.swift
  96. 0 swift-sdk/{ → Core/Models}/IterableAttributionInfo.swift
  97. +74 −0 swift-sdk/Core/Models/IterableEmbeddedMessage.swift
  98. +6 −1 swift-sdk/{ → Core/Models}/IterableInAppMessage.swift
  99. 0 swift-sdk/{ → Core/Models}/IterablePushNotificationMetadata.swift
  100. +38 −0 swift-sdk/Core/Models/RetryPolicy.swift
  101. +18 −0 swift-sdk/Core/Protocols/IterableAuthManagerProtocol.swift
  102. +16 −0 swift-sdk/Core/Protocols/IterableEmbeddedManagerProtocol.swift
  103. +10 −0 swift-sdk/Core/Protocols/IterableEmbeddedUpdateDelegate.swift
  104. +27 −0 swift-sdk/{ → Core/Protocols}/IterableInAppManagerProtocol.swift
  105. 0 swift-sdk/{ → Core/Protocols}/IterableInboxViewControllerViewDelegate.swift
  106. +33 −0 swift-sdk/Core/Utilities/AuthFailure.swift
  107. +22 −0 swift-sdk/Core/Utilities/AuthFailureReason.swift
  108. +24 −4 swift-sdk/Internal/APNSTypeChecker.swift
  109. +14 −15 swift-sdk/Internal/{IterableActionRunner.swift → ActionRunner.swift}
  110. +0 −48 swift-sdk/Internal/ApiClientProtocol.swift
  111. +61 −0 swift-sdk/Internal/AppExtensionHelper.swift
  112. +121 −28 swift-sdk/Internal/AuthManager.swift
  113. +10 −0 swift-sdk/Internal/CoreDataUtil.swift
  114. +7 −1 swift-sdk/Internal/DataFieldsHelper.swift
  115. +119 −0 swift-sdk/Internal/DeepLinkManager.swift
  116. +82 −0 swift-sdk/Internal/EmbeddedHelper.swift
  117. +52 −0 swift-sdk/Internal/EmbeddedMessagingProcessor.swift
  118. +132 −0 swift-sdk/Internal/EmbeddedMessagingSerialization.swift
  119. +98 −0 swift-sdk/Internal/EmbeddedSessionManager.swift
  120. +47 −0 swift-sdk/Internal/EmptyEmbeddedManager.swift
  121. +18 −10 swift-sdk/Internal/EmptyInAppManager.swift
  122. +31 −9 swift-sdk/Internal/HealthMonitor.swift
  123. +18 −6 swift-sdk/Internal/InboxImpressionTracker.swift
  124. +25 −17 swift-sdk/Internal/InboxSessionManager.swift
  125. +92 −0 swift-sdk/Internal/InboxState.swift
  126. +146 −46 swift-sdk/Internal/InboxViewControllerViewModel.swift
  127. +4 −4 swift-sdk/Internal/InboxViewControllerViewModelProtocol.swift
  128. +301 −102 swift-sdk/Internal/InternalIterableAPI.swift
  129. +31 −61 swift-sdk/Internal/{IterableAppIntegrationInternal.swift → InternalIterableAppIntegration.swift}
  130. +7 −7 swift-sdk/Internal/IterableAPICallRequest.swift
  131. +2 −2 swift-sdk/Internal/IterableAPICallTaskProcessor.swift
  132. +81 −0 swift-sdk/Internal/IterableAPIMobileFrameworkDetector.swift
  133. +24 −14 swift-sdk/Internal/IterableCoreDataPersistence.swift
  134. +0 −150 swift-sdk/Internal/IterableDeepLinkManager.swift
  135. +252 −0 swift-sdk/Internal/IterableEmbeddedManager.swift
  136. +127 −34 swift-sdk/Internal/IterableHtmlMessageViewController.swift
  137. +2 −2 swift-sdk/Internal/IterableInboxCell+Layout.swift
  138. +2 −0 swift-sdk/Internal/IterablePersistence.swift
  139. +2 −2 swift-sdk/Internal/IterableTaskError.swift
  140. +1 −1 swift-sdk/Internal/IterableTaskProcessor.swift
  141. +138 −105 swift-sdk/Internal/IterableTaskRunner.swift
  142. +37 −30 swift-sdk/Internal/IterableTaskScheduler.swift
  143. +45 −35 swift-sdk/Internal/{UserDefaultsLocalStorage.swift → IterableUserDefaults.swift}
  144. +0 −278 swift-sdk/Internal/LegacyRequestHandler.swift
  145. +68 −0 swift-sdk/Internal/MiscEmbeddedClasses.swift
  146. +2 −2 swift-sdk/Internal/MiscInboxClasses.swift
  147. +0 −8 swift-sdk/Internal/Models.swift
  148. +2 −2 swift-sdk/Internal/{ → Network}/NetworkConnectivityChecker.swift
  149. +5 −11 swift-sdk/Internal/{ → Network}/NetworkConnectivityManager.swift
  150. +71 −60 swift-sdk/Internal/{ → Network}/NetworkHelper.swift
  151. +0 −37 swift-sdk/Internal/{ → Network}/NetworkMonitor.swift
  152. +147 −0 swift-sdk/Internal/Network/NetworkSession.swift
  153. +0 −268 swift-sdk/Internal/OnlineRequestProcessor.swift
  154. +76 −30 swift-sdk/Internal/{Promise.swift → Pending.swift}
  155. +0 −268 swift-sdk/Internal/RequestHandler.swift
  156. +50 −19 swift-sdk/Internal/RequestHandlerProtocol.swift
  157. +112 −18 swift-sdk/Internal/RequestProcessorUtil.swift
  158. +5 −5 swift-sdk/Internal/RequestSender.swift
  159. +32 −0 swift-sdk/Internal/Utilities/DependencyContainer.swift
  160. +64 −70 swift-sdk/Internal/{DependencyContainer.swift → Utilities/DependencyContainerProtocol.swift}
  161. 0 swift-sdk/Internal/{ → Utilities}/IterableLogUtil.swift
  162. +13 −2 swift-sdk/Internal/{ → Utilities}/IterableUtil.swift
  163. +86 −0 swift-sdk/Internal/Utilities/Keychain/IterableKeychain.swift
  164. +117 −0 swift-sdk/Internal/Utilities/Keychain/KeychainWrapper.swift
  165. +139 −0 swift-sdk/Internal/Utilities/LocalStorage.swift
  166. +15 −7 swift-sdk/Internal/{ → Utilities}/LocalStorageProtocol.swift
  167. +1 −0 swift-sdk/Internal/{ → Utilities}/NotificationHelper.swift
  168. 0 swift-sdk/Internal/{ → Utilities}/OrderedDictionary.swift
  169. 0 swift-sdk/Internal/{ → Utilities}/PersistenceHelper.swift
  170. 0 swift-sdk/Internal/{ → Utilities}/ResourceHelper.swift
  171. +34 −0 swift-sdk/Internal/Utilities/UIColor+Extension.swift
  172. +6 −7 swift-sdk/Internal/{ → Utilities}/WebViewProtocol.swift
  173. +69 −29 swift-sdk/Internal/{ → api-client}/ApiClient.swift
  174. +60 −0 swift-sdk/Internal/api-client/ApiClientProtocol.swift
  175. +160 −52 swift-sdk/Internal/{ → api-client/Request}/OfflineRequestProcessor.swift
  176. +326 −0 swift-sdk/Internal/api-client/Request/OnlineRequestProcessor.swift
  177. +165 −6 swift-sdk/Internal/{ → api-client/Request}/RequestCreator.swift
  178. +360 −0 swift-sdk/Internal/api-client/Request/RequestHandler.swift
  179. +41 −11 swift-sdk/Internal/{ → api-client/Request}/RequestProcessorProtocol.swift
  180. +2 −14 swift-sdk/Internal/{ → in-app}/InAppCalculations.swift
  181. 0 swift-sdk/Internal/{ → in-app}/InAppContentParser.swift
  182. +23 −24 swift-sdk/Internal/{ → in-app}/InAppDisplayer.swift
  183. +2 −2 swift-sdk/Internal/{ → in-app}/InAppHelper.swift
  184. +5 −5 swift-sdk/Internal/{ → in-app}/InAppInternal.swift
  185. +14 −4 swift-sdk/Internal/{ → in-app}/InAppManager+Functions.swift
  186. +132 −112 swift-sdk/Internal/{ → in-app}/InAppManager.swift
  187. +62 −24 swift-sdk/Internal/{ → in-app}/InAppMessageParser.swift
  188. +46 −9 swift-sdk/Internal/{ → in-app}/InAppPersistence.swift
  189. +6 −11 swift-sdk/Internal/{ → in-app}/InAppPresenter.swift
  190. +0 −12 swift-sdk/IterableAuthManagerProtocol.swift
  191. +1 −4 swift-sdk/Resources/IterableDataModel.xcdatamodeld/IterableDataModel.xcdatamodel/contents
  192. +82 −0 swift-sdk/Resources/PrivacyInfo.xcprivacy
  193. +156 −56 swift-sdk/{ → SDK}/IterableAPI.swift
  194. +3 −5 swift-sdk/{ → SDK}/IterableAppIntegration.swift
  195. +37 −0 swift-sdk/{ → SDK}/IterableConfig.swift
  196. +1 −5 swift-sdk/{ → SDK}/IterableLogging.swift
  197. 0 swift-sdk/{ → SDK}/IterableMessaging.swift
  198. +39 −0 swift-sdk/ui-components/swiftui/InboxViewRepresentable.swift
  199. +94 −0 swift-sdk/ui-components/swiftui/IterableInboxView.swift
  200. +529 −0 swift-sdk/ui-components/uikit/IterableEmbeddedView.swift
  201. +150 −0 swift-sdk/ui-components/uikit/IterableEmbeddedView.xib
  202. 0 swift-sdk/{ → ui-components/uikit}/IterableInboxCell.swift
  203. +2 −3 swift-sdk/{ → ui-components/uikit}/IterableInboxNavigationViewController.swift
  204. +34 −21 swift-sdk/{ → ui-components/uikit}/IterableInboxViewController.swift
  205. 0 swift-sdk/{Resources → ui-components/uikit}/SampleInboxCell.xib
  206. +78 −6 tests/common/CommonExtensions.swift
  207. +20 −610 tests/common/CommonMocks.swift
  208. +15 −0 tests/common/MockAPNSTypeChecker.swift
  209. +20 −0 tests/common/MockApplicationStateProvider.swift
  210. +65 −0 tests/common/MockAuthManager.swift
  211. +31 −0 tests/common/MockCustomActionDelegate.swift
  212. +15 −0 tests/common/MockDateProvider.swift
  213. +22 −0 tests/common/MockInAppDelegate.swift
  214. +43 −0 tests/common/MockInAppDisplayer.swift
  215. +64 −0 tests/common/MockInAppFetcher.swift
  216. +23 −0 tests/common/MockInAppPersister.swift
  217. +46 −0 tests/common/MockInboxState.swift
  218. +50 −0 tests/common/MockLocalStorage.swift
  219. +25 −0 tests/common/MockMessageViewControllerEventTracker.swift
  220. +251 −0 tests/common/MockNetworkSession.swift
  221. +89 −0 tests/common/MockNotificationCenter.swift
  222. +21 −0 tests/common/MockNotificationResponse.swift
  223. +50 −0 tests/common/MockPushTracker.swift
  224. +31 −0 tests/common/MockUrlDelegate.swift
  225. +22 −0 tests/common/MockUrlOpener.swift
  226. +39 −0 tests/common/MockWebView.swift
  227. +29 −0 tests/endpoint-tests.xctestplan
  228. +1 −0 tests/endpoint-tests/CI.swift.template
  229. +4 −1 tests/endpoint-tests/E2EDependencyContainer.swift
  230. +14 −10 tests/endpoint-tests/EndpointTests.swift
  231. +5 −0 tests/endpoint-tests/Environment.swift
  232. +5 −4 tests/endpoint-tests/IterableAPISupport.swift
  233. +5 −5 tests/endpoint-tests/OfflineModeE2ETests.swift
  234. +1 −0 tests/endpoint-tests/scripts/env_vars.sh.sample
  235. +3 −1 tests/endpoint-tests/scripts/run_test.sh
  236. +4 −0 tests/hosting-apps/host-app/host-app.entitlements
  237. +6 −6 tests/hosting-apps/inbox-ui-tests-app/AppDelegate.swift
  238. +10 −0 tests/hosting-apps/inbox-ui-tests-app/inbox-ui-tests-app.entitlements
  239. +17 −29 tests/hosting-apps/ui-tests-app/ViewController.swift
  240. +4 −0 tests/hosting-apps/ui-tests-app/ui-tests-app.entitlements
  241. +38 −33 tests/inbox-ui-tests/InboxCustomizationTests.swift
  242. +121 −117 tests/inbox-ui-tests/InboxUITests.swift
  243. +9 −1 tests/inbox-ui-tests/InboxUITestsHelper.swift
  244. +100 −0 tests/inbox-ui-tests/NavInboxSessionUITests.swift
  245. +59 −0 tests/inbox-ui-tests/PopupInboxSessionUITests.swift
  246. +140 −13 ...cation-extension-tests/{NotificationExtensionSwiftTests.swift → NotificationExtensionTests.swift}
  247. +57 −25 tests/offline-events-tests/HealthMonitorTests.swift
  248. +19 −8 tests/offline-events-tests/MockPersistence.swift
  249. +65 −30 tests/offline-events-tests/NetworkConnectivityManagerTests.swift
  250. +171 −48 tests/offline-events-tests/RequestHandlerTests.swift
  251. +8 −10 tests/offline-events-tests/TaskProcessorTests.swift
  252. +73 −36 tests/offline-events-tests/TaskRunnerTests.swift
  253. +73 −24 tests/offline-events-tests/TaskSchedulerTests.swift
  254. +133 −106 tests/offline-events-tests/TasksCRUDTests.swift
  255. +92 −0 tests/swift-sdk.xctestplan
  256. +37 −33 tests/ui-tests/IterableInboxViewControllerUITests.swift
  257. +176 −174 tests/ui-tests/UITests.swift
  258. +1 −1 tests/ui-tests/UITestsHelper.swift
  259. +92 −38 tests/unit-tests/{IterableActionRunnerTests.swift → ActionRunnerTests.swift}
  260. +219 −35 tests/unit-tests/AuthTests.swift
  261. +26 −7 tests/unit-tests/{IterableAutoRegistrationTests.swift → AutoRegistrationTests.swift}
  262. +105 −0 tests/unit-tests/BlankApiClient.swift
  263. +1 −1 tests/unit-tests/CommerceItemTests.swift
  264. +85 −44 tests/unit-tests/DeepLinkTests.swift
  265. +388 −0 tests/unit-tests/EmbeddedManagerTests.swift
  266. +45 −0 tests/unit-tests/EmbeddedMessagingProcessorTests.swift
  267. +9 −0 tests/unit-tests/EmbeddedMessagingSerializationTests.swift
  268. +49 −0 tests/unit-tests/EmbeddedSessionManagerTests.swift
  269. +8 −91 tests/unit-tests/InAppHelperTests.swift
  270. +15 −0 tests/unit-tests/InAppMessageProcessorTests.swift
  271. +138 −0 tests/unit-tests/InAppNavigationTests.swift
  272. +10 −10 tests/unit-tests/InAppParsingTests.swift
  273. +173 −1 tests/unit-tests/InAppPersistenceTests.swift
  274. +2 −2 tests/unit-tests/InAppPresenterTests.swift
  275. +455 −11 tests/unit-tests/InAppTests.swift
  276. +1 −1 tests/unit-tests/InboxMessageViewModelTests.swift
  277. +3 −6 tests/unit-tests/InboxSessionManagerTests.swift
  278. +13 −5 tests/unit-tests/InboxTests.swift
  279. +456 −452 tests/unit-tests/InboxViewControllerViewModelTests.swift
  280. +81 −15 tests/unit-tests/IterableAPIResponseTests.swift
  281. +170 −6 tests/unit-tests/IterableAPITests.swift
  282. +30 −0 tests/unit-tests/IterableDataRegionObjCTests.m
  283. +80 −2 tests/unit-tests/IterableHtmlMessageViewControllerTests.swift
  284. +0 −2 tests/unit-tests/IterableInboxViewControllerTests.swift
  285. +1 −1 tests/unit-tests/IterableRequestUtilTests.swift
  286. +82 −0 tests/unit-tests/KeychainWrapperTests.swift
  287. +57 −90 tests/unit-tests/LocalStorageTests.swift
  288. +9 −9 tests/unit-tests/Mocks.swift
  289. +11 −11 tests/unit-tests/NotificationMetadataTests.swift
  290. +46 −0 tests/unit-tests/NotificationObserverTests.swift
  291. +16 −104 tests/unit-tests/{IterableNotificationResponseTests.swift → NotificationResponseTests.swift}
  292. +42 −42 tests/unit-tests/{PromiseTests.swift → PendingTests.swift}
  293. +20 −14 tests/unit-tests/RequestCreatorTests.swift
  294. +38 −11 tests/unit-tests/TestInAppPayloadGenerator.swift
  295. +19 −0 tests/unit-tests/TestUtils.swift
  296. +1 −1 tests/unit-tests/WebViewProtocolTests.swift
  297. +4 −0 tests/unit-tests/unit-tests-Bridging-Header.h
6 changes: 6 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
root = true

[*]
indent_style = space
indent_size = 4
tab_width = 4
119 changes: 103 additions & 16 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
@@ -4,21 +4,108 @@ on: pull_request

jobs:
run-tests-job:
runs-on: macos-latest
runs-on: macos-15

steps:
- uses: actions/checkout@v2

- uses: maxim-lobanov/setup-xcode@v1.1
with:
xcode-version: 12.0

- name: Build and test
run: |
xcodebuild test -project swift-sdk.xcodeproj -scheme swift-sdk -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 11' -enableCodeCoverage YES CODE_SIGNING_REQUIRED=NO | xcpretty && exit ${PIPESTATUS[0]}
- name: CocoaPods lint
run: pod lib lint

- name: Upload coverage report to codecov.io
run: bash <(curl -s https://codecov.io/bash) -X gcov -J 'IterableSDK' -J 'IterableAppExtensions'
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
with:
xcode-version: latest-stable

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.x'

- name: Setup Ruby and xcpretty
run: |
gem install erb
gem install xcpretty
- name: Print available simulators
run: xcrun simctl list devices | cat

- name: Build and test
run: |
xcodebuild test -project swift-sdk.xcodeproj -scheme swift-sdk -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 16 Pro,OS=18.2' -enableCodeCoverage YES -resultBundlePath TestResults.xcresult CODE_SIGNING_REQUIRED=NO | xcpretty && exit ${PIPESTATUS[0]}
- name: Process test results
run: |
python3 scripts/process_xcresult.py --path TestResults.xcresult --test-output test-results.html --coverage-output coverage-results.html --test-plan tests/swift-sdk.xctestplan --summary-json test-summary.json --commit-sha ${{ github.sha }}
if: success() || failure()

- name: Create Test Report Check
uses: actions/github-script@v7
if: success() || failure()
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
// Read the test results and coverage reports
let testReport = "";
let coverageReport = "";
try {
testReport = fs.readFileSync("test-results.html", 'utf8');
coverageReport = fs.readFileSync("coverage-results.html", 'utf8');
} catch (error) {
core.warning(`Error reading report files: ${error.message}`);
}
// Read test summary
let testStats = {
total_tests: 0,
passed_tests: 0,
failed_tests: 0,
success_rate: 0
};
try {
const summaryJson = fs.readFileSync("test-summary.json", 'utf8');
testStats = JSON.parse(summaryJson);
// Generate simple markdown summary
fs.writeFileSync("report-summary.md",
`# Test Results\n\n` +
`- Total: ${testStats.total_tests}\n` +
`- Passed: ${testStats.passed_tests}\n` +
`- Failed: ${testStats.failed_tests}\n` +
`- Success: ${(testStats.success_rate).toFixed(1)}%\n`
);
} catch (error) {
core.warning(`Error reading test summary: ${error.message}`);
}
// Extract just the main content from the HTML - removing the HTML tags
function stripHtml(html) {
// Simple regex to extract text content from HTML
return html
.replace(/<h2>[\s\S]*?<\/h2>/gi, '')
.trim();
}
// Create the check with test results as summary and coverage as details
await github.rest.checks.create({
owner: context.repo.owner,
repo: context.repo.repo,
name: 'Unit Test Results',
head_sha: context.payload.pull_request?.head.sha || context.sha,
status: 'completed',
conclusion: testStats.failed_tests > 0 ? 'failure' : 'success',
output: {
title: `Tests: ${testStats.passed_tests}/${testStats.passed_tests + testStats.failed_tests} passed (${(testStats.success_rate).toFixed(1)}%) Skipped: ${testStats.skipped_tests}`,
summary: stripHtml(testReport.substring(0, 65000)),
text: stripHtml(coverageReport.substring(0, 65000))
}
});
- name: CocoaPods lint
run: pod lib lint --allow-warnings

- name: Upload coverage report to codecov.io
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
run: bash <(curl -s https://codecov.io/bash) -X gcov -J 'IterableSDK' -J 'IterableAppExtensions' -B main -C ${{ github.sha }} -r ${{ github.repository }}
34 changes: 18 additions & 16 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -4,22 +4,24 @@ on: pull_request

jobs:
run-e2e-job:
runs-on: macos-latest
runs-on: macos-15

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
with:
xcode-version: latest-stable

- uses: maxim-lobanov/setup-xcode@v1.1
with:
xcode-version: 12.0
- name: Build and test
env:
api_key: ${{secrets.E2E_API_KEY}}
server_api_key: ${{secrets.E2E_SERVER_API_KEY}}
push_campaign_id: ${{secrets.E2E_PUSH_CAMPAIGN_ID}}
push_template_id: ${{secrets.E2E_PUSH_TEMPLATE_ID}}
in_app_campaign_id: ${{secrets.E2E_IN_APP_CAMPAIGN_ID}}
in_app_template_id: ${{secrets.E2E_IN_APP_TEMPLATE_ID}}
run: |
./tests/endpoint-tests/scripts/run_test.sh
- name: Build and test
env:
api_key: ${{secrets.E2E_API_KEY}}
push_campaign_id: ${{secrets.E2E_PUSH_CAMPAIGN_ID}}
push_template_id: ${{secrets.E2E_PUSH_TEMPLATE_ID}}
in_app_campaign_id: ${{secrets.E2E_IN_APP_CAMPAIGN_ID}}
in_app_template_id: ${{secrets.E2E_IN_APP_TEMPLATE_ID}}
run: |
./tests/endpoint-tests/scripts/run_test.sh
62 changes: 62 additions & 0 deletions .github/workflows/ios-sdk-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: iOS SDK Release
run-name: ${{ github.actor }} is starting iOS SDK release

on:
workflow_dispatch:
inputs:
version_number:
description: "iOS SDK version"
required: true
branch:
description: "Branch to release (defaults to master)"
required: true
default: "master"
changelog_section:
description: "Changelog version header (e.g. 6.4.17, 6.5.0-beta)"
required: true
set_prerelease:
type: boolean
description: "Is this a prerelease?"
default: false
env:
VERSION: ${{ github.event.inputs.version_number }}
BRANCH: ${{ github.event.inputs.branch }}
CHANGELOG_SECTION: ${{ github.event.inputs.changelog_section }}
OUTPUT_DIR: ./output_dir
GITHUB_TOKEN: ${{ secrets.SDK_RELEASE_TOKEN }}
RELEASE_BRANCH:
SET_PRERELEASE: ${{ github.event.inputs.set_prerelease }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }}

jobs:
ios-sdk-release:
runs-on: macos-latest

steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: ruby/setup-ruby@6bd3d993c602f6b675728ebaecb2b569ff86e99b # v1.174.0
with:
ruby-version: "3.2"
bundler-cache: true
- name: Install Cocoapods
run: gem install cocoapods

- name: clean cocaopods cache and lint
run: bundle exec fastlane ios clean_and_lint

- name: create xcframeworks and zip
run: bundle exec fastlane ios build_xcframework output_dir:./output_dir

- name: create and push git tag
run: bundle exec fastlane ios create_git_tag version:$VERSION

- name: create github release and upload assets
run: |
bundle exec fastlane ios create_release version:$VERSION branch:$BRANCH changelog_section:$CHANGELOG_SECTION output_dir:$OUTPUT_DIR github_token:$GITHUB_TOKEN set_prerelease:$SET_PRERELEASE
- name: push pods to trunk
run: bundle exec fastlane ios pod_trunk_push

- name: slack notification
run: bundle exec fastlane ios slack_message version:$VERSION changelog_section:$CHANGELOG_SECTION slack_webhook:$SLACK_WEBHOOK
109 changes: 109 additions & 0 deletions .github/workflows/prepare-for-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
name: Prepare For Release

on:
workflow_dispatch:
inputs:
version:
description: 'Version number (e.g., 6.5.0)'
required: true
type: string
jira_ticket:
description: 'JIRA ticket MOB number (e.g., 1234)'
required: true
type: string

permissions:
contents: write
pull-requests: write

jobs:
prepare-release:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}

- name: Update Changelog
id: update_changelog
run: |
changelog_file="CHANGELOG.md"
# Function to extract content between two patterns, including the first pattern
extract_between() {
awk "/^## \[$1\]/{p=1;print;next} /^## \[/{p=0} p" "$3"
}
# Get the unreleased content
unreleased_content=$(extract_between "Unreleased" "[0-9]" "$changelog_file")
if [ -z "$unreleased_content" ]; then
echo "No unreleased changes found in $changelog_file"
exit 1
fi
# Get the current version - using awk
current_version=$(awk '/^## \[[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?\]/ { match($0, /[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?/); print substr($0, RSTART, RLENGTH); exit }' "$changelog_file")
new_version="${{ github.event.inputs.version }}"
# Validate version format
if ! [[ $new_version =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?$ ]]; then
echo "Invalid version format. Please use semantic versioning (e.g., 6.5.0 or 6.5.0-beta1)"
exit 1
fi
echo "new_version=${new_version}" >> $GITHUB_OUTPUT
# Create temporary file
temp_file=$(mktemp)
# Preserve header and write new content
{
# Preserve the header (first 4 lines)
head -n 4 "$changelog_file"
echo "## [Unreleased]"
echo ""
echo "## [$new_version]"
# Remove the "## [Unreleased]" line from unreleased_content using BSD sed
echo "$unreleased_content" | sed '1{/^## \[Unreleased\]/d;}'
echo ""
# Get the rest of the file starting from the first version entry
sed -n '/^## \[[0-9]/,$p' "$changelog_file"
} > "$temp_file"
# Replace original file
mv "$temp_file" "$changelog_file"
- name: Update Version Numbers
run: |
# Update Iterable-iOS-SDK.podspec
sed -i '' "s/\(s\.version[[:space:]]*=[[:space:]]*\)\".*\"/\1\"${{ github.event.inputs.version }}\"/" Iterable-iOS-SDK.podspec
# Update Iterable-iOS-AppExtensions.podspec
sed -i '' "s/\(s\.version[[:space:]]*=[[:space:]]*\)\".*\"/\1\"${{ github.event.inputs.version }}\"/" Iterable-iOS-AppExtensions.podspec
# Update sdkVersion in IterableAPI.swift
find . -name "IterableAPI.swift" -type f -exec sed -i '' "s/\(static let sdkVersion[[:space:]]*=[[:space:]]*\)\".*\"/\1\"${{ github.event.inputs.version }}\"/" {} \;
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
with:
token: ${{ secrets.GITHUB_TOKEN }}
title: "MOB-${{ github.event.inputs.jira_ticket }}: Prepare for Release ${{ steps.update_changelog.outputs.new_version }}"
body: |
# Prepare for Release ${{ steps.update_changelog.outputs.new_version }}
## SDK Release Checklist
- [ ] CHANGELOG.md updated with correct version
- [ ] Version numbers updated:
- [ ] Iterable-iOS-SDK.podspec
- [ ] Iterable-iOS-AppExtensions.podspec
- [ ] sdkVersion in IterableAPI.swift
- [ ] README.md reviewed (if needed)
- [ ] All tests passing
- [ ] Documentation updated (if needed)
branch: "MOB-${{ github.event.inputs.jira_ticket }}-prepare-for-release-${{ steps.update_changelog.outputs.new_version }}"
commit-message: "[MOB-${{ github.event.inputs.jira_ticket }}]: Prepare for release ${{ steps.update_changelog.outputs.new_version }}"
labels: release
delete-branch: true
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -18,3 +18,13 @@ build2/
# needed integration testing
env_vars.sh
CI.swift
*.swiftmodule
*.timestamp
*.modulemap
*.pcm
.build/arm64-apple-macosx/debug/IterableSDK.build/DerivedSources/resource_bundle_accessor.swift
.build/arm64-apple-macosx/debug/index/db/v13/p25195--4de704/lock.mdb
.build/arm64-apple-macosx/debug/index/db/v13/p25195--4de704/data.mdb
.build/workspace-state.json
*.mdb
.build/arm64-apple-macosx/debug/IterableSDK.build/output-file-map.json
Loading