Skip to content

Commit 8fa51ac

Browse files
Merge pull request #550 from Iterable/tapash/mob-4289-network-session
[MOB-4289] - NetworkSession Refactoring
2 parents 33a2f48 + 2079403 commit 8fa51ac

20 files changed

+465
-220
lines changed

swift-sdk.xcodeproj/project.pbxproj

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
55E6F462238E066400808BCE /* DeepLinkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55E6F45E238E066400808BCE /* DeepLinkTests.swift */; };
4141
5B49BB3E27CFB71500E6F00C /* PopupInboxSessionUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B49BB3D27CFB71500E6F00C /* PopupInboxSessionUITests.swift */; };
4242
5B6C3C1127CE871F00B9A753 /* NavInboxSessionUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6C3C1027CE871F00B9A753 /* NavInboxSessionUITests.swift */; };
43+
5B88BC482805D09D004016E5 /* NetworkSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B88BC472805D09D004016E5 /* NetworkSession.swift */; };
4344
AC02480822791E2100495FB9 /* IterableInboxNavigationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC02480722791E2100495FB9 /* IterableInboxNavigationViewController.swift */; };
4445
AC02CAA6234E50B5006617E0 /* RegistrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC02CAA5234E50B5006617E0 /* RegistrationTests.swift */; };
4546
AC03094B21E532470003A288 /* InAppPersistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC03094A21E532470003A288 /* InAppPersistence.swift */; };
@@ -89,7 +90,6 @@
8990
AC43E7FF23A8C2C0008917E2 /* image.jpg in Resources */ = {isa = PBXBuildFile; fileRef = AC74FE1E23A8C0DB004AC442 /* image.jpg */; };
9091
AC4B039622A8743F0043185B /* InAppManager+Functions.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4B039322A8743F0043185B /* InAppManager+Functions.swift */; };
9192
AC4BA00224163D8F007359F1 /* IterableHtmlMessageViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4BA00124163D8F007359F1 /* IterableHtmlMessageViewControllerTests.swift */; };
92-
AC4BAE0A240BAF0E00D9121F /* OHHTTPStubs in Frameworks */ = {isa = PBXBuildFile; productRef = AC4BAE09240BAF0E00D9121F /* OHHTTPStubs */; };
9393
AC50865424C60172001DC132 /* IterableDataModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = AC50865224C60172001DC132 /* IterableDataModel.xcdatamodeld */; };
9494
AC50865624C603AC001DC132 /* IterablePersistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC50865524C603AC001DC132 /* IterablePersistence.swift */; };
9595
AC50865824C60426001DC132 /* IterableTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC50865724C60426001DC132 /* IterableTask.swift */; };
@@ -414,6 +414,7 @@
414414
55E6F45E238E066400808BCE /* DeepLinkTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeepLinkTests.swift; sourceTree = "<group>"; };
415415
5B49BB3D27CFB71500E6F00C /* PopupInboxSessionUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopupInboxSessionUITests.swift; sourceTree = "<group>"; };
416416
5B6C3C1027CE871F00B9A753 /* NavInboxSessionUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavInboxSessionUITests.swift; sourceTree = "<group>"; };
417+
5B88BC472805D09D004016E5 /* NetworkSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkSession.swift; sourceTree = "<group>"; };
417418
5BFC7CED27FC9AF300E77479 /* inbox-ui-tests-app.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "inbox-ui-tests-app.entitlements"; sourceTree = "<group>"; };
418419
AC02480722791E2100495FB9 /* IterableInboxNavigationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IterableInboxNavigationViewController.swift; sourceTree = "<group>"; };
419420
AC02CAA5234E50B5006617E0 /* RegistrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationTests.swift; sourceTree = "<group>"; };
@@ -635,7 +636,6 @@
635636
buildActionMask = 2147483647;
636637
files = (
637638
AC7B143020D02CE200877BFE /* IterableSDK.framework in Frameworks */,
638-
AC4BAE0A240BAF0E00D9121F /* OHHTTPStubs in Frameworks */,
639639
);
640640
runOnlyForDeploymentPostprocessing = 0;
641641
};
@@ -754,7 +754,6 @@
754754
AC2263D520CF49B8009800EB = {
755755
isa = PBXGroup;
756756
children = (
757-
5BFC7CED27FC9AF300E77479 /* inbox-ui-tests-app.entitlements */,
758757
AC2263E120CF49B8009800EB /* swift-sdk */,
759758
AC90C4C520D8632E00EECA5D /* notification-extension */,
760759
ACFCA72920EB02DB00BFB277 /* tests */,
@@ -1210,6 +1209,7 @@
12101209
AC7B4B0123C6F9B500DB4758 /* Supporting Files */,
12111210
AC7B4B0023C6F99200DB4758 /* Test Files */,
12121211
ACDA975B23159C37004C412E /* AppDelegate.swift */,
1212+
5BFC7CED27FC9AF300E77479 /* inbox-ui-tests-app.entitlements */,
12131213
ACDA976223159C39004C412E /* Assets.xcassets */,
12141214
AC7B4AF823C6547A00DB4758 /* CustomInboxCell3.swift */,
12151215
AC7B4AF723C6547A00DB4758 /* CustomInboxCell3.xib */,
@@ -1251,6 +1251,7 @@
12511251
children = (
12521252
AC978D3D24FF953C00372B8C /* NetworkConnectivityChecker.swift */,
12531253
ACF40620250781F1005FD775 /* NetworkConnectivityManager.swift */,
1254+
5B88BC472805D09D004016E5 /* NetworkSession.swift */,
12541255
ACD6116B2107D004003E7F6B /* NetworkHelper.swift */,
12551256
ACF406222507BC72005FD775 /* NetworkMonitor.swift */,
12561257
);
@@ -1412,7 +1413,6 @@
14121413
);
14131414
name = "unit-tests";
14141415
packageProductDependencies = (
1415-
AC4BAE09240BAF0E00D9121F /* OHHTTPStubs */,
14161416
);
14171417
productName = "swift-sdk-swift-tests";
14181418
productReference = AC7B142B20D02CE200877BFE /* unit-tests.xctest */;
@@ -1637,7 +1637,6 @@
16371637
);
16381638
mainGroup = AC2263D520CF49B8009800EB;
16391639
packageReferences = (
1640-
ACACA91623E0947C00B9E8DF /* XCRemoteSwiftPackageReference "OHHTTPStubs" */,
16411640
);
16421641
productRefGroup = AC2263E020CF49B8009800EB /* Products */;
16431642
projectDirPath = "";
@@ -1794,6 +1793,7 @@
17941793
ACD6116C2107D004003E7F6B /* NetworkHelper.swift in Sources */,
17951794
ACC362B624D16D91002C67BA /* IterableRequest.swift in Sources */,
17961795
ACB1DFDB26369D2F00A31597 /* HealthMonitor.swift in Sources */,
1796+
5B88BC482805D09D004016E5 /* NetworkSession.swift in Sources */,
17971797
AC06E4D327948C32007A6F20 /* InboxState.swift in Sources */,
17981798
ACC362BD24D21172002C67BA /* IterableAPICallTaskProcessor.swift in Sources */,
17991799
AC84510922910A0C0052BB8F /* RequestCreator.swift in Sources */,
@@ -2590,7 +2590,7 @@
25902590
buildSettings = {
25912591
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
25922592
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
2593-
CODE_SIGN_ENTITLEMENTS = "inbox-ui-tests-app.entitlements";
2593+
CODE_SIGN_ENTITLEMENTS = "tests/hosting-apps/inbox-ui-tests-app/inbox-ui-tests-app.entitlements";
25942594
CODE_SIGN_STYLE = Automatic;
25952595
DEVELOPMENT_TEAM = BP98Z28R86;
25962596
INFOPLIST_FILE = "tests/hosting-apps/inbox-ui-tests-app/Info.plist";
@@ -2614,7 +2614,7 @@
26142614
buildSettings = {
26152615
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
26162616
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
2617-
CODE_SIGN_ENTITLEMENTS = "inbox-ui-tests-app.entitlements";
2617+
CODE_SIGN_ENTITLEMENTS = "tests/hosting-apps/inbox-ui-tests-app/inbox-ui-tests-app.entitlements";
26182618
CODE_SIGN_STYLE = Automatic;
26192619
DEVELOPMENT_TEAM = BP98Z28R86;
26202620
INFOPLIST_FILE = "tests/hosting-apps/inbox-ui-tests-app/Info.plist";
@@ -2923,25 +2923,6 @@
29232923
};
29242924
/* End XCConfigurationList section */
29252925

2926-
/* Begin XCRemoteSwiftPackageReference section */
2927-
ACACA91623E0947C00B9E8DF /* XCRemoteSwiftPackageReference "OHHTTPStubs" */ = {
2928-
isa = XCRemoteSwiftPackageReference;
2929-
repositoryURL = "https://github.com/AliSoftware/OHHTTPStubs.git";
2930-
requirement = {
2931-
kind = upToNextMajorVersion;
2932-
minimumVersion = 9.0.0;
2933-
};
2934-
};
2935-
/* End XCRemoteSwiftPackageReference section */
2936-
2937-
/* Begin XCSwiftPackageProductDependency section */
2938-
AC4BAE09240BAF0E00D9121F /* OHHTTPStubs */ = {
2939-
isa = XCSwiftPackageProductDependency;
2940-
package = ACACA91623E0947C00B9E8DF /* XCRemoteSwiftPackageReference "OHHTTPStubs" */;
2941-
productName = OHHTTPStubs;
2942-
};
2943-
/* End XCSwiftPackageProductDependency section */
2944-
29452926
/* Begin XCVersionGroup section */
29462927
AC50865224C60172001DC132 /* IterableDataModel.xcdatamodeld */ = {
29472928
isa = XCVersionGroup;

swift-sdk.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 0 additions & 16 deletions
This file was deleted.

swift-sdk/Constants.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,17 @@ enum Const {
7878
static let online = "Online"
7979
static let offline = "Offline"
8080
}
81+
82+
enum CookieName {
83+
static let campaignId = "iterableEmailCampaignId"
84+
static let templateId = "iterableTemplateId"
85+
static let messageId = "iterableMessageId"
86+
}
87+
88+
enum HttpHeader {
89+
static let location = "Location"
90+
static let setCookie = "Set-Cookie"
91+
}
8192
}
8293

8394
enum JsonKey {

swift-sdk/Internal/DependencyContainer.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import Foundation
66
import UIKit
77

8-
protocol DependencyContainerProtocol {
8+
protocol DependencyContainerProtocol: RedirectNetworkSessionProvider {
99
var dateProvider: DateProviderProtocol { get }
1010
var networkSession: NetworkSessionProtocol { get }
1111
var notificationStateProvider: NotificationStateProviderProtocol { get }
@@ -106,6 +106,10 @@ extension DependencyContainerProtocol {
106106
CoreDataPersistenceContextProvider(dateProvider: dateProvider)
107107
}
108108

109+
func createRedirectNetworkSession(delegate: RedirectNetworkSessionDelegate) -> NetworkSessionProtocol {
110+
RedirectNetworkSession(delegate: delegate)
111+
}
112+
109113
private func createTaskScheduler(persistenceContextProvider: IterablePersistenceContextProvider,
110114
healthMonitor: HealthMonitor) -> IterableTaskScheduler {
111115
IterableTaskScheduler(persistenceContextProvider: persistenceContextProvider,

swift-sdk/Internal/InternalIterableAPI.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider {
541541
localStorage = dependencyContainer.localStorage
542542
inAppDisplayer = dependencyContainer.inAppDisplayer
543543
urlOpener = dependencyContainer.urlOpener
544-
deepLinkManager = IterableDeepLinkManager()
544+
deepLinkManager = IterableDeepLinkManager(redirectNetworkSessionProvider: dependencyContainer)
545545
}
546546

547547
func start() -> Pending<Bool, Error> {

swift-sdk/Internal/IterableDeepLinkManager.swift

Lines changed: 14 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import Foundation
66

77
class IterableDeepLinkManager: NSObject {
8+
init(redirectNetworkSessionProvider: RedirectNetworkSessionProvider) {
9+
self.redirectNetworkSessionProvider = redirectNetworkSessionProvider
10+
}
811
/// Handles a Universal Link
912
/// For Iterable links, it will track the click and retrieve the original URL,
1013
/// pass it to `IterableURLDelegate` for handling
@@ -63,7 +66,7 @@ class IterableDeepLinkManager: NSObject {
6366
deepLinkMessageId = nil
6467

6568
if isIterableDeepLink(appLinkURL.absoluteString) {
66-
let trackAndRedirectTask = redirectUrlSession.dataTask(with: appLinkURL) { [unowned self] _, _, error in
69+
redirectUrlSession.makeDataRequest(with: appLinkURL) { [unowned self] _, _, error in
6770
if let error = error {
6871
ITBError("error: \(error.localizedDescription)")
6972
fulfill.resolve(with: (nil, nil))
@@ -77,8 +80,6 @@ class IterableDeepLinkManager: NSObject {
7780
}
7881
}
7982
}
80-
81-
trackAndRedirectTask.resume()
8283
} else {
8384
fulfill.resolve(with: (appLinkURL, nil))
8485
}
@@ -94,59 +95,23 @@ class IterableDeepLinkManager: NSObject {
9495
return regex.firstMatch(in: urlString, options: [], range: NSMakeRange(0, urlString.count)) != nil
9596
}
9697

97-
private lazy var redirectUrlSession: URLSession = {
98-
URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue.main)
98+
private lazy var redirectUrlSession: NetworkSessionProtocol = {
99+
redirectNetworkSessionProvider.createRedirectNetworkSession(delegate: self)
99100
}()
101+
100102

103+
private var redirectNetworkSessionProvider: RedirectNetworkSessionProvider
101104
private var deepLinkLocation: URL?
102105
private var deepLinkCampaignId: NSNumber?
103106
private var deepLinkTemplateId: NSNumber?
104107
private var deepLinkMessageId: String?
105108
}
106109

107-
extension IterableDeepLinkManager: URLSessionDelegate, URLSessionTaskDelegate {
108-
/**
109-
Delegate handler when a redirect occurs. Stores a reference to the redirect url and does not execute the redirect.
110-
- parameters:
111-
- session: the session
112-
- task: the task
113-
- response: the redirectResponse
114-
- request: the request
115-
- completionHandler: the completionHandler
116-
*/
117-
public func urlSession(_: URLSession,
118-
task _: URLSessionTask,
119-
willPerformHTTPRedirection response: HTTPURLResponse,
120-
newRequest request: URLRequest,
121-
completionHandler: @escaping (URLRequest?) -> Void) {
122-
deepLinkLocation = request.url
123-
124-
guard let headerFields = response.allHeaderFields as? [String: String] else {
125-
return
126-
}
127-
128-
guard let url = response.url else {
129-
return
130-
}
131-
132-
for cookie in HTTPCookie.cookies(withResponseHeaderFields: headerFields, for: url) {
133-
if cookie.name == "iterableEmailCampaignId" {
134-
deepLinkCampaignId = number(fromString: cookie.value)
135-
} else if cookie.name == "iterableTemplateId" {
136-
deepLinkTemplateId = number(fromString: cookie.value)
137-
} else if cookie.name == "iterableMessageId" {
138-
deepLinkMessageId = cookie.value
139-
}
140-
}
141-
142-
completionHandler(nil)
143-
}
144-
145-
private func number(fromString str: String) -> NSNumber {
146-
if let intValue = Int(str) {
147-
return NSNumber(value: intValue)
148-
}
149-
150-
return NSNumber(value: 0)
110+
extension IterableDeepLinkManager: RedirectNetworkSessionDelegate {
111+
func onRedirect(deepLinkLocation: URL?, campaignId: NSNumber?, templateId: NSNumber?, messageId: String?) {
112+
self.deepLinkLocation = deepLinkLocation
113+
self.deepLinkCampaignId = campaignId
114+
self.deepLinkTemplateId = templateId
115+
self.deepLinkMessageId = messageId
151116
}
152117
}

swift-sdk/Internal/NetworkHelper.swift

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -27,43 +27,6 @@ extension NetworkError: LocalizedError {
2727
}
2828
}
2929

30-
protocol DataTaskProtocol {
31-
var state: URLSessionDataTask.State { get }
32-
func resume()
33-
func cancel()
34-
}
35-
36-
extension URLSessionDataTask: DataTaskProtocol {}
37-
38-
protocol NetworkSessionProtocol {
39-
typealias CompletionHandler = (Data?, URLResponse?, Error?) -> Void
40-
func makeRequest(_ request: URLRequest, completionHandler: @escaping CompletionHandler)
41-
func makeDataRequest(with url: URL, completionHandler: @escaping CompletionHandler)
42-
func createDataTask(with url: URL, completionHandler: @escaping CompletionHandler) -> DataTaskProtocol
43-
}
44-
45-
extension URLSession: NetworkSessionProtocol {
46-
func makeRequest(_ request: URLRequest, completionHandler: @escaping CompletionHandler) {
47-
let task = dataTask(with: request) { data, response, error in
48-
completionHandler(data, response, error)
49-
}
50-
51-
task.resume()
52-
}
53-
54-
func makeDataRequest(with url: URL, completionHandler: @escaping CompletionHandler) {
55-
let task = dataTask(with: url) { data, response, error in
56-
completionHandler(data, response, error)
57-
}
58-
59-
task.resume()
60-
}
61-
62-
func createDataTask(with url: URL, completionHandler: @escaping CompletionHandler) -> DataTaskProtocol {
63-
dataTask(with: url, completionHandler: completionHandler)
64-
}
65-
}
66-
6730
struct NetworkHelper {
6831
static func getData(fromUrl url: URL, usingSession networkSession: NetworkSessionProtocol) -> Pending<Data, Error> {
6932
let fulfill = Fulfill<Data, Error>()

0 commit comments

Comments
 (0)