Jelajahi Sumber

1.修改iOS Apex CRM推送处理。

Pen Li 7 tahun lalu
induk
melakukan
b33aa6e8b5

+ 8 - 2
RedAnt CRM/APEX CRM/APEX CRM.xcodeproj/project.pbxproj

@@ -37,6 +37,7 @@
 		42201EF322004FA7008AEADE /* NSData+CommonCrypto.m in Sources */ = {isa = PBXBuildFile; fileRef = 42201EEE22004FA7008AEADE /* NSData+CommonCrypto.m */; };
 		42201EF422004FA7008AEADE /* NSData+Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = 42201EEF22004FA7008AEADE /* NSData+Base64.m */; };
 		4232521721C491B600C77851 /* RAContactHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4232521621C491B600C77851 /* RAContactHelper.m */; };
+		4235D18A2201899A00DEB4FB /* CRMRemoteNotificationBroadcast.m in Sources */ = {isa = PBXBuildFile; fileRef = 4235D1892201899A00DEB4FB /* CRMRemoteNotificationBroadcast.m */; };
 		4277784F21AFB98600BCF7FA /* RAMapNavigateHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 4277784E21AFB98600BCF7FA /* RAMapNavigateHandler.m */; };
 		42A8A21321AE7828003B854B /* RAPhotoPreviewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 42A8A20B21AE7828003B854B /* RAPhotoPreviewController.m */; };
 		42A8A21421AE7828003B854B /* PhotoList.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 42A8A20D21AE7828003B854B /* PhotoList.storyboard */; };
@@ -130,6 +131,8 @@
 		42201EEF22004FA7008AEADE /* NSData+Base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+Base64.m"; sourceTree = "<group>"; };
 		4232521521C491B600C77851 /* RAContactHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RAContactHelper.h; sourceTree = "<group>"; };
 		4232521621C491B600C77851 /* RAContactHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RAContactHelper.m; sourceTree = "<group>"; };
+		4235D1882201899A00DEB4FB /* CRMRemoteNotificationBroadcast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CRMRemoteNotificationBroadcast.h; sourceTree = "<group>"; };
+		4235D1892201899A00DEB4FB /* CRMRemoteNotificationBroadcast.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CRMRemoteNotificationBroadcast.m; sourceTree = "<group>"; };
 		4277784D21AFB98600BCF7FA /* RAMapNavigateHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RAMapNavigateHandler.h; sourceTree = "<group>"; };
 		4277784E21AFB98600BCF7FA /* RAMapNavigateHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RAMapNavigateHandler.m; sourceTree = "<group>"; };
 		42A8A20A21AE7828003B854B /* RAPhotoPreviewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RAPhotoPreviewController.h; sourceTree = "<group>"; };
@@ -443,6 +446,8 @@
 				7106E80C21A684F20056DD20 /* ViewController.m */,
 				7106E82421A698D20056DD20 /* RAWKWebView.h */,
 				7106E82521A698D20056DD20 /* RAWKWebView.m */,
+				4235D1882201899A00DEB4FB /* CRMRemoteNotificationBroadcast.h */,
+				4235D1892201899A00DEB4FB /* CRMRemoteNotificationBroadcast.m */,
 				7106E80E21A684F20056DD20 /* Main.storyboard */,
 				7106E81121A684F50056DD20 /* Assets.xcassets */,
 				7106E81321A684F50056DD20 /* LaunchScreen.storyboard */,
@@ -686,6 +691,7 @@
 				42201EF322004FA7008AEADE /* NSData+CommonCrypto.m in Sources */,
 				421F3EB821F9B951001A4BB9 /* RAEmptyDataView.m in Sources */,
 				4212AB9821AD25C800BE4E45 /* RAPreviewController.m in Sources */,
+				4235D18A2201899A00DEB4FB /* CRMRemoteNotificationBroadcast.m in Sources */,
 				42F53F8821B617E4008EAEFC /* SignatureView.m in Sources */,
 				42201EE5220046F9008AEADE /* CRMUser.m in Sources */,
 				4212ABC521AD3C3200BE4E45 /* RADataProvider.m in Sources */,
@@ -910,7 +916,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				DEVELOPMENT_TEAM = HXWLAA5YN5;
 				INFOPLIST_FILE = "APEX CRM/Info.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.1;
+				IPHONEOS_DEPLOYMENT_TARGET = 10.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
@@ -928,7 +934,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				DEVELOPMENT_TEAM = HXWLAA5YN5;
 				INFOPLIST_FILE = "APEX CRM/Info.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.1;
+				IPHONEOS_DEPLOYMENT_TARGET = 10.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",

+ 124 - 1
RedAnt CRM/APEX CRM/APEX CRM/AppDelegate.m

@@ -7,16 +7,41 @@
 //
 
 #import "AppDelegate.h"
+#import <UserNotifications/UserNotifications.h>
+#import "CRMUser.h"
+#import "RADataProvider.h"
+#import "CRMRemoteNotificationBroadcast.h"
 
-@interface AppDelegate ()
+@interface AppDelegate () <UNUserNotificationCenterDelegate>
 
 @end
 
 @implementation AppDelegate
 
+#pragma mark - App State
 
 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
     // Override point for customization after application launch.
+    
+    // register remote notification
+    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
+    UNAuthorizationOptions options = UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge;
+    [center requestAuthorizationWithOptions:options completionHandler:^(BOOL granted, NSError * _Nullable error) {
+        if (granted) {
+            [application registerForRemoteNotifications];
+        } else {
+            
+        }
+    }];
+    center.delegate = self;
+    
+    // 用户点击通知启动应用
+    if (launchOptions && application.applicationState == UIApplicationStateInactive) {
+        NSDictionary *userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
+        if (userInfo) {
+            [self receiveNotification:userInfo];
+        }
+    }
     return YES;
 }
 
@@ -40,6 +65,8 @@
 
 - (void)applicationDidBecomeActive:(UIApplication *)application {
     // 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.
+    
+    [application setApplicationIconBadgeNumber:0];
 }
 
 
@@ -47,5 +74,101 @@
     // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
 }
 
+#pragma mark - Notification
+
+- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
+    NSLog(@"Fail To Register Remote Notification: %@",error);
+}
+
+- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
+    
+    //向APNS注册成功,收到返回的deviceToken
+    NSString *realDeviceToken = [NSString stringWithFormat:@"%@",deviceToken];
+    //去除<>和空格
+    realDeviceToken = [realDeviceToken stringByReplacingOccurrencesOfString:@"<" withString:@""];
+    realDeviceToken = [realDeviceToken stringByReplacingOccurrencesOfString:@">" withString:@""];
+    realDeviceToken = [realDeviceToken stringByReplacingOccurrencesOfString:@" " withString:@""];
+    
+    [CRMUser sharedUser].deviceToken = realDeviceToken;
+    if (CRMUser.sharedUser.shouldUploadToken) {
+        [RADataProvider uploadDeviceToken];
+    }
+}
+
+// 用户点击通知的响应
+- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(nonnull UNNotificationResponse *)response withCompletionHandler:(nonnull void (^)(void))completionHandler {
+    
+    // 用户点击
+    if ([response.actionIdentifier isEqualToString:UNNotificationDefaultActionIdentifier]) {
+        
+        NSDictionary *userInfo = response.notification.request.content.userInfo;
+        [self receiveNotification:userInfo];
+    }
+}
+
+// 前台接收通知
+- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
+    
+    NSDictionary *userInfo = notification.request.content.userInfo;
+    [self showDialogForNotification:userInfo];
+    
+    if (completionHandler) {
+        completionHandler(UNNotificationPresentationOptionNone);
+    }
+}
+
+/*
+content-available = 1
+ 前台收到通知:
+    1. userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:
+    2. application:didReceiveRemoteNotification:fetchCompletionHandler:
+ 后台收到通知:
+    1. application:didReceiveRemoteNotification:fetchCompletionHandler:
+ 
+ content-available = 0
+  前台收到通知:
+    1. userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:
+  后台收到通知:
+    1. 没有任何回调
+ 
+静默通知
+ "content-available": 1,
+ "alert":""
+ 
+*/
+//- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
+//
+//    if ([UIApplication sharedApplication].applicationState == UIApplicationStateInactive) {
+//
+//    } else {
+//
+//    }
+//    if (completionHandler) {
+//        completionHandler(UIBackgroundFetchResultNewData);
+//    }
+//}
+
+#pragma mark - Handle Notification
+
+- (void)showDialogForNotification:(NSDictionary *)userInfo {
+    
+    __weak typeof(self) weakSelf = self;
+    UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"Warning" message:@"you have a message, read it now?" preferredStyle:UIAlertControllerStyleAlert];
+    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        [weakSelf receiveNotification:userInfo];
+    }];
+    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
+        
+    }];
+    
+    [alertVC addAction:cancelAction];
+    [alertVC addAction:okAction];
+    
+    [self.window.rootViewController presentViewController:alertVC animated:YES completion:nil];
+}
+
+- (void)receiveNotification:(NSDictionary *)userInfo {
+    [[NSNotificationCenter defaultCenter] postNotificationName:CRM_REMOTE_NOTIFICATION_RECEVIED object:self userInfo:userInfo];
+}
 
 @end

+ 11 - 0
RedAnt CRM/APEX CRM/APEX CRM/CRMRemoteNotificationBroadcast.h

@@ -0,0 +1,11 @@
+//
+//  CRMRemoteNotificationBroadcast.h
+//  APEX CRM
+//
+//  Created by Jack on 2019/1/30.
+//  Copyright © 2019 USAI. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+FOUNDATION_EXTERN NSString * const CRM_REMOTE_NOTIFICATION_RECEVIED;

+ 11 - 0
RedAnt CRM/APEX CRM/APEX CRM/CRMRemoteNotificationBroadcast.m

@@ -0,0 +1,11 @@
+//
+//  CRMRemoteNotificationBroadcast.m
+//  APEX CRM
+//
+//  Created by Jack on 2019/1/30.
+//  Copyright © 2019 USAI. All rights reserved.
+//
+
+#import "CRMRemoteNotificationBroadcast.h"
+
+NSString * const CRM_REMOTE_NOTIFICATION_RECEVIED = @"CRM_REMOTE_NOTIFICATION_RECEVIED";

+ 3 - 0
RedAnt CRM/APEX CRM/APEX CRM/RAWKWebView.h

@@ -12,6 +12,9 @@
 @class RAWKWebView;
 @protocol RAWebViewDelegate <NSObject>
 
+- (void)webviewDidStarLoading:(RAWKWebView *)webview;
+- (void)webviewDidFinishLoading:(RAWKWebView *)webview error:(NSError *)error;
+
 - (void)webview:(RAWKWebView *)webview didLogin:(NSString *)user password:(NSString *)password;
 - (void)webviewDidLogout:(RAWKWebView *)webview;
 

+ 33 - 1
RedAnt CRM/APEX CRM/APEX CRM/RAWKWebView.m

@@ -101,7 +101,7 @@
     if(self.wkwebView==nil)
         return;
     NSURL* U=[NSURL URLWithString:url];
-    NSURLRequest* request=[[NSURLRequest alloc]initWithURL:U cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30.0f];
+    NSURLRequest* request=[[NSURLRequest alloc]initWithURL:U cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:30.0f];
     
     [self.wkwebView loadRequest:request];
 }
@@ -657,6 +657,18 @@
     return @"";
 }
 
+- (void)ra_injectJS:(NSString *)js {
+    
+//    NSStringEncoding encoding = NSUTF8StringEncoding;
+//    NSString *js = [NSString stringWithContentsOfFile:@"/Users/macmini1/eclipse-workspace/MyWeb/WebContent/JS/Interface.js" usedEncoding:&encoding error:nil];
+    
+    if (js) {
+        [self.wkwebView evaluateJavaScript:js completionHandler:^(id _Nullable result, NSError * _Nullable error) {
+            NSLog(@"create JS %@ Error: %@", result, error);
+        }];
+    }
+}
+
 #pragma mark - Web Callback
 
 -(void) returnToWebPage:(NSDictionary*)params value:(NSObject*)value
@@ -1069,6 +1081,9 @@
     if (self.firstLoad) {
         self.hud = [RAProgressHUD showHUDOnView:self.ra_viewController.view];
     }
+    if (self.delegate && [self.delegate respondsToSelector:@selector(webviewDidStarLoading:)]) {
+        [self.delegate webviewDidStarLoading:self];
+    }
 }
 
 - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
@@ -1079,6 +1094,10 @@
         self.hud = nil;
     }
     
+    if (self.delegate && [self.delegate respondsToSelector:@selector(webviewDidFinishLoading:error:)]) {
+        [self.delegate webviewDidFinishLoading:self error:error];
+    }
+    
 //    NSURL *bundleURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
 //    [webView loadHTMLString:@"<html></html>" baseURL:bundleURL];
     
@@ -1093,6 +1112,10 @@
         self.firstLoad = NO;
     }
     
+    if (self.delegate && [self.delegate respondsToSelector:@selector(webviewDidFinishLoading:error:)]) {
+        [self.delegate webviewDidFinishLoading:self error:nil];
+    }
+    
     //    self.wkwebView.scrollView.scrollEnabled = NO;
     [webView evaluateJavaScript:@"document.body.scrollHeight" completionHandler:^(id result, NSError *_Nullable error) {
         
@@ -1101,6 +1124,15 @@
         //获取后返回重新布局
         
     }];
+    
+//    NSStringEncoding encoding = NSUTF8StringEncoding;
+//    NSString *js = [NSString stringWithContentsOfFile:@"/Users/macmini1/eclipse-workspace/MyWeb/WebContent/JS/Interface.js" usedEncoding:&encoding error:nil];
+//    [self ra_injectJS:js];
+//
+    // css
+    // /Users/macmini1/eclipse-workspace/MyWeb/WebContent/test.css
+//    NSString *cssJs = [NSString stringWithFormat:];
+    
 }
 
 - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {

+ 60 - 42
RedAnt CRM/APEX CRM/APEX CRM/WKWebTestViewController.m

@@ -11,9 +11,13 @@
 #import "CRMUser.h"
 #import "RADataProvider.h"
 #import "NSString+RAJavascript.h"
+#import "CRMRemoteNotificationBroadcast.h"
 
 @interface WKWebTestViewController () <RAWebViewDelegate>
+
 @property (weak, nonatomic) IBOutlet RAWKWebView *webview;
+@property (nonatomic,assign) BOOL loaded;
+@property (nonatomic,assign) NSInteger notificationId;
 
 @end
 
@@ -39,58 +43,26 @@
     self.webview.delegate = self;
     [self.webview LoadFromURL:_url];
     self.webview.JumpTo = ^(NSString* url, NSString* module){
-        
-//        Class class_container =NSClassFromString(module);
         UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:module];
         [vc performSelector:@selector(setUrl:) withObject:url];
-//        [vc performSelector:@selector(setTitle:) withObject:_dataSource[indexPath.row]];
-//        vc.url=@"http://10.0.0.4:8080/backend_test/index.html";
         [self.navigationController pushViewController:vc animated:YES];
     };
-    
-    // Do any additional setup after loading the view.
-    
-//    if(self.webview==nil)
-//    {
-//        WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
-//
-//        WKPreferences *preferences = [WKPreferences new];
-//        preferences.javaScriptCanOpenWindowsAutomatically = YES;
-//        preferences.minimumFontSize = 40.0;
-//        configuration.preferences = preferences;
-//
-//
-//        self.webview = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];
-//
-//        [self.view addSubview:self.webview];
-//    }
-    
-    
-    
-    
-//    NSString *urlStr = [[NSBundle mainBundle] pathForResource:@"index.html" ofType:nil];
-//    NSURL *fileURL = [NSURL fileURLWithPath:urlStr];
-//    NSURL* U=[NSURL URLWithString:@"http://10.0.0.4:8080/backend_test/index.html"];
-//    //    [self.webView loadFileURL:fileURL allowingReadAccessToURL:fileURL];
-//    
-//    NSURLRequest* request=[NSURLRequest requestWithURL:U];
-//    [self.webview loadRequest:request];
+
+    self.notificationId = -1;
+    [self regirsterBroadcast];
 }
-- (void)viewWillAppear:(BOOL)animated
-{
-    
 
+- (void)dealloc {
+    [self unregisterBroadcast];
 }
 
-/*
-#pragma mark - Navigation
+- (void)regirsterBroadcast {
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveBroadCast:) name:CRM_REMOTE_NOTIFICATION_RECEVIED object:nil];
+}
 
-// In a storyboard-based application, you will often want to do a little preparation before navigation
-- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
-    // Get the new view controller using [segue destinationViewController].
-    // Pass the selected object to the new view controller.
+- (void)unregisterBroadcast {
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
 }
-*/
 
 #pragma mark - WebViewDelegate
 
@@ -105,6 +77,21 @@
     [[CRMUser sharedUser] logout];
 }
 
+- (void)webviewDidStarLoading:(RAWKWebView *)webview {
+    @synchronized (self) {
+        self.loaded = NO;
+    }
+}
+
+- (void)webviewDidFinishLoading:(RAWKWebView *)webview error:(NSError *)error {
+    @synchronized (self) {
+        self.loaded = !error;
+        if (self.loaded) {
+            [self readNotificationNow:self.notificationId];
+        }
+    }
+}
+
 #pragma mark - Notification
 
 - (void)handleNotificationByJs:(NSInteger)notificationId {
@@ -122,7 +109,13 @@
     }];
 }
 
+// 当前ViewController是WebVC
 - (void)readNotificationNow:(NSInteger)notificationId {
+    if (notificationId == -1) {
+        return;
+    }
+    self.notificationId = -1;
+    
     if (!CRMUser.sharedUser.isLogin) {
         
         UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"Warning" message:@"you should login first" preferredStyle:UIAlertControllerStyleAlert];
@@ -139,4 +132,29 @@
     [self handleNotificationByJs:notificationId];
 }
 
+- (void)receiveBroadCast:(NSNotification *)notification {
+    
+    if (self.navigationController.presentingViewController) {
+        [self.navigationController.presentingViewController dismissViewControllerAnimated:YES completion:nil];
+    }
+    
+    if (self.navigationController.topViewController != self) {
+        [self.navigationController popToViewController:self animated:YES];
+    }
+    
+    NSDictionary *aps = [notification.userInfo objectForKey:@"aps"];
+    NSInteger notificationId = [[aps objectForKey:@"id"] integerValue];
+    
+    @synchronized (self) {
+        if (self.loaded) {
+            
+            [self readNotificationNow:notificationId];
+            
+        } else {
+            
+            self.notificationId = notificationId;
+        }
+    }
+}
+
 @end