on master help sign in
Add basic AppDelegate callbacks to AppDelegateConfig
a5bfacfAli Abrar
jsaddle-wkwebview/cbits-uikit/AppDelegate.m+47−2
@@ -2,6 +2,7 @@
2#import "ViewController.h"
2#import "ViewController.h"
3#import <UserNotifications/UserNotifications.h>
3#import <UserNotifications/UserNotifications.h>
4
4
5+extern void handlerIO(HsStablePtr);
5extern void handlerCString(const char * _Nonnull, HsStablePtr);
6extern void handlerCString(const char * _Nonnull, HsStablePtr);
6
7
7@interface AppDelegate ()
8@interface AppDelegate ()
@@ -9,6 +10,14 @@ extern void handlerCString(const char * _Nonnull, HsStablePtr);
9@end
10@end
10
11
11HsStablePtr globalHandler = 0;
12HsStablePtr globalHandler = 0;
13+HsStablePtr global_willFinishLaunchingWithOptions = 0;
14+HsStablePtr global_didFinishLaunchingWithOptions = 0;
15+HsStablePtr global_applicationDidBecomeActive = 0;
16+HsStablePtr global_applicationWillResignActive = 0;
17+HsStablePtr global_applicationDidEnterBackground = 0;
18+HsStablePtr global_applicationWillEnterForeground = 0;
19+HsStablePtr global_applicationWillTerminate = 0;
20+HsStablePtr global_applicationSignificantTimeChange = 0;
12BOOL global_requestAuthorizationWithOptions = NO;
21BOOL global_requestAuthorizationWithOptions = NO;
13BOOL global_requestAuthorizationOptionBadge = NO;
22BOOL global_requestAuthorizationOptionBadge = NO;
14BOOL global_requestAuthorizationOptionSound = NO;
23BOOL global_requestAuthorizationOptionSound = NO;
@@ -20,7 +29,14 @@ HsStablePtr global_didFailToRegisterForRemoteNotificationsWithError = 0;
20
29
21@implementation AppDelegate
30@implementation AppDelegate
22
31
32+- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
33+ // Tells the delegate that the launch process has begun but that state restoration has not yet occurred.
34+ handlerIO(global_willFinishLaunchingWithOptions);
35+ return YES;
36+}
37+
23- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
38- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
39+ // Tells the delegate that the launch process is almost done and the app is almost ready to run.
24 self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
40 self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
25 // Override point for customization after application launch.
41 // Override point for customization after application launch.
26 self.window.rootViewController = [[ViewController alloc] initWithHandler:globalHandler];
42 self.window.rootViewController = [[ViewController alloc] initWithHandler:globalHandler];
@@ -49,49 +65,70 @@ HsStablePtr global_didFailToRegisterForRemoteNotificationsWithError = 0;
49 if (global_registerForRemoteNotifications) {
65 if (global_registerForRemoteNotifications) {
50 [application registerForRemoteNotifications];
66 [application registerForRemoteNotifications];
51 }
67 }
68+ handlerIO(global_didFinishLaunchingWithOptions);
52 return YES;
69 return YES;
53}
70}
54
71
55- (void)applicationWillResignActive:(UIApplication *)application {
72- (void)applicationWillResignActive:(UIApplication *)application {
56 // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
73 // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
57 // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
74 // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
75+ handlerIO(global_applicationWillResignActive);
58}
76}
59
77
60
78
61- (void)applicationDidEnterBackground:(UIApplication *)application {
79- (void)applicationDidEnterBackground:(UIApplication *)application {
62 // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
80 // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
63 // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
81 // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
82+ handlerIO(global_applicationDidEnterBackground);
64}
83}
65
84
66
85
67- (void)applicationWillEnterForeground:(UIApplication *)application {
86- (void)applicationWillEnterForeground:(UIApplication *)application {
68 // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
87 // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
88+ handlerIO(global_applicationWillEnterForeground);
69}
89}
70
90
71
91
72- (void)applicationDidBecomeActive:(UIApplication *)application {
92- (void)applicationDidBecomeActive:(UIApplication *)application {
73 // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
93 // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
94+ handlerIO(global_applicationDidBecomeActive);
74}
95}
75
96
76
97
77- (void)applicationWillTerminate:(UIApplication *)application {
98- (void)applicationWillTerminate:(UIApplication *)application {
78 // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
99 // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
100+ handlerIO(global_applicationWillTerminate);
79}
101}
80
102
81- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
103- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
104+ // Tells the delegate that the app successfully registered with Apple Push Notification service (APNs).
82 NSString *deviceTokenString = [deviceToken base64EncodedStringWithOptions: 0];
105 NSString *deviceTokenString = [deviceToken base64EncodedStringWithOptions: 0];
83 handlerCString([deviceTokenString UTF8String], global_didRegisterForRemoteNotificationsWithDeviceToken);
106 handlerCString([deviceTokenString UTF8String], global_didRegisterForRemoteNotificationsWithDeviceToken);
84}
107}
85
108
86- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
109- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
110+ // Sent to the delegate when Apple Push Notification service cannot successfully complete the registration process.
87− NSString *errorString = [error localizedDescription];
111+ NSString *errorString = [error localizedDescription];
88− handlerCString([errorString UTF8String], global_didFailToRegisterForRemoteNotificationsWithError);
112+ handlerCString([errorString UTF8String], global_didFailToRegisterForRemoteNotificationsWithError);
113+}
114+
115+- (void)applicationSignificantTimeChange:(UIApplication *)application {
116+ // Tells the delegate when there is a significant change in the time.
117+ handlerIO(global_applicationSignificantTimeChange);
89}
118}
90
119
91@end
120@end
92
121
93void runInWKWebView(HsStablePtr handler,
122void runInWKWebView(HsStablePtr handler,
94 const char * _Nonnull progName,
123 const char * _Nonnull progName,
124+ HsStablePtr hs_willFinishLaunchingWithOptions,
125+ HsStablePtr hs_didFinishLaunchingWithOptions,
126+ HsStablePtr hs_applicationDidBecomeActive,
127+ HsStablePtr hs_applicationWillResignActive,
128+ HsStablePtr hs_applicationDidEnterBackground,
129+ HsStablePtr hs_applicationWillEnterForeground,
130+ HsStablePtr hs_applicationWillTerminate,
131+ HsStablePtr hs_applicationSignificantTimeChange,
95 const BOOL hs_requestAuthorizationWithOptions,
132 const BOOL hs_requestAuthorizationWithOptions,
96 const BOOL hs_requestAuthorizationOptionBadge,
133 const BOOL hs_requestAuthorizationOptionBadge,
97 const BOOL hs_requestAuthorizationOptionSound,
134 const BOOL hs_requestAuthorizationOptionSound,
@@ -102,6 +139,14 @@ void runInWKWebView(HsStablePtr handler,
102 HsStablePtr hs_didFailToRegisterForRemoteNotificationsWithError) {
139 HsStablePtr hs_didFailToRegisterForRemoteNotificationsWithError) {
103 @autoreleasepool {
140 @autoreleasepool {
104 globalHandler = handler;
141 globalHandler = handler;
142+ global_willFinishLaunchingWithOptions = hs_willFinishLaunchingWithOptions;
143+ global_didFinishLaunchingWithOptions = hs_didFinishLaunchingWithOptions;
144+ global_applicationDidBecomeActive = hs_applicationDidBecomeActive;
145+ global_applicationWillResignActive = hs_applicationWillResignActive;
146+ global_applicationDidEnterBackground = hs_applicationDidEnterBackground;
147+ global_applicationWillEnterForeground = hs_applicationWillEnterForeground;
148+ global_applicationWillTerminate = hs_applicationWillTerminate;
149+ global_applicationSignificantTimeChange = hs_applicationSignificantTimeChange;
105 global_requestAuthorizationWithOptions = hs_requestAuthorizationWithOptions;
150 global_requestAuthorizationWithOptions = hs_requestAuthorizationWithOptions;
106 global_requestAuthorizationOptionBadge = hs_requestAuthorizationOptionBadge;
151 global_requestAuthorizationOptionBadge = hs_requestAuthorizationOptionBadge;
107 global_requestAuthorizationOptionSound = hs_requestAuthorizationOptionSound;
152 global_requestAuthorizationOptionSound = hs_requestAuthorizationOptionSound;
jsaddle-wkwebview/src-ghc/Language/Javascript/JSaddle/WKWebView.hs+51−8
@@ -24,6 +24,14 @@ import Language.Javascript.JSaddle (JSM)
24foreign import ccall runInWKWebView
24foreign import ccall runInWKWebView
25 :: StablePtr (WKWebView -> IO ())
25 :: StablePtr (WKWebView -> IO ())
26 -> CString
26 -> CString
27+ -> StablePtr (IO ()) -- willFinishLaunchingWithOptions
28+ -> StablePtr (IO ()) -- didFinishLaunchingWithOptions
29+ -> StablePtr (IO ()) -- applicationDidBecomeActive
30+ -> StablePtr (IO ()) -- applicationWillResignActive
31+ -> StablePtr (IO ()) -- applicationDidEnterBackground
32+ -> StablePtr (IO ()) -- applicationWillEnterForeground
33+ -> StablePtr (IO ()) -- applicationWillTerminate
34+ -> StablePtr (IO ()) -- applicationSignificantTimeChange
27 -> CChar -- whether to run requestAuthorizationWithOptions
35 -> CChar -- whether to run requestAuthorizationWithOptions
28 -> CChar -- Ask for Badge authorization
36 -> CChar -- Ask for Badge authorization
29 -> CChar -- Ask for Sound authorization
37 -> CChar -- Ask for Sound authorization
@@ -34,14 +42,29 @@ foreign import ccall runInWKWebView
34 -> StablePtr (CString -> IO ()) -- didFailToRegisterForRemoteNotificationsWithError
42 -> StablePtr (CString -> IO ()) -- didFailToRegisterForRemoteNotificationsWithError
35 -> IO ()
43 -> IO ()
36
44
37−
38data AppDelegateConfig = AppDelegateConfig
45data AppDelegateConfig = AppDelegateConfig
46+ { _appDelegateConfig_willFinishLaunchingWithOptions :: IO ()
47+ , _appDelegateConfig_didFinishLaunchingWithOptions :: IO ()
48+ , _appDelegateConfig_applicationDidBecomeActive :: IO ()
49+ , _appDelegateConfig_applicationWillResignActive :: IO ()
50+ , _appDelegateConfig_applicationDidEnterBackground :: IO ()
51+ , _appDelegateConfig_applicationWillEnterForeground :: IO ()
52+ , _appDelegateConfig_applicationWillTerminate :: IO ()
53+ , _appDelegateConfig_applicationSignificantTimeChange :: IO ()
39− { _appDelegateConfig_appDelegateNotificationConfig :: AppDelegateNotificationConfig
54+ , _appDelegateConfig_appDelegateNotificationConfig :: AppDelegateNotificationConfig
40 }
55 }
41
56
42instance Default AppDelegateConfig where
57instance Default AppDelegateConfig where
43 def = AppDelegateConfig
58 def = AppDelegateConfig
59+ { _appDelegateConfig_willFinishLaunchingWithOptions = return ()
60+ , _appDelegateConfig_didFinishLaunchingWithOptions = return ()
61+ , _appDelegateConfig_applicationDidBecomeActive = return ()
62+ , _appDelegateConfig_applicationWillResignActive = return ()
63+ , _appDelegateConfig_applicationDidEnterBackground = return ()
64+ , _appDelegateConfig_applicationWillEnterForeground = return ()
65+ , _appDelegateConfig_applicationWillTerminate = return ()
66+ , _appDelegateConfig_applicationSignificantTimeChange = return ()
44− { _appDelegateConfig_appDelegateNotificationConfig = def
67+ , _appDelegateConfig_appDelegateNotificationConfig = def
45 }
68 }
46
69
47data AuthorizationOption = AuthorizationOption_Badge
70data AuthorizationOption = AuthorizationOption_Badge
@@ -59,11 +82,11 @@ data AppDelegateNotificationConfig = AppDelegateNotificationConfig
59
82
60instance Default AppDelegateNotificationConfig where
83instance Default AppDelegateNotificationConfig where
61 def = AppDelegateNotificationConfig
84 def = AppDelegateNotificationConfig
62− { _appDelegateNotificationConfig_requestAuthorizationWithOptions = Nothing
85+ { _appDelegateNotificationConfig_requestAuthorizationWithOptions = Nothing
63− , _appDelegateNotificationConfig_registerForRemoteNotifications = False
86+ , _appDelegateNotificationConfig_registerForRemoteNotifications = False
64− , _appDelegateNotificationConfig_didRegisterForRemoteNotificationsWithDeviceToken = \_ -> return ()
87+ , _appDelegateNotificationConfig_didRegisterForRemoteNotificationsWithDeviceToken = \_ -> return ()
65− , _appDelegateNotificationConfig_didFailToRegisterForRemoteNotificationsWithError = \_ -> return ()
88+ , _appDelegateNotificationConfig_didFailToRegisterForRemoteNotificationsWithError = \_ -> return ()
66− }
89+ }
67
90
68
91
69-- | Run JSaddle in a WKWebView
92-- | Run JSaddle in a WKWebView
@@ -88,6 +111,18 @@ run' mUrl cfg f = do
88 Just (url, allowing) -> newStablePtr (jsaddleMainFile url allowing f)
111 Just (url, allowing) -> newStablePtr (jsaddleMainFile url allowing f)
89 Nothing -> newStablePtr (jsaddleMain f)
112 Nothing -> newStablePtr (jsaddleMain f)
90 progName <- getProgName
113 progName <- getProgName
114+
115+ -- AppDelegate callbacks
116+ willFinishLaunchingWithOptions <- newStablePtr $ _appDelegateConfig_willFinishLaunchingWithOptions cfg
117+ didFinishLaunchingWithOptions <- newStablePtr $ _appDelegateConfig_didFinishLaunchingWithOptions cfg
118+ applicationDidBecomeActive <- newStablePtr $ _appDelegateConfig_applicationDidBecomeActive cfg
119+ applicationWillResignActive <- newStablePtr $ _appDelegateConfig_applicationWillResignActive cfg
120+ applicationDidEnterBackground <- newStablePtr $ _appDelegateConfig_applicationDidEnterBackground cfg
121+ applicationWillEnterForeground <- newStablePtr $ _appDelegateConfig_applicationWillEnterForeground cfg
122+ applicationWillTerminate <- newStablePtr $ _appDelegateConfig_applicationWillTerminate cfg
123+ applicationSignificantTimeChange <- newStablePtr $ _appDelegateConfig_applicationSignificantTimeChange cfg
124+
125+ -- AppDelegate notification configuration
91 let ncfg = _appDelegateConfig_appDelegateNotificationConfig cfg
126 let ncfg = _appDelegateConfig_appDelegateNotificationConfig cfg
92 (requestAuthorizationWithOptions, authorizationOptions) =
127 (requestAuthorizationWithOptions, authorizationOptions) =
93 case _appDelegateNotificationConfig_requestAuthorizationWithOptions ncfg of
128 case _appDelegateNotificationConfig_requestAuthorizationWithOptions ncfg of
@@ -99,6 +134,14 @@ run' mUrl cfg f = do
99 withCString progName $ \pn -> runInWKWebView
134 withCString progName $ \pn -> runInWKWebView
100 handler
135 handler
101 pn
136 pn
137+ willFinishLaunchingWithOptions
138+ didFinishLaunchingWithOptions
139+ applicationDidBecomeActive
140+ applicationWillResignActive
141+ applicationDidEnterBackground
142+ applicationWillEnterForeground
143+ applicationWillTerminate
144+ applicationSignificantTimeChange
102 (boolToCChar requestAuthorizationWithOptions)
145 (boolToCChar requestAuthorizationWithOptions)
103 (boolToCChar $ Set.member AuthorizationOption_Badge authorizationOptions)
146 (boolToCChar $ Set.member AuthorizationOption_Badge authorizationOptions)
104 (boolToCChar $ Set.member AuthorizationOption_Sound authorizationOptions)
147 (boolToCChar $ Set.member AuthorizationOption_Sound authorizationOptions)
jsaddle-wkwebview/src/Language/Javascript/JSaddle/WKWebView/Internal.hs+8−2
@@ -33,6 +33,7 @@ foreign export ccall jsaddleStart :: StablePtr (IO ()) -> IO ()
33foreign export ccall jsaddleResult :: StablePtr (Results -> IO ()) -> CString -> IO ()
33foreign export ccall jsaddleResult :: StablePtr (Results -> IO ()) -> CString -> IO ()
34foreign export ccall withWebView :: WKWebView -> StablePtr (WKWebView -> IO ()) -> IO ()
34foreign export ccall withWebView :: WKWebView -> StablePtr (WKWebView -> IO ()) -> IO ()
35foreign export ccall handlerCString :: CString -> StablePtr (CString -> IO ()) -> IO ()
35foreign export ccall handlerCString :: CString -> StablePtr (CString -> IO ()) -> IO ()
36+foreign export ccall handlerIO :: StablePtr (IO ()) -> IO ()
36foreign import ccall addJSaddleHandler :: WKWebView -> StablePtr (IO ()) -> StablePtr (Results -> IO ()) -> IO ()
37foreign import ccall addJSaddleHandler :: WKWebView -> StablePtr (IO ()) -> StablePtr (Results -> IO ()) -> IO ()
37foreign import ccall loadHTMLString :: WKWebView -> CString -> IO ()
38foreign import ccall loadHTMLString :: WKWebView -> CString -> IO ()
38foreign import ccall loadBundleFile :: WKWebView -> CString -> CString -> IO ()
39foreign import ccall loadBundleFile :: WKWebView -> CString -> CString -> IO ()
@@ -91,8 +92,13 @@ withWebView webView ptrF = do
91
92
92handlerCString :: CString -> StablePtr (CString -> IO ()) -> IO ()
93handlerCString :: CString -> StablePtr (CString -> IO ()) -> IO ()
93handlerCString c fptr = do
94handlerCString c fptr = do
94− f <- deRefStablePtr fptr
95+ f <- deRefStablePtr fptr
95− f c
96+ f c
97+
98+handlerIO :: StablePtr (IO ()) -> IO ()
99+handlerIO ptr = do
100+ f <- deRefStablePtr ptr
101+ f
96
102
97boolToCChar :: Bool -> CChar
103boolToCChar :: Bool -> CChar
98boolToCChar a = if a then 1 else 0
104boolToCChar a = if a then 1 else 0