on master help sign in
Preliminary support for push notifications
e22e06eAli Abrar
jsaddle-wkwebview/cbits-uikit/AppDelegate.m+18−2
@@ -1,12 +1,15 @@
1#import "AppDelegate.h"
1#import "AppDelegate.h"
2#import "ViewController.h"
2#import "ViewController.h"
3+#import <UserNotifications/UserNotifications.h>
3
4
4−@interface AppDelegate ()
5+extern void didRegisterForRemoteNotificationsWithDeviceTokenCallback(HsStablePtr, const char * _Nonnull);
5
6
7+@interface AppDelegate ()
6
8
7@end
9@end
8
10
9HsStablePtr globalHandler = 0;
11HsStablePtr globalHandler = 0;
12+HsStablePtr globalDeviceTokenHook = 0;
10
13
11@implementation AppDelegate
14@implementation AppDelegate
12
15
@@ -16,6 +19,13 @@ HsStablePtr globalHandler = 0;
16 self.window.rootViewController = [[ViewController alloc] initWithHandler:globalHandler];
19 self.window.rootViewController = [[ViewController alloc] initWithHandler:globalHandler];
17 self.window.backgroundColor = [UIColor whiteColor];
20 self.window.backgroundColor = [UIColor whiteColor];
18 [self.window makeKeyAndVisible];
21 [self.window makeKeyAndVisible];
22+ UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
23+ [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound + UNAuthorizationOptionBadge)
24+ completionHandler:^(BOOL granted, NSError * _Nullable error) {
25+ // Handler used to alter application behavior based on types of notifications authorized
26+ // Perhaps we don't need to do anything here.
27+ }];
28+ [application registerForRemoteNotifications];
19 return YES;
29 return YES;
20}
30}
21
31
@@ -45,11 +55,17 @@ HsStablePtr globalHandler = 0;
45 // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
55 // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
46}
56}
47
57
58+- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
59+ NSString *deviceTokenString = [deviceToken base64EncodedStringWithOptions: 0];
60+ didRegisterForRemoteNotificationsWithDeviceTokenCallback(globalDeviceTokenHook, [deviceTokenString UTF8String]);
61+}
62+
48@end
63@end
49
64
50−void runInWKWebView(HsStablePtr handler, const char * _Nonnull progName) {
65+void runInWKWebView(HsStablePtr handler, const char * _Nonnull progName, HsStablePtr deviceTokenHook) {
51 @autoreleasepool {
66 @autoreleasepool {
52 globalHandler = handler;
67 globalHandler = handler;
68+ globalDeviceTokenHook = deviceTokenHook;
53 const char * _Nonnull argv [] = {"", 0};
69 const char * _Nonnull argv [] = {"", 0};
54 UIApplicationMain(0, argv, nil, NSStringFromClass([AppDelegate class]));
70 UIApplicationMain(0, argv, nil, NSStringFromClass([AppDelegate class]));
55 }
71 }
jsaddle-wkwebview/jsaddle-wkwebview.cabal+12−6
@@ -14,6 +14,10 @@ description:
14category: Web, Javascript
14category: Web, Javascript
15author: Hamish Mackenzie
15author: Hamish Mackenzie
16
16
17+flag include-app-delegate
18+ description: Include default AppDelegate C sources.
19+ default: True
20+
17source-repository head
21source-repository head
18 type: git
22 type: git
19 location: https://github.com/ghcjs/jsaddle
23 location: https://github.com/ghcjs/jsaddle
@@ -38,11 +42,13 @@ library
38 else
42 else
39 hs-source-dirs: src-ghc
43 hs-source-dirs: src-ghc
40 if os(ios)
44 if os(ios)
41− frameworks: UIKit
45+ frameworks: UIKit, UserNotifications
46+ if flag(include-app-delegate)
42− c-sources:
47+ c-sources:
43− cbits-uikit/AppDelegate.m
48+ cbits-uikit/AppDelegate.m
44− cbits-uikit/ViewController.m
49+ cbits-uikit/ViewController.m
45 else
50 else
46 frameworks: Cocoa
51 frameworks: Cocoa
52+ if flag(include-app-delegate)
47− c-sources:
53+ c-sources:
48− cbits-cocoa/AppDelegate.m
54+ cbits-cocoa/AppDelegate.m
jsaddle-wkwebview/src-ghc/Language/Javascript/JSaddle/WKWebView.hs+7−4
@@ -10,18 +10,19 @@ module Language.Javascript.JSaddle.WKWebView
10import Data.ByteString (ByteString)
10import Data.ByteString (ByteString)
11import Language.Javascript.JSaddle.WKWebView.Internal (jsaddleMain, jsaddleMainFile, WKWebView(..), mainBundleResourcePath)
11import Language.Javascript.JSaddle.WKWebView.Internal (jsaddleMain, jsaddleMainFile, WKWebView(..), mainBundleResourcePath)
12import System.Environment (getProgName)
12import System.Environment (getProgName)
13−import Foreign.C.String (CString, withCString)
13+import Foreign.C.String (CString, withCString, peekCString)
14import Foreign.StablePtr (StablePtr, newStablePtr)
14import Foreign.StablePtr (StablePtr, newStablePtr)
15import Language.Javascript.JSaddle (JSM)
15import Language.Javascript.JSaddle (JSM)
16
16
17−foreign import ccall runInWKWebView :: StablePtr (WKWebView -> IO ()) -> CString -> IO ()
17+foreign import ccall runInWKWebView :: StablePtr (WKWebView -> IO ()) -> CString -> StablePtr (CString -> IO ()) -> IO ()
18
18
19-- | Run JSaddle in a WKWebView
19-- | Run JSaddle in a WKWebView
20run :: JSM () -> IO ()
20run :: JSM () -> IO ()
21run f = do
21run f = do
22 handler <- newStablePtr (jsaddleMain f)
22 handler <- newStablePtr (jsaddleMain f)
23 progName <- getProgName
23 progName <- getProgName
24+ deviceTokenHandler <- newStablePtr (\s -> putStrLn =<< peekCString s)
24− withCString progName $ runInWKWebView handler
25+ withCString progName $ \pn -> runInWKWebView handler pn deviceTokenHandler
25
26
26-- | Run JSaddle in a WKWebView first loading the specified file
27-- | Run JSaddle in a WKWebView first loading the specified file
27-- from the mainBundle (relative to the resourcePath).
28-- from the mainBundle (relative to the resourcePath).
@@ -31,4 +32,6 @@ runFile :: ByteString -- ^ The file to navigate to.
31runFile url allowing f = do
32runFile url allowing f = do
32 handler <- newStablePtr (jsaddleMainFile url allowing f)
33 handler <- newStablePtr (jsaddleMainFile url allowing f)
33 progName <- getProgName
34 progName <- getProgName
35+ deviceTokenHandler <- newStablePtr (\s -> putStrLn =<< peekCString s)
34− withCString progName $ runInWKWebView handler
36+ withCString progName $ \pn -> runInWKWebView handler pn deviceTokenHandler
37+
jsaddle-wkwebview/src/Language/Javascript/JSaddle/WKWebView/Internal.hs+8
@@ -29,6 +29,7 @@ newtype WKWebView = WKWebView (Ptr WKWebView)
29foreign export ccall jsaddleStart :: StablePtr (IO ()) -> IO ()
29foreign export ccall jsaddleStart :: StablePtr (IO ()) -> IO ()
30foreign export ccall jsaddleResult :: StablePtr (Results -> IO ()) -> CString -> IO ()
30foreign export ccall jsaddleResult :: StablePtr (Results -> IO ()) -> CString -> IO ()
31foreign export ccall withWebView :: WKWebView -> StablePtr (WKWebView -> IO ()) -> IO ()
31foreign export ccall withWebView :: WKWebView -> StablePtr (WKWebView -> IO ()) -> IO ()
32+foreign export ccall didRegisterForRemoteNotificationsWithDeviceTokenCallback :: StablePtr (CString -> IO ()) -> CString -> IO ()
32foreign import ccall addJSaddleHandler :: WKWebView -> StablePtr (IO ()) -> StablePtr (Results -> IO ()) -> IO ()
33foreign import ccall addJSaddleHandler :: WKWebView -> StablePtr (IO ()) -> StablePtr (Results -> IO ()) -> IO ()
33foreign import ccall loadHTMLString :: WKWebView -> CString -> IO ()
34foreign import ccall loadHTMLString :: WKWebView -> CString -> IO ()
34foreign import ccall loadBundleFile :: WKWebView -> CString -> CString -> IO ()
35foreign import ccall loadBundleFile :: WKWebView -> CString -> CString -> IO ()
@@ -85,6 +86,12 @@ withWebView webView ptrF = do
85 f <- deRefStablePtr ptrF
86 f <- deRefStablePtr ptrF
86 f webView
87 f webView
87
88
89+-- | A base64 encoded device token
90+didRegisterForRemoteNotificationsWithDeviceTokenCallback :: StablePtr (CString -> IO ()) -> CString -> IO ()
91+didRegisterForRemoteNotificationsWithDeviceTokenCallback f token = do
92+ f' <- deRefStablePtr f
93+ f' token
94+
88jsaddleJs :: ByteString
95jsaddleJs :: ByteString
89jsaddleJs = ghcjsHelpers <> "\
96jsaddleJs = ghcjsHelpers <> "\
90 \runJSaddleBatch = (function() {\n\
97 \runJSaddleBatch = (function() {\n\
@@ -112,3 +119,4 @@ mainBundleResourcePath = do
112 if bs == nullPtr
119 if bs == nullPtr
113 then return Nothing
120 then return Nothing
114 else Just <$> packCString bs
121 else Just <$> packCString bs
122+