Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(iOS): Add local and remote notification router #3796

Merged
merged 14 commits into from
Nov 25, 2020
Merged
8 changes: 8 additions & 0 deletions ios/Capacitor/Capacitor.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
objects = {

/* Begin PBXBuildFile section */
373A69C1255C9360000A6F44 /* NotificationHandlerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373A69C0255C9360000A6F44 /* NotificationHandlerProtocol.swift */; };
373A69F2255C95D0000A6F44 /* NotificationRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373A69F1255C95D0000A6F44 /* NotificationRouter.swift */; };
501CBAA71FC0A723009B0D4D /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 501CBAA61FC0A723009B0D4D /* WebKit.framework */; };
50503EE91FC08595003606DC /* Capacitor.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50503EDF1FC08594003606DC /* Capacitor.framework */; };
50503EEE1FC08595003606DC /* CapacitorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50503EED1FC08595003606DC /* CapacitorTests.swift */; };
Expand Down Expand Up @@ -122,6 +124,8 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
373A69C0255C9360000A6F44 /* NotificationHandlerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationHandlerProtocol.swift; sourceTree = "<group>"; };
373A69F1255C95D0000A6F44 /* NotificationRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationRouter.swift; sourceTree = "<group>"; };
501CBAA61FC0A723009B0D4D /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
50503EDF1FC08594003606DC /* Capacitor.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Capacitor.framework; sourceTree = BUILT_PRODUCTS_DIR; };
50503EE81FC08595003606DC /* CapacitorTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CapacitorTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -319,6 +323,8 @@
62959AFE2524DA7700A3D7F1 /* UIStatusBarManager+CAPHandleTapAction.m */,
62959B122524DA7700A3D7F1 /* Info.plist */,
62959B8225253A9500A3D7F1 /* Capacitor.modulemap */,
373A69C0255C9360000A6F44 /* NotificationHandlerProtocol.swift */,
373A69F1255C95D0000A6F44 /* NotificationRouter.swift */,
);
path = Capacitor;
sourceTree = "<group>";
Expand Down Expand Up @@ -557,12 +563,14 @@
62959B472524DA7800A3D7F1 /* CAPNotifications.swift in Sources */,
62959B312524DA7800A3D7F1 /* JS.swift in Sources */,
62959B292524DA7800A3D7F1 /* SplashScreen.swift in Sources */,
373A69F2255C95D0000A6F44 /* NotificationRouter.swift in Sources */,
62959B1A2524DA7800A3D7F1 /* CAPPluginCall.swift in Sources */,
62959B302524DA7800A3D7F1 /* UIStatusBarManager+CAPHandleTapAction.m in Sources */,
62959B392524DA7800A3D7F1 /* CapacitorExtension.swift in Sources */,
62959B3D2524DA7800A3D7F1 /* CAPMessageHandlerWrapper.swift in Sources */,
62959B422524DA7800A3D7F1 /* DocLinks.swift in Sources */,
62959B172524DA7800A3D7F1 /* JSExport.swift in Sources */,
373A69C1255C9360000A6F44 /* NotificationHandlerProtocol.swift in Sources */,
62959B3F2524DA7800A3D7F1 /* CAPAssetHandler.swift in Sources */,
62959B3C2524DA7800A3D7F1 /* CAPBridgeDelegate.swift in Sources */,
62959B2F2524DA7800A3D7F1 /* DefaultPlugins.m in Sources */,
Expand Down
1 change: 1 addition & 0 deletions ios/Capacitor/Capacitor/CAPBridgeProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import WebKit
var viewController: UIViewController? { get }
var config: InstanceConfiguration { get }
var webView: WKWebView? { get }
var notificationRouter: NotificationRouter { get }
var isSimEnvironment: Bool { get }
var isDevEnvironment: Bool { get }
@available(iOS 12.0, *)
Expand Down
1 change: 1 addition & 0 deletions ios/Capacitor/Capacitor/CAPInstanceConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ NS_SWIFT_NAME(InstanceConfiguration)
@property (nonatomic, readonly) BOOL enableLogging;
@property (nonatomic, readonly) BOOL enableScrolling;
@property (nonatomic, readonly) BOOL allowLinkPreviews;
@property (nonatomic, readonly) BOOL handleApplicationNotifications;
@property (nonatomic, readonly) BOOL cordovaDeployDisabled;
@property (nonatomic, readonly) UIScrollViewContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior;
@property (nonatomic, readonly, nonnull) NSURL *appLocation;
Expand Down
1 change: 1 addition & 0 deletions ios/Capacitor/Capacitor/CAPInstanceConfiguration.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ - (instancetype)initWithDescriptor:(CAPInstanceDescriptor *)descriptor {
_enableLogging = descriptor.enableLogging;
_enableScrolling = descriptor.enableScrolling;
_allowLinkPreviews = descriptor.allowLinkPreviews;
_handleApplicationNotifications = descriptor.handleApplicationNotifications;
_contentInsetAdjustmentBehavior = descriptor.contentInsetAdjustmentBehavior;
_appLocation = descriptor.appLocation;
_pluginConfigurations = descriptor.pluginConfigurations;
Expand Down
1 change: 1 addition & 0 deletions ios/Capacitor/Capacitor/CAPInstanceDescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ NS_SWIFT_NAME(InstanceDescriptor)
@property (nonatomic, assign) BOOL enableLogging;
@property (nonatomic, assign) BOOL enableScrolling;
@property (nonatomic, assign) BOOL allowLinkPreviews;
@property (nonatomic, assign) BOOL handleApplicationNotifications;
@property (nonatomic, assign) UIScrollViewContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior;
@property (nonatomic, copy, nonnull) NSURL *appLocation;
@property (nonatomic, copy, nonnull) CDVConfigParser *cordovaConfiguration;
Expand Down
1 change: 1 addition & 0 deletions ios/Capacitor/Capacitor/CAPInstanceDescriptor.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ - (void)_setDefaultsWithAppLocation:(NSURL*)location {
_enableLogging = YES;
_enableScrolling = YES;
_allowLinkPreviews = YES;
_handleApplicationNotifications = YES;
_contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
_appLocation = location;
_cordovaConfiguration = [[CDVConfigParser alloc] init];
Expand Down
4 changes: 4 additions & 0 deletions ios/Capacitor/Capacitor/CapacitorBridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ internal class CapacitorBridge: NSObject, CAPBridgeProtocol {
return bridgeDelegate?.bridgedWebView
}

public var notificationRouter: NotificationRouter

public var isSimEnvironment: Bool {
#if targetEnvironment(simulator)
return true
Expand Down Expand Up @@ -172,6 +174,8 @@ internal class CapacitorBridge: NSObject, CAPBridgeProtocol {
self.messageHandlerWrapper = messageHandlerWrapper
self.config = configuration
self.cordovaParser = cordovaConfiguration
self.notificationRouter = NotificationRouter()
self.notificationRouter.handleApplicationNotifications = configuration.handleApplicationNotifications

super.init()

Expand Down
6 changes: 6 additions & 0 deletions ios/Capacitor/Capacitor/NotificationHandlerProtocol.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Foundation

@objc(CAPNotificationHandlerProtocol) public protocol NotificationHandlerProtocol {
func willPresent(notification: UNNotification) -> UNNotificationPresentationOptions
func didReceive(response: UNNotificationResponse)
}
60 changes: 60 additions & 0 deletions ios/Capacitor/Capacitor/NotificationRouter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import Foundation

@objc(CAPNotificationRouter) public class NotificationRouter: NSObject, UNUserNotificationCenterDelegate {
var handleApplicationNotifications: Bool {
get {
return UNUserNotificationCenter.current().delegate === self
}
set {
let center = UNUserNotificationCenter.current()

if newValue {
center.delegate = self
} else if center.delegate === self {
center.delegate = nil
}
}
}

public weak var pushNotificationHandler: NotificationHandlerProtocol? {
didSet {
if pushNotificationHandler != nil, oldValue != nil {
CAPLog.print("Push notification handler overriding previous instance: \(String(describing: type(of: oldValue)))")
}
}
}

public weak var localNotificationHandler: NotificationHandlerProtocol? {
didSet {
if localNotificationHandler != nil, oldValue != nil {
CAPLog.print("Local notification handler overriding previous instance: \(String(describing: type(of: oldValue)))")
}
}
}

public func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let presentationOptions: UNNotificationPresentationOptions?

if notification.request.trigger?.isKind(of: UNPushNotificationTrigger.self) == true {
presentationOptions = pushNotificationHandler?.willPresent(notification: notification)
} else {
presentationOptions = localNotificationHandler?.willPresent(notification: notification)
}

completionHandler(presentationOptions ?? [])
}

public func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
if response.notification.request.trigger?.isKind(of: UNPushNotificationTrigger.self) == true {
pushNotificationHandler?.didReceive(response: response)
} else {
localNotificationHandler?.didReceive(response: response)
}

completionHandler()
}
}