Discuz iOS应用开发 - bigApp iOS源码分析 - 消息系统

关于站内消息的页面

这个页面的功能,从代码角度上来看,并没有完成。

  • 上图上部4个按钮的操作代码并没有实现。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     - (IBAction)topButtonClick:(id)sender
    {
    if (sender) {
    if (sender == _btn_tiezi || [sender tag] == 1001) {
    //帖子消息
    }
    else if (sender == _btn_tanyou || [sender tag] == 1002) {
    //坛友互动
    }
    else if (sender == _btn_tanyou || [sender tag] == 1003) {
    //系统提醒
    }
    else if (sender == _btn_gonggong || [sender tag] == 1004) {
    //公共消息
    }
    }
    }

相关的实现是空的。

  • badge的变化也没有实现。
    另外有一个名为DialogListViewController的VC,有一部分相关的站内信息的相关操作,包括数据查询以及badge的更新。但这个VC没有任何地方调用。

因为以后需要用JPush来实现消息的推送。所以这一部分需要更多的设计与考虑。

暂时就调查这些。

6.03 更新
来看看网页版的消息界面,有消息,我的帖子,坛友互动,以及系统提醒。

现在的状态是:
手机iOS上的四个按钮:
帖子消息:应该对应我的帖子
坛友互动:对应坛友互动
系统提醒:对应系统提醒。
公共消息:暂时不知道对应哪些。

而手机上TableView显示的消息对应的是论坛的消息。
现在iOS上部4个按钮的功能都无法实现,原因如下:

  1. iOS部分没有实现相关的API去得到这些信息。
  2. BigApp插件也没有提供相应的php api。

消息部分有相关的代码

  1. BigApp插件提供了checknewpm.php API
  2. 对应这个API,iOS实现中有checkNewMessageComeWithResultBlock函数去查询。

该函数仅通知有几个新用户发送消息给你,并不提供有几条新消息发送给你。

需要知道有多少条新消息,需要调用request_DialogListWithResultBlock函数去调用mypm.php去得到所有的消息列表,然后再发现每一个用户发给你的新消息个数。

现在消息更新的机制是这样的
在MainViewController中,定义了一个计时器,每60秒会触发一次,调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (void)doCheckIfHasNewMessage
{
[[Clan_NetAPIManager sharedManager] checkNewMessageComeWithResultBlock:^(id data, NSError *error) {
if (!error) {
NSNumber *results = [data valueForKey:@"newpm"];
if (!isNull(results) && results.intValue >= 1) {
//有新消息
[[NSUserDefaults standardUserDefaults] setObject:results forKey:@"KNEWS_MESSAGE"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"KNEWS_MESSAGE_COME" object:nil];
} else {
//无新消息
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:0] forKey:@"KNEWS_MESSAGE"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"KNEWS_MESSAGE_COME" object:nil];
}
} else {

}
}];
}

消息个数会保存在@”KNEWS_MESSAGE”的键值中。同是发送一个@”KNEWS_MESSAGE_COME”的通知。MainViewController会监听这个通知,并更新Tabbar的Badge标记个数。

当点击用户的消息之后,会弹出用户的消息列表,此时,会更新Discuz数据库,告知该消息被阅读(不知道这一步怎么实现的?),也就是说,下一次消息轮询时,消息的个数变0。然后监听器处罚,然后更新Tabbar的Badge标记个数。

新的方案:
取消定时器的消息轮询,当接到推送时,再去进行消息查询。
因此需要在App打开状态,后台状态以及关闭状态接到推送时,进行消息查询。

通知及监听系统保留,不过直接用直接用request_DialogListWithResultBlock获取新消息个数,Tabbar显示新消息个数。
消息列表中,每个Cell显示当前用户的新消息个数。
当点击Cell是,需要更新当前Cell的新消息个数以及Tabbar的消息个数。

关于JPush的Alias
使用uid作为JPush的Alias,每当用户登录时,设置Alias,具体的在

1
2
3
4
5
6
7
8
9
10
11
12
13
+ (void)saveToLocal
{
NSData *date = [NSKeyedArchiver archivedDataWithRootObject:[UserModel currentUserInfo]];
[[NSUserDefaults standardUserDefaults] setObject:date forKey:kKEY_CURRENT_USER];

if ([UserModel currentUserInfo].logined &&
[UserModel currentUserInfo].uid != nil &&
[[UserModel currentUserInfo].uid isEqualToString:@""]) {
[JPUSHService setAlias:[UserModel currentUserInfo].uid callbackSelector:@selector(tagsAliasCallback:tags:alias:) object:self];
} else {
[JPUSHService setAlias:@"" callbackSelector:@selector(tagsAliasCallback:tags:alias:) object:self];
}
}

大概就是登录状态,设置uid为JPush的alias,否则把Alias设置为空字符串。

关于JPush的Badge
服务器端采用Badge+1策略。
目前涉及到消息和好友邀请两种类型的推送,但JPush仅支持一个总数。因此App Badge显示为两个推送的总和。
站内信Tabbar显示消息的Badge
我的Tabbar显示好友的Badge

当这些消息被阅读后,再重新设置对应的Tabbar的Badge,App的Badge,同是更新JPush的Badge值。

在具体实现的过程中的问题:

  1. Discuz编码和插件编码的问题。一定要统一,我们最终确定用中文简体UTF8。如果混了,或者自己转换过编码,有可能会像我一样遇到各种莫名其妙的问题。

  2. Discuz针对消息,仅能获得有多少个用户向你发送了新消息,而不能获得某一个用户发给你多少条新消息。因此,Badge的显示是一个用户显示为一条新消息 (而不管他发给你多少条新消息)。这就使的Badge+1的策略不能实行。

  3. 之前提到过的,好友邀请的Badge和消息的Badge分开,而JPush仅有一个全局的。

  4. 内部调用Http Request询问多少条新消息,有时会失败。

  5. 因此这个Badge的显示,有时候是不正确的。