Skip to content

Commit 4083874

Browse files
Merge pull request #517 from Iterable/tapash/mob-3594-swiftui-inbox
[MOB-3594] - SwiftUI Inbox
2 parents cf5d084 + 6c43731 commit 4083874

File tree

8 files changed

+163
-32
lines changed

8 files changed

+163
-32
lines changed

Iterable-iOS-SDK.podspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Pod::Spec.new do |s|
1616
s.platform = :ios, "9.0"
1717
s.source = { :git => "https://github.com/Iterable/swift-sdk.git", :tag => s.version }
1818
s.source_files = "swift-sdk/**/*.{h,m,swift}"
19+
s.exclude_files = "swift-sdk/swiftui/**"
1920

2021
s.pod_target_xcconfig = {
2122
'SWIFT_VERSION' => '5.3'

sample-apps/swiftui-sample-app/swiftui-sample-app.xcodeproj/project.pbxproj

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
AC5C7F6726E749B60067D6D7 /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC5C7F6626E749B60067D6D7 /* LoginView.swift */; };
2222
AC5C7F6926E7738E0067D6D7 /* DeeplinkHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC5C7F6826E7738E0067D6D7 /* DeeplinkHandler.swift */; };
2323
AC5C7F6B26E778530067D6D7 /* AppModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC5C7F6A26E778530067D6D7 /* AppModel.swift */; };
24-
AC9AF7C2271F20CB00619392 /* InboxView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC9AF7C1271F20CB00619392 /* InboxView.swift */; };
2524
ACEAACBC26EA00BA00D006AF /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACEAACBB26EA00BA00D006AF /* NotificationService.swift */; };
2625
ACEAACC026EA00BA00D006AF /* notification-extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = ACEAACB926EA00BA00D006AF /* notification-extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
2726
ACEAACC626EA00DF00D006AF /* IterableAppExtensions in Frameworks */ = {isa = PBXBuildFile; productRef = ACEAACC526EA00DF00D006AF /* IterableAppExtensions */; };
@@ -68,7 +67,6 @@
6867
AC5C7F6626E749B60067D6D7 /* LoginView.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = "<group>"; tabWidth = 2; };
6968
AC5C7F6826E7738E0067D6D7 /* DeeplinkHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeeplinkHandler.swift; sourceTree = "<group>"; };
7069
AC5C7F6A26E778530067D6D7 /* AppModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppModel.swift; sourceTree = "<group>"; };
71-
AC9AF7C1271F20CB00619392 /* InboxView.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = InboxView.swift; sourceTree = "<group>"; tabWidth = 2; };
7270
ACEAACB426E9FA6100D006AF /* swiftui-sample-app.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "swiftui-sample-app.entitlements"; sourceTree = "<group>"; };
7371
ACEAACB926EA00BA00D006AF /* notification-extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "notification-extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
7472
ACEAACBB26EA00BA00D006AF /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = "<group>"; };
@@ -159,7 +157,6 @@
159157
AC5C7F5F26E7361A0067D6D7 /* Views */ = {
160158
isa = PBXGroup;
161159
children = (
162-
AC9AF7C0271F200500619392 /* Inbox */,
163160
AC59DB0626E0C489002A7E08 /* ContentView.swift */,
164161
AC5C7F6026E7364B0067D6D7 /* CoffeeListView.swift */,
165162
AC5C7F6226E7370D0067D6D7 /* CoffeeView.swift */,
@@ -169,14 +166,6 @@
169166
path = Views;
170167
sourceTree = "<group>";
171168
};
172-
AC9AF7C0271F200500619392 /* Inbox */ = {
173-
isa = PBXGroup;
174-
children = (
175-
AC9AF7C1271F20CB00619392 /* InboxView.swift */,
176-
);
177-
name = Inbox;
178-
sourceTree = "<group>";
179-
};
180169
ACEAACBA26EA00BA00D006AF /* notification-extension */ = {
181170
isa = PBXGroup;
182171
children = (
@@ -292,7 +281,6 @@
292281
buildActionMask = 2147483647;
293282
files = (
294283
AC5C7F6126E7364B0067D6D7 /* CoffeeListView.swift in Sources */,
295-
AC9AF7C2271F20CB00619392 /* InboxView.swift in Sources */,
296284
AC5C7F6326E7370E0067D6D7 /* CoffeeView.swift in Sources */,
297285
AC5C7F6B26E778530067D6D7 /* AppModel.swift in Sources */,
298286
AC5C7F6526E744700067D6D7 /* CoffeeRow.swift in Sources */,

sample-apps/swiftui-sample-app/swiftui-sample-app/Views/ContentView.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import SwiftUI
2+
import IterableSDK
23

34
struct ContentView: View {
45
@State
@@ -33,7 +34,9 @@ struct ContentView: View {
3334
.tag(SelectedTab.home)
3435

3536
NavigationView {
36-
InboxView()
37+
IterableInboxView()
38+
.noMessagesTitle("No Messages")
39+
.noMessagesBody("Please check back later")
3740
}
3841
.tabItem {
3942
Image(systemName: "envelope")

sample-apps/swiftui-sample-app/swiftui-sample-app/Views/InboxView.swift

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

swift-sdk.xcodeproj/project.pbxproj

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@
169169
ACA8D1A62196309C001B1332 /* Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA8D1A42196309C001B1332 /* Common.swift */; };
170170
ACA8D1A921965B7D001B1332 /* InAppTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA8D1A821965B7D001B1332 /* InAppTests.swift */; };
171171
ACA8D1AB21966555001B1332 /* InAppManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA8D1AA21966555001B1332 /* InAppManager.swift */; };
172+
ACA95D2D275494A100AF4666 /* InboxViewRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA95D2C275494A100AF4666 /* InboxViewRepresentable.swift */; };
173+
ACA95D2F2754AA6800AF4666 /* IterableInboxView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA95D2E2754AA6800AF4666 /* IterableInboxView.swift */; };
172174
ACAA816E231163660035C743 /* RequestCreatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACAA816D231163660035C743 /* RequestCreatorTests.swift */; };
173175
ACB1DFD126369CC300A31597 /* HealthMonitorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACB1DFD026369CC300A31597 /* HealthMonitorTests.swift */; };
174176
ACB1DFDB26369D2F00A31597 /* HealthMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACB1DFDA26369D2F00A31597 /* HealthMonitor.swift */; };
@@ -527,6 +529,8 @@
527529
ACA8D1A42196309C001B1332 /* Common.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Common.swift; sourceTree = "<group>"; };
528530
ACA8D1A821965B7D001B1332 /* InAppTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InAppTests.swift; sourceTree = "<group>"; };
529531
ACA8D1AA21966555001B1332 /* InAppManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InAppManager.swift; sourceTree = "<group>"; };
532+
ACA95D2C275494A100AF4666 /* InboxViewRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InboxViewRepresentable.swift; sourceTree = "<group>"; };
533+
ACA95D2E2754AA6800AF4666 /* IterableInboxView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IterableInboxView.swift; sourceTree = "<group>"; };
530534
ACAA816D231163660035C743 /* RequestCreatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestCreatorTests.swift; sourceTree = "<group>"; };
531535
ACB1DFD026369CC300A31597 /* HealthMonitorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthMonitorTests.swift; sourceTree = "<group>"; };
532536
ACB1DFDA26369D2F00A31597 /* HealthMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthMonitor.swift; sourceTree = "<group>"; };
@@ -768,6 +772,7 @@
768772
AC2263E120CF49B8009800EB /* swift-sdk */ = {
769773
isa = PBXGroup;
770774
children = (
775+
AC5C467E2756AEA4000762B6 /* swiftui */,
771776
AC72A0BB20CF4C8C004D7997 /* Internal */,
772777
AC44C0EB22615F8100E0641D /* Resources */,
773778
AC2263F920CF4B63009800EB /* Supporting Files */,
@@ -959,6 +964,23 @@
959964
name = "local-storage-tests";
960965
sourceTree = "<group>";
961966
};
967+
AC5C467E2756AEA4000762B6 /* swiftui */ = {
968+
isa = PBXGroup;
969+
children = (
970+
AC5C467F2756B065000762B6 /* Internal */,
971+
ACA95D2E2754AA6800AF4666 /* IterableInboxView.swift */,
972+
);
973+
path = swiftui;
974+
sourceTree = "<group>";
975+
};
976+
AC5C467F2756B065000762B6 /* Internal */ = {
977+
isa = PBXGroup;
978+
children = (
979+
ACA95D2C275494A100AF4666 /* InboxViewRepresentable.swift */,
980+
);
981+
name = Internal;
982+
sourceTree = "<group>";
983+
};
962984
AC5E888724E1B7AD00752321 /* Request Processing */ = {
963985
isa = PBXGroup;
964986
children = (
@@ -1745,6 +1767,7 @@
17451767
AC942BC62539DEDA002988C9 /* ResourceHelper.swift in Sources */,
17461768
AC4B039622A8743F0043185B /* InAppManager+Functions.swift in Sources */,
17471769
AC72A0D420CF4D19004D7997 /* IterableDeepLinkManager.swift in Sources */,
1770+
ACA95D2F2754AA6800AF4666 /* IterableInboxView.swift in Sources */,
17481771
ACC51A6B22A879070095E81F /* EmptyInAppManager.swift in Sources */,
17491772
AC52C5B62729CE44000DCDCF /* IterableUserDefaults.swift in Sources */,
17501773
ACC362BF24D21192002C67BA /* IterableTaskProcessor.swift in Sources */,
@@ -1761,6 +1784,7 @@
17611784
ACB8273F22372A5C00DB17D3 /* IterableHtmlMessageViewController.swift in Sources */,
17621785
AC5812F624F3A90F007E6D36 /* OfflineRequestProcessor.swift in Sources */,
17631786
AC81918A22713A400014955E /* AbstractDiffCalculator.swift in Sources */,
1787+
ACA95D2D275494A100AF4666 /* InboxViewRepresentable.swift in Sources */,
17641788
AC684A88222F4FDD00F29749 /* InAppDisplayer.swift in Sources */,
17651789
AC72A0D220CF4D12004D7997 /* IterableUtil.swift in Sources */,
17661790
AC32E16821DD55B900BD4F83 /* OrderedDictionary.swift in Sources */,

swift-sdk/IterableInboxViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ open class IterableInboxViewController: UITableViewController {
6060

6161
/// We default, we don't show any message when inbox is empty.
6262
/// If you want to show a message, such as, "There are no messages", you will
63-
/// have to set the `noMessagesTitle` and `noMessagesText` properties below.
63+
/// have to set the `noMessagesTitle` and `noMessagesBody` properties below.
6464

6565
/// Use this to set the title to show when there are no message in the inbox.
6666
@IBInspectable public var noMessagesTitle: String? = nil
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//
2+
// Copyright © 2021 Iterable. All rights reserved.
3+
//
4+
5+
#if canImport(SwiftUI)
6+
7+
import Foundation
8+
import SwiftUI
9+
10+
@available(iOS 13.0, *)
11+
struct InboxViewRepresentable: UIViewControllerRepresentable {
12+
var noMessagesTitle: String?
13+
var noMessagwsBody: String?
14+
var showCountInUnreadBadge = true
15+
var isPopup = true
16+
var cellNibName: String?
17+
var popupModalPresentationStyle: UIModalPresentationStyle?
18+
var viewDelegate: IterableInboxViewControllerViewDelegate?
19+
20+
typealias UIViewControllerType = IterableInboxViewController
21+
22+
func makeUIViewController(context: Context) -> IterableInboxViewController {
23+
let inbox = IterableInboxViewController()
24+
inbox.noMessagesTitle = noMessagesTitle
25+
inbox.noMessagesBody = noMessagwsBody
26+
inbox.showCountInUnreadBadge = showCountInUnreadBadge
27+
inbox.isPopup = isPopup
28+
inbox.cellNibName = cellNibName
29+
inbox.popupModalPresentationStyle = popupModalPresentationStyle
30+
inbox.viewDelegate = viewDelegate
31+
return inbox
32+
}
33+
34+
func updateUIViewController(_ uiViewController: IterableInboxViewController, context: Context) {
35+
}
36+
}
37+
38+
#endif
39+
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
//
2+
// Copyright © 2021 Iterable. All rights reserved.
3+
//
4+
5+
#if canImport(SwiftUI)
6+
7+
import Foundation
8+
import SwiftUI
9+
10+
@available(iOS 13.0, *)
11+
public struct IterableInboxView: View {
12+
public init() {
13+
}
14+
15+
/// We default, we don't show any message when inbox is empty.
16+
/// If you want to show a message, such as, "There are no messages", you will
17+
/// have to set the `noMessagesTitle` and `noMessagesBody` properties below.
18+
19+
/// Use this to set the title to show when there are no message in the inbox.
20+
public func noMessagesTitle(_ value: String) -> IterableInboxView {
21+
var view = self
22+
view.noMessagesTitle = value
23+
return view
24+
}
25+
26+
/// Use this to set the message to show when there are no message in the inbox.
27+
public func noMessagesBody(_ value: String) -> IterableInboxView {
28+
var view = self
29+
view.noMessagesBody = value
30+
return view
31+
}
32+
33+
/// If `true`, the inbox badge will show a number when there are any unread messages in the inbox.
34+
/// If `false` it will simply show an indicator if there are any unread messages in the inbox.
35+
public func showCountInUnreadBadge(_ value: Bool) -> IterableInboxView {
36+
var view = self
37+
view.showCountInUnreadBadge = value
38+
return view
39+
}
40+
41+
/// Set this to `true` to show a popup when an inbox message is selected in the list.
42+
/// Set this to `false`to push inbox message into navigation stack.
43+
public func isPopup(_ value: Bool) -> IterableInboxView {
44+
var view = self
45+
view.isPopup = value
46+
return view
47+
}
48+
49+
/// If you want to use a custom layout for your inbox TableViewCell
50+
/// you should set this. Please note that this assumes
51+
/// that the nib is present in the main bundle.
52+
public func cellNibName(_ value: String) -> IterableInboxView {
53+
var view = self
54+
view.cellNibName = value
55+
return view
56+
}
57+
58+
/// when in popup mode, specify here if you'd like to change the presentation style
59+
public func popupModalPresentationStyle(_ value: UIModalPresentationStyle) -> IterableInboxView {
60+
var view = self
61+
view.popupModalPresentationStyle = value
62+
return view
63+
}
64+
65+
/// Set this property to override default inbox display behavior.
66+
/// Please see `IterableInboxViewControllerViewDelegate` for more details
67+
public func viewDelegate(_ value: IterableInboxViewControllerViewDelegate) -> IterableInboxView {
68+
var view = self
69+
view.viewDelegate = value
70+
return view
71+
}
72+
73+
public var body: some View {
74+
var view = InboxViewRepresentable()
75+
view.noMessagesTitle = noMessagesTitle
76+
view.noMessagwsBody = noMessagesBody
77+
view.showCountInUnreadBadge = showCountInUnreadBadge
78+
view.isPopup = isPopup
79+
view.cellNibName = cellNibName
80+
view.popupModalPresentationStyle = popupModalPresentationStyle
81+
view.viewDelegate = viewDelegate
82+
return view
83+
}
84+
85+
private var noMessagesTitle: String?
86+
private var noMessagesBody: String?
87+
private var showCountInUnreadBadge = true
88+
private var isPopup = true
89+
private var cellNibName: String?
90+
private var popupModalPresentationStyle: UIModalPresentationStyle?
91+
private var viewDelegate: IterableInboxViewControllerViewDelegate?
92+
}
93+
94+
#endif

0 commit comments

Comments
 (0)