回忆起当初做推送功能的时候,踩过一些坑,也得到了一些经验。总归推送的模块实现按如下步骤来。
1.先确定的推送消息需要跳转的界面。将其写成单独的xib,方便之后present。
2.像苹果申请APNS证书并且将其制作成.p12文件,将其传给极光推送。
3.得到appkey,并且按照JPUSH中的iOS+SDK+Integration+Guide.pdf将极光推送的框架集成进入app代码。
4.服务器根据registrationID来对用户进行分类推送,我们需要处理得到的消息。
5.解析得到的userInfoDic,并跳转到需要显示消息的页面。
得到消息之后,主要需要进行的操作是如何进行跳转。我们需要获取当前显示的vc界面。
方法1.
// 取到tabbarcontroller
TabBarViewController *tabBarController = (TabBarViewController*)self.window.rootViewController;
// 取到navigationcontroller
MyNavigationController * nav = (MyNavigationController*)tabBarController.selectedViewController;
//取到nav控制器当前显示的控制器
UIViewController *baseVC = (UIViewController *)nav.visibleViewController;
[baseVC.navigationController pushViewController:XXVC animated:YES];//PUSH过去
方法2.
- (UIViewController *)getCurrentVC{
UIViewController *result = nil;
UIWindow * window = [[UIApplication sharedApplication] keyWindow];
//app默认windowLevel是UIWindowLevelNormal,如果不是,找到UIWindowLevelNormal的
if (window.windowLevel != UIWindowLevelNormal)
{
NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow * tmpWin in windows)
{
if (tmpWin.windowLevel == UIWindowLevelNormal)
{
window = tmpWin;
break;
}
}
}
id nextResponder = nil;
UIViewController *appRootVC=window.rootViewController;
// 如果是present上来的appRootVC.presentedViewController 不为nil
if (appRootVC.presentedViewController) {
nextResponder = appRootVC.presentedViewController;
}else{
UIView *frontView = [[window subviews] objectAtIndex:0];
nextResponder = [frontView nextResponder];
}
if ([nextResponder isKindOfClass:[UITabBarController class]]){
UITabBarController * tabbar = (UITabBarController *)nextResponder;
UINavigationController * nav = (UINavigationController *)tabbar.viewControllers[tabbar.selectedIndex];
// UINavigationController * nav = tabbar.selectedViewController ; 上下两种写法都行
result=nav.childViewControllers.lastObject;
}else if ([nextResponder isKindOfClass:[UINavigationController class]]){
UIViewController * nav = (UIViewController *)nextResponder;
result = nav.childViewControllers.lastObject;
}else{
result = nextResponder;
}
return result;
}
两个方法均能获取当前最前显示的UIViewController。方法一比较简便但是有内容缺陷。当你的应用处于如游客时没有TabBarViewController,当登陆后present到一个新的TabBarViewController导航控制器,当用户处于任意一个RootViewController时,使用方法一会造成crash。
当iOS推送给你的时候:会主动调用application的代理方法,userInfoDic里就存着远程推送的内容。
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:
(void (^)(UIBackgroundFetchResult))completionHandler {
[JPUSHService handleRemoteNotification:userInfo];
userInfoDic = [[NSDictionary alloc]init];
userInfoDic = userInfo;
completionHandler(UIBackgroundFetchResultNewData);
}
技术外的话:推送功能特别是远程push,并不是即时接受,甚至很久之后才收到这也是正常的。所以尽量能够确定时间的活动,通过利用app内部的json字段来注册本地推送,达到定时的效果。