献给初学iOS的小盆友们——微博app项目开发之九未读数设置以及后台播放
2016-01-26 10:48
597 查看
上节课我们把可以封装的代码都给封装起来了,让对应的控制器的代码也精简了许多,业务逻辑也更明了。今天会新增一些微博功能,里面也包含了代码封装思想。
后台播放
打开后我们可以发现,这个接口不仅可以返回未读微博数据的接口,也返回其它各种消息的未读数,例如新增粉丝,评论数等等。
当看到接口文档所需要的参数之后,我们便知又要建立一个请求参数模型了。因为几乎所有的请求参数模型都会包括access token,所以我们先创建一个只包含access token 的基类参数模型,代码如下:
而且提供一个类方法,让他直接返回基本参数模型,也就是一创建参数模型的时候就给他赋值。
然后我们就可以创建一个专门获取未读数的参数模型YGUnreadMsgParam了,让其继承自YGBaseParam。这样他就有两个参数了,一个是uid,一个是access token。为了让接口返回的结果数据也模型化,我们还要创建一个结果模型YGUnreadResult,代码如下:
这里设计两个方法一个是为了统计显示在消息按钮上的信息个数,一个是显示在应用程序图标上的数字。
仿照AccountTool和StatusTool,我们也可以设计一个工具类YGUnreadTool用来直接获取未读数信息。执行代码如下:
下面我们就可以真正的要把得到的未读数的各种信息显示在tabBar上了,所以自然而然的就要在tabBarController的方法内去实现了。
首先设计一个方法专门用来请求未读数并显示:
细心的同学可能会发现,当我们这样设置完毕后,且在viewDidLoad内调用成功,并不能把总未读数显示在应用图标上。当你打开applcationIconBadgeNumber的头文件时,会看到如下内容:
可以看到,这里要求我们必须注册一个通知用来监听badgeNumber的变化。注册代码写在app Delegate内:
完成注册后,我们又想到,tabbar上的数字是要经常变化的,所以要用NSTimer,使应用每隔一段时间就请求一次。
所以在ViewDidLoad方法内添加如下代码:
最后在首页按钮显示了数字后,当我们点击首页按钮,就会有一个刷新效果,找到之前写的监听tabbar按钮的方法,代码如下:
这里你会很奇怪,为什么还要加上selected Index的判断,因为我们不想从其它控制器,一返回到首页的时候就刷新,而是在选中首页控制器后,再次点击才刷新。然后我们返回到,YGHomeViewController内,添加refresh方法:
**代码勘误:
当我自己敲这节课的代码的时候,却怎么也调试不出显示数字和点击home按钮刷新的效果。
原来我们忘记在下面的方法内
给各种控制器的实例赋值了,所以不能调用其方法。
还有个小错误:在YGStatusResult的头文件内,int total_number 属性中多了一个*。这个错误会导致setValue不成功。
**
所以加上这个代码,项目就能顺利运行啦,如果你隔一会看到类似下图的情况,说明你代码写的很成功了。
程序进入后台的时候会通知appDelegate 的代理方法,所以我们在程序进入后台的时候,就让它调用以下代码:
但是这样的后台程序优先级比较低,为了提高优先级,优先级越低,越容易被系统干掉。所以我们可以欺骗苹果系统,告诉它,程序在后台播放音乐,请不要干掉它,设置后台播放如下图(在项目的capabilities内设置):
但是苹果不是傻子,它会检测到底有没有播放音乐,如果没有播放音乐,程序就会被干掉。所以我们要在在程序即将进入后台的时候,播放音乐,但是播放一个静音几乎为0kb的音乐,且循环播放。
这里player是个局部变量,以上方法一执行完毕,局部变量就会被清空,为了让它一直播放,就咬把局部变量变成成员属性,一直对其进行强引用。如果你想检测到底是否进入后台音乐播放功能,这里提供了一个带有声音的mp3用来替换silence。
好啦,今天的课程就讲到这里,仔细体会这两天的封装内容,有没有一种醍醐灌顶的感觉?
主要内容
获取用户未读数后台播放
本节资料
第九节资料9.1 获取用户未读数
玩过微博的同学应该知道当我们隔一段时间不用微博时,应用会提醒我们有多少条微博未读,并显示在tabbar上以及应用图标上。我们首先查看接口文档,了解下怎么获取这个未读数据。这个接口在提醒接口内,如下图所示:打开后我们可以发现,这个接口不仅可以返回未读微博数据的接口,也返回其它各种消息的未读数,例如新增粉丝,评论数等等。
当看到接口文档所需要的参数之后,我们便知又要建立一个请求参数模型了。因为几乎所有的请求参数模型都会包括access token,所以我们先创建一个只包含access token 的基类参数模型,代码如下:
[code]@property(nonatomic,copy)NSString* access_token; +(instancetype)param;
而且提供一个类方法,让他直接返回基本参数模型,也就是一创建参数模型的时候就给他赋值。
[code]+(instancetype)param { YGBaseParam *param = [[self alloc]init]; param.access_token =[YGAccountTool account].access_token; return param; }
然后我们就可以创建一个专门获取未读数的参数模型YGUnreadMsgParam了,让其继承自YGBaseParam。这样他就有两个参数了,一个是uid,一个是access token。为了让接口返回的结果数据也模型化,我们还要创建一个结果模型YGUnreadResult,代码如下:
[code]//status int 新微博未读数 //follower int 新粉丝数 //cmt int 新评论数 //dm int 新私信数 //mention_status int 新提及我的微博数 //mention_cmt int 新提及我的评论数 //group int 微群消息未读数 //private_group int 私有微群消息未读数 //notice int 新通知未读数 //invite int 新邀请未读数 //badge int 新勋章数 //photo int 相册消息未读数 /** * 新微博未读数 */ @property (nonatomic,assign) int status; /** * 新粉丝数 */ @property (nonatomic,assign) int follower; /** * 新评论数 */ @property (nonatomic,assign) int cmt; /** * 新私信数 */ @property (nonatomic,assign) int dm; /** * 新提及我的微博数 */ @property (nonatomic,assign) int mention_status; /** * 新提及我的评论数 */ @property (nonatomic,assign) int mention_cmt; -(int)messageCount; -(int)totalCount;
这里设计两个方法一个是为了统计显示在消息按钮上的信息个数,一个是显示在应用程序图标上的数字。
[code]-(int)messageCount { return _cmt+_mention_cmt+_mention_status; } -(int)totalCount { return _status+_dm+_follower+_cmt+_mention_cmt+_mention_status; }
仿照AccountTool和StatusTool,我们也可以设计一个工具类YGUnreadTool用来直接获取未读数信息。执行代码如下:
[code]+(void)unreadWithSuccess:(void (^)(YGUnreadResult *))success failure:(void (^)(NSError *))failure { YGUnreadMsgParam *param =[YGUnreadMsgParam param]; param.uid = [YGAccountTool account].uid; [YGHttpTool GET:@"https://rm.api.weibo.com/2/remind/unread_count.json" parameters:param.mj_keyValues success:^(id responseObject) { // 字典转模型 YGUnreadResult *result = [YGUnreadResult mj_objectWithKeyValues:responseObject]; if (success) { success(result); } } failure:^(NSError *error) { failure(error); }]; }
下面我们就可以真正的要把得到的未读数的各种信息显示在tabBar上了,所以自然而然的就要在tabBarController的方法内去实现了。
首先设计一个方法专门用来请求未读数并显示:
[code]#pragma mark 请求未读数 -(void)requestUnread { [YGUnreadTool unreadWithSuccess:^(YGUnreadResult *result) { //设置首页微博未读数 // NSLog(@"this is return result%d",result.status); _home.tabBarItem.badgeValue = [NSString stringWithFormat:@"%d",result.status]; // NSLog(@"this is home badge%@",_home.tabBarItem.badgeValue); //设置消息未读数 _message.tabBarItem.badgeValue = [NSString stringWithFormat:@"%d",result.messageCount]; //设置我的未读数 _profile.tabBarItem.badgeValue = [NSString stringWithFormat:@"%d",result.follower]; // 设置未读数总和 [UIApplication sharedApplication].applicationIconBadgeNumber = result.totalCount; } failure:^(NSError *error) { }]; }
细心的同学可能会发现,当我们这样设置完毕后,且在viewDidLoad内调用成功,并不能把总未读数显示在应用图标上。当你打开applcationIconBadgeNumber的头文件时,会看到如下内容:
可以看到,这里要求我们必须注册一个通知用来监听badgeNumber的变化。注册代码写在app Delegate内:
[code] //注册通知 UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil]; [application registerUserNotificationSettings:setting];
完成注册后,我们又想到,tabbar上的数字是要经常变化的,所以要用NSTimer,使应用每隔一段时间就请求一次。
所以在ViewDidLoad方法内添加如下代码:
[code]// 请求微博未读数 [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(requestUnread) userInfo:nil repeats:YES];
最后在首页按钮显示了数字后,当我们点击首页按钮,就会有一个刷新效果,找到之前写的监听tabbar按钮的方法,代码如下:
[code]#pragma mark - 当点击tabBar上的按钮调用 -(void)tabBar:(YGTabBar *)tabBar didClickButton:(NSInteger)index { if (index ==0&& self.selectedIndex == index) { //点击首页刷新 [_home refresh]; NSLog(@"this is refresh"); } self.selectedIndex = index; }
这里你会很奇怪,为什么还要加上selected Index的判断,因为我们不想从其它控制器,一返回到首页的时候就刷新,而是在选中首页控制器后,再次点击才刷新。然后我们返回到,YGHomeViewController内,添加refresh方法:
[code]#pragma mark refresh -(void)refresh { [self.tableView.mj_header beginRefreshing]; NSLog(@"this is into refresh"); }
**代码勘误:
当我自己敲这节课的代码的时候,却怎么也调试不出显示数字和点击home按钮刷新的效果。
原来我们忘记在下面的方法内
给各种控制器的实例赋值了,所以不能调用其方法。
还有个小错误:在YGStatusResult的头文件内,int total_number 属性中多了一个*。这个错误会导致setValue不成功。
**
所以加上这个代码,项目就能顺利运行啦,如果你隔一会看到类似下图的情况,说明你代码写的很成功了。
9.2 后台请求刷新
可以看到有时候程序只能在前台运行的时候,NSTimer才被调用,当程序进入后台的时候,程序就停止更新微博了。所以我们现在要解决如何在后台也能运行程序。程序进入后台的时候会通知appDelegate 的代理方法,所以我们在程序进入后台的时候,就让它调用以下代码:
[code]//程序进入后台时调用 - (void)applicationDidEnterBackground:(UIApplication *)application { // 开启一个后台任务,时间不确定,优先级比较低,假如系统要关闭应用,首先考虑此task UIBackgroundTaskIdentifier ID = [application beginBackgroundTaskWithExpirationHandler:^{ // 当后台任务结束的时候调用 [application endBackgroundTask:ID]; }]; }
但是这样的后台程序优先级比较低,为了提高优先级,优先级越低,越容易被系统干掉。所以我们可以欺骗苹果系统,告诉它,程序在后台播放音乐,请不要干掉它,设置后台播放如下图(在项目的capabilities内设置):
但是苹果不是傻子,它会检测到底有没有播放音乐,如果没有播放音乐,程序就会被干掉。所以我们要在在程序即将进入后台的时候,播放音乐,但是播放一个静音几乎为0kb的音乐,且循环播放。
[code]- (void)applicationWillResignActive:(UIApplication *)application { NSURL *url = [[NSBundle mainBundle] URLForResource:@"silence.mp3" withExtension:nil]; ***AudioPlayer *player = [[***AudioPlayer alloc] initWithContentsOfURL:url error:nil]; [player prepareToPlay]; // 无限播放 player.numberOfLoops = -1; [player play]; _player = player; }
这里player是个局部变量,以上方法一执行完毕,局部变量就会被清空,为了让它一直播放,就咬把局部变量变成成员属性,一直对其进行强引用。如果你想检测到底是否进入后台音乐播放功能,这里提供了一个带有声音的mp3用来替换silence。
好啦,今天的课程就讲到这里,仔细体会这两天的封装内容,有没有一种醍醐灌顶的感觉?
相关文章推荐
- PHP微信开发代码
- iOS发布app到App Store教程
- Android 接收和收发短信
- Android开发之SoundPool使用具体解释
- admob 广告接入(iOS)
- 2016年2月至3月Android学习计划
- Android美团多渠道打包方式
- android开发中观察者模式的实际应用
- GitHub上史上最全的Android开源项目分类汇总
- AndroidStudio的alt+enter 没有效果 没有解决方案提示
- 最优雅退出 Android 应用程序的 6 种方式
- iOS多线程的基本使用
- Android中View绘制流程以及invalidate()等相关方法分析
- Android Camera开发系列(上)——Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片
- Android Camera开发系列(上)——Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片
- iOS7中的ViewController切换(二.自定义容器控制器动画方式)
- App架构设计经验谈:接口的设计
- iOS输入法开发(Swift)
- android tablayout结合viewpager实现带导航条的滑动页卡
- Android studio 安装篇