@@ -38,7 +38,7 @@ public class WeLoop: NSObject {
3838 private var project : Project ?
3939
4040 /// The current app user. Must be set before the widget can be loaded
41- private var user : User ?
41+ internal var user : User ?
4242
4343 /// A ref to an error that occurred during the authentication. Will be passed down to the delegate the next time `invoke` is called
4444 private var authenticationError : Error ?
@@ -53,6 +53,9 @@ public class WeLoop: NSObject {
5353
5454 /// The preferred invocation method for the SDK. Must be set using `setInvocationMethod`
5555 var invocationMethod : WeLoopInvocation = . manual
56+
57+ /// The time interval between each notification refresh call. Must be set using `setNotificationRefreshInterval`
58+ var refreshInterval : TimeInterval = 30.0
5659
5760 // MARK: Object references
5861
@@ -66,6 +69,9 @@ public class WeLoop: NSObject {
6669 /// A reference to the controller containing the floating action button
6770 private var fabController : FloatingButtonController ?
6871
72+ /// A reference to the polling timer to refresh notifications
73+ private var notificationRefreshTimer : Timer ?
74+
6975 /// A screenshot of the window is taken right before invoking the SDK. This is a ref to this screenshot
7076 var screenshot : UIImage ?
7177
@@ -125,18 +131,26 @@ public class WeLoop: NSObject {
125131 shared. fabController? . updatePosition ( position)
126132 }
127133
134+ /// Set the preferred time interval between two calls to refresh the notifications on the weloop project.
135+ /// You **must** call this before calling `initialize` if you wish to customize this parameter.
136+ ///
137+ /// - Parameter position: the desired time elapsed between each notification refresh
138+ @objc public static func set( notificationRefreshInterval interval: TimeInterval ) {
139+ shared. refreshInterval = interval
140+ }
128141
129142 // MARK: - Internal API
130143
131-
132144 /// Initializer is made private to prevent clients from creating any other instances
133145 private override init ( ) {
134146 super. init ( )
147+
148+ NotificationCenter . default. addObserver ( self , selector: #selector( startNotificationPolling) , name: UIApplication . willEnterForegroundNotification, object: nil )
149+ NotificationCenter . default. addObserver ( self , selector: #selector( stopNotificationPolling) , name: UIApplication . willResignActiveNotification, object: nil )
135150 }
136151
137- var isShowingWidget : Bool {
138- guard let widgetVC = weLoopViewController else { return false }
139- return widgetVC. window. isKeyWindow && previousWindow == nil
152+ deinit {
153+ NotificationCenter . default. removeObserver ( self )
140154 }
141155
142156 func initialize( apiKey: String , autoAuthentication: Bool = true , subdomain: String ? = nil ) {
@@ -152,6 +166,7 @@ public class WeLoop: NSObject {
152166 self . project = project
153167 self . setupInvocation ( settings: project. settings)
154168 try self . initializeWidget ( )
169+ self . startNotificationPolling ( )
155170 self . delegate? . initializationSuccessful ? ( )
156171 } catch ( let error) {
157172 self . authenticationError = error
@@ -162,6 +177,8 @@ public class WeLoop: NSObject {
162177 dataTask? . resume ( )
163178 }
164179
180+ // MARK: Invocation
181+
165182 func set( invocationMethod method: WeLoopInvocation ) {
166183 let oldInvocation = invocationMethod
167184 invocationMethod = method
@@ -178,7 +195,6 @@ public class WeLoop: NSObject {
178195 guard !isShowingWidget else { return }
179196 try showWidget ( )
180197 } catch ( let error) {
181- print ( error)
182198 delegate? . failedToLaunch ? ( with: error)
183199 }
184200 }
@@ -207,6 +223,13 @@ public class WeLoop: NSObject {
207223 }
208224 }
209225
226+ // MARK: Widget
227+
228+ var isShowingWidget : Bool {
229+ guard let widgetVC = weLoopViewController else { return false }
230+ return widgetVC. window. isKeyWindow && previousWindow == nil
231+ }
232+
210233 private func initializeWidget( ) throws {
211234 let url = try widgetURL ( )
212235 let widgetVC = WeLoopViewController ( )
@@ -241,8 +264,7 @@ public class WeLoop: NSObject {
241264
242265 let settingsParams = try project. settings. queryParams ( )
243266
244- var urlString = " \( appURL ( ) ) / \( apiKey) /project/conversations?params= \( settingsParams) "
245-
267+ var urlString = " \( appURL) / \( apiKey) /project/conversations?params= \( settingsParams) "
246268 if autoAuthentication, let user = user {
247269 let userParams = try user. queryParams ( )
248270 urlString. append ( " &auto= \( userParams) " )
@@ -251,6 +273,30 @@ public class WeLoop: NSObject {
251273 }
252274 return URL ( string: urlString) !
253275 }
276+
277+ // MARK: Notification Badge
278+
279+ @objc private func startNotificationPolling( ) {
280+ notificationRefreshTimer? . invalidate ( )
281+ notificationRefreshTimer = Timer ( timeInterval: refreshInterval, target: self , selector: #selector( refreshNotificationBadge) , userInfo: nil , repeats: true )
282+ RunLoop . main. add ( notificationRefreshTimer!, forMode: . default)
283+ }
284+
285+ @objc private func stopNotificationPolling( ) {
286+ notificationRefreshTimer? . invalidate ( )
287+ notificationRefreshTimer = nil
288+ }
289+
290+ @objc func refreshNotificationBadge( ) {
291+ refreshNotificationCount { [ weak self] ( response) in
292+ do {
293+ let notification = try response ( )
294+ self ? . fabController? . setNotificationBadge ( hidden: !notification. isNotif)
295+ } catch let ( error) {
296+ print ( error)
297+ }
298+ }
299+ }
254300}
255301
256302extension WeLoop : ShakeGestureDelegate {
0 commit comments