您的位置:首页 > 移动开发

献给初学iOS的小盆友们——微博app项目开发之九未读数设置以及后台播放

2016-01-26 10:48 597 查看
上节课我们把可以封装的代码都给封装起来了,让对应的控制器的代码也精简了许多,业务逻辑也更明了。今天会新增一些微博功能,里面也包含了代码封装思想。

主要内容

获取用户未读数

后台播放

本节资料

第九节资料

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。

好啦,今天的课程就讲到这里,仔细体会这两天的封装内容,有没有一种醍醐灌顶的感觉?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: