Initial commit

This commit is contained in:
ifish
2017-08-15 16:59:01 +08:00
commit bdc83e07ef
5766 changed files with 423223 additions and 0 deletions
@@ -0,0 +1,23 @@
//
// NTESCustomSysNotiSender.h
// NIM
//
// Created by chris on 15/5/26.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import <Foundation/Foundation.h>
#define NTESNotifyID @"id"
#define NTESCustomContent @"content"
#define NTESCommandTyping (1)
#define NTESCustom (2)
@interface NTESCustomSysNotificationSender : NSObject
- (void)sendCustomContent:(NSString *)content toSession:(NIMSession *)session;
- (void)sendTypingState:(NIMSession *)session;
@end
@@ -0,0 +1,77 @@
//
// NTESCustomSysNotiSender.m
// NIM
//
// Created by chris on 15/5/26.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import "NTESCustomSysNotificationSender.h"
@interface NTESCustomSysNotificationSender ()
@property (nonatomic,strong) NSDate *lastTime;
@end
@implementation NTESCustomSysNotificationSender
- (void)sendCustomContent:(NSString *)content toSession:(NIMSession *)session{
if (!content) {
return;
}
NSDictionary *dict = @{
NTESNotifyID : @(NTESCustom),
NTESCustomContent : content,
};
NSData *data = [NSJSONSerialization dataWithJSONObject:dict
options:0
error:nil];
NSString *json = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NIMCustomSystemNotification *notification = [[NIMCustomSystemNotification alloc] initWithContent:json];
notification.apnsContent = content;
notification.sendToOnlineUsersOnly = NO;
NIMCustomSystemNotificationSetting *setting = [[NIMCustomSystemNotificationSetting alloc] init];
setting.apnsEnabled = YES;
notification.setting = setting;
[[[NIMSDK sharedSDK] systemNotificationManager] sendCustomNotification:notification
toSession:session
completion:nil];
}
- (void)sendTypingState:(NIMSession *)session
{
NSString *currentAccount = [[[NIMSDK sharedSDK] loginManager] currentAccount];
if (session.sessionType != NIMSessionTypeP2P ||
[session.sessionId isEqualToString:currentAccount])
{
return;
}
NSDate *now = [NSDate date];
if (_lastTime == nil ||
[now timeIntervalSinceDate:_lastTime] > 3)
{
_lastTime = now;
NSDictionary *dict = @{NTESNotifyID : @(NTESCommandTyping)};
NSData *data = [NSJSONSerialization dataWithJSONObject:dict
options:0
error:nil];
NSString *content = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NIMCustomSystemNotification *notification = [[NIMCustomSystemNotification alloc] initWithContent:content];
notification.sendToOnlineUsersOnly = YES;
NIMCustomSystemNotificationSetting *setting = [[NIMCustomSystemNotificationSetting alloc] init];
setting.apnsEnabled = NO;
notification.setting = setting;
[[[NIMSDK sharedSDK] systemNotificationManager] sendCustomNotification:notification
toSession:session
completion:nil];
}
}
@end
@@ -0,0 +1,15 @@
//
// NTESContactDataMember.h
// NIM
//
// Created by chris on 15/9/21.
// Copyright © 2015年 Netease. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NTESContactDataMember : NSObject
@property (nonatomic,strong) NIMKitInfo *info;
@end
@@ -0,0 +1,82 @@
//
// NTESContactDataMember.m
// NIM
//
// Created by chris on 15/9/21.
// Copyright © 2015年 Netease. All rights reserved.
//
#import "NTESContactDataMember.h"
#import "NTESSpellingCenter.h"
@implementation NTESContactDataMember
- (CGFloat)uiHeight{
return 50;
}
//userId和Vcname必有一个有值,根据有值的状态push进不同的页面
- (NSString *)vcName{
return nil;
}
- (NSString *)reuseId{
return @"NTESContactDataItem";
}
- (NSString *)cellName{
return @"NIMContactDataCell";
}
- (NSString *)badge{
return @"";
}
- (NSString *)groupTitle {
NSString *title = [[NTESSpellingCenter sharedCenter] firstLetter:self.info.showName].capitalizedString;
unichar character = [title characterAtIndex:0];
if (character >= 'A' && character <= 'Z') {
return title;
}else{
return @"#";
}
}
- (NSString *)userId{
return self.info.infoId;
}
- (UIImage *)icon{
return self.info.avatarImage;
}
- (NSString *)avatarUrl{
return self.info.avatarUrlString;
}
- (NSString *)memberId{
return self.info.infoId;
}
- (NSString *)showName{
return self.info.showName;
}
- (BOOL)showAccessoryView{
return NO;
}
- (id)sortKey {
return [[NTESSpellingCenter sharedCenter] spellingForString:self.info.showName].shortSpelling;
}
- (BOOL)isEqual:(id)object{
if (![object isKindOfClass:[self class]]) {
return NO;
}
return [self.info.infoId isEqualToString:[[object info] infoId]];
}
@end
@@ -0,0 +1,15 @@
//
// NTESGroupedContacts.h
// NIM
//
// Created by Xuhui on 15/3/2.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import "NTESGroupedDataCollection.h"
@class NTESContactsManager;
@interface NTESGroupedContacts : NTESGroupedDataCollection
@end
@@ -0,0 +1,51 @@
//
// NTESGroupedContacts.m
// NIM
//
// Created by Xuhui on 15/3/2.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import "NTESGroupedContacts.h"
#import "NTESContactDataMember.h"
@interface NTESGroupedContacts ()
@end
@implementation NTESGroupedContacts
- (instancetype)init
{
self = [super init];
if(self) {
self.groupTitleComparator = ^NSComparisonResult(NSString *title1, NSString *title2) {
if ([title1 isEqualToString:@"#"]) {
return NSOrderedDescending;
}
if ([title2 isEqualToString:@"#"]) {
return NSOrderedAscending;
}
return [title1 compare:title2];
};
self.groupMemberComparator = ^NSComparisonResult(NSString *key1, NSString *key2) {
return [key1 compare:key2];
};
[self update];
}
return self;
}
- (void)update{
NSMutableArray *contacts = [NSMutableArray array];
for (NIMUser *user in [NIMSDK sharedSDK].userManager.myFriends) {
NIMKitInfo *info = [[NIMKit sharedKit] infoByUser:user.userId];
NTESContactDataMember *contact = [[NTESContactDataMember alloc] init];
contact.info = info;
[contacts addObject:contact];
}
[self setMembers:contacts];
}
@end
@@ -0,0 +1,44 @@
//
// NTESGroupedDataCollection.h
// NIM
//
// Created by Xuhui on 15/3/2.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import <Foundation/Foundation.h>
@protocol NTESGroupMemberProtocol <NSObject>
- (NSString *)groupTitle;
- (NSString *)memberId;
- (id)sortKey;
@end
@interface NTESGroupedDataCollection : NSObject
@property (nonatomic, strong) NSArray *members;
@property (nonatomic, copy) NSComparator groupTitleComparator;
@property (nonatomic, copy) NSComparator groupMemberComparator;
@property (nonatomic, readonly) NSArray *sortedGroupTitles;
- (void)addGroupMember:(id<NTESGroupMemberProtocol>)member;
- (void)removeGroupMember:(id<NTESGroupMemberProtocol>)member;
- (void)addGroupAboveWithTitle:(NSString *)title members:(NSArray *)members;
- (NSString *)titleOfGroup:(NSInteger)groupIndex;
- (NSArray *)membersOfGroup:(NSInteger)groupIndex;
- (id<NTESGroupMemberProtocol>)memberOfIndex:(NSIndexPath *)indexPath;
- (id<NTESGroupMemberProtocol>)memberOfId:(NSString *)uid;
- (NSInteger)groupCount;
- (NSInteger)memberCountOfGroup:(NSInteger)groupIndex;
@end
@@ -0,0 +1,237 @@
//
// NTESGroupedDataCollection.m
// NIM
//
// Created by Xuhui on 15/3/2.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import "NTESGroupedDataCollection.h"
@interface Pair : NSObject
@property (nonatomic, strong) id first;
@property (nonatomic, strong) id second;
@end
@implementation Pair
- (instancetype)initWithFirst:(id)first second:(id)second {
self = [super init];
if(self) {
_first = first;
_second = second;
}
return self;
}
@end
@interface NTESGroupedDataCollection () {
NSMutableOrderedSet *_specialGroupTtiles;
NSMutableOrderedSet *_specialGroups;
NSMutableOrderedSet *_groupTtiles;
NSMutableOrderedSet *_groups;
}
@end
@implementation NTESGroupedDataCollection
- (instancetype)init
{
self = [super init];
if(self) {
_specialGroupTtiles = [[NSMutableOrderedSet alloc] init];
_specialGroups = [[NSMutableOrderedSet alloc] init];
_groupTtiles = [[NSMutableOrderedSet alloc] init];
_groups = [[NSMutableOrderedSet alloc] init];
}
return self;
}
- (NSArray *)sortedGroupTitles
{
return [_groupTtiles array];
}
- (void)setMembers:(NSArray *)members
{
NSMutableDictionary *tmp = [NSMutableDictionary dictionary];
NSString *me = [[NIMSDK sharedSDK].loginManager currentAccount];
for (id<NTESGroupMemberProtocol>member in members) {
if ([[member memberId] isEqualToString:me]) {
continue;
}
NSString *groupTitle = [member groupTitle];
NSMutableArray *groupedMembers = [tmp objectForKey:groupTitle];
if(!groupedMembers) {
groupedMembers = [NSMutableArray array];
}
[groupedMembers addObject:member];
[tmp setObject:groupedMembers forKey:groupTitle];
}
[_groupTtiles removeAllObjects];
[_groups removeAllObjects];
[tmp enumerateKeysAndObjectsUsingBlock:^(NSString *groupTitle, NSMutableArray *groupedMembers, BOOL *stop) {
if (groupTitle.length) {
unichar character = [groupTitle characterAtIndex:0];
if (character >= 'A' && character <= 'Z') {
[_groupTtiles addObject:groupTitle];
}else{
[_groupTtiles addObject:@"#"];
}
[_groups addObject:[[Pair alloc] initWithFirst:groupTitle second:groupedMembers]];
}
}];
[self sort];
}
- (void)addGroupMember:(id<NTESGroupMemberProtocol>)member
{
NSString *groupTitle = [member groupTitle];
NSInteger groupIndex = [_groupTtiles indexOfObject:groupTitle];
Pair *pair = [_groups objectAtIndex:groupIndex];
if(!pair) {
NSMutableArray *members = [NSMutableArray array];
pair = [[Pair alloc] initWithFirst:groupTitle second:members];
}
NSMutableArray *members = pair.second;
[members addObject:member];
[_groupTtiles addObject:groupTitle];
[_groups addObject:pair];
[self sort];
}
- (void)removeGroupMember:(id<NTESGroupMemberProtocol>)member{
NSString *groupTitle = [member groupTitle];
NSInteger groupIndex = [_groupTtiles indexOfObject:groupTitle];
Pair *pair = [_groups objectAtIndex:groupIndex];
[pair.second removeObject:member];
if (![pair.second count]) {
[_groups removeObject:pair];
}
[self sort];
}
- (void)addGroupAboveWithTitle:(NSString *)title members:(NSArray *)members {
Pair *pair = [[Pair alloc] initWithFirst:title second:members];
[_specialGroupTtiles addObject:title];
[_specialGroups addObject:pair];
}
- (NSString *)titleOfGroup:(NSInteger)groupIndex
{
if(groupIndex >= 0 && groupIndex < _specialGroupTtiles.count) {
return [_specialGroupTtiles objectAtIndex:groupIndex];
}
groupIndex -= _specialGroupTtiles.count;
if(groupIndex >= 0 && groupIndex < _groupTtiles.count) {
return [_groupTtiles objectAtIndex:groupIndex];
}
return nil;
}
- (NSArray *)membersOfGroup:(NSInteger)groupIndex
{
if(groupIndex >= 0 && groupIndex < _specialGroups.count) {
Pair *pair = [_specialGroups objectAtIndex:groupIndex];
return pair.second;
}
groupIndex -= _specialGroups.count;
if(groupIndex >= 0 && groupIndex < _groups.count) {
Pair *pair = [_groups objectAtIndex:groupIndex];
return pair.second;
}
return nil;
}
- (id<NTESGroupMemberProtocol>)memberOfIndex:(NSIndexPath *)indexPath
{
NSArray *members = nil;
NSInteger groupIndex = indexPath.section;
if(groupIndex >= 0 && groupIndex < _specialGroups.count) {
Pair *pair = [_specialGroups objectAtIndex:groupIndex];
members = pair.second;
}
groupIndex -= _specialGroups.count;
if(groupIndex >= 0 && groupIndex < _groups.count) {
Pair *pair = [_groups objectAtIndex:groupIndex];
members = pair.second;
}
NSInteger memberIndex = indexPath.row;
if(memberIndex < 0 || memberIndex >= members.count) return nil;
return [members objectAtIndex:memberIndex];
}
- (id<NTESGroupMemberProtocol>)memberOfId:(NSString *)uid{
for (Pair *pair in _groups) {
NSArray *members = pair.second;
for (id<NTESGroupMemberProtocol> member in members) {
if ([[member memberId] isEqualToString:uid]) {
return member;
}
}
}
return nil;
}
- (NSInteger)groupCount
{
return _specialGroupTtiles.count + _groupTtiles.count;
}
- (NSInteger)memberCountOfGroup:(NSInteger)groupIndex
{
NSArray *members = nil;
if(groupIndex >= 0 && groupIndex < _specialGroups.count) {
Pair *pair = [_specialGroups objectAtIndex:groupIndex];
members = pair.second;
}
groupIndex -= _specialGroups.count;
if(groupIndex >= 0 && groupIndex < _groups.count) {
Pair *pair = [_groups objectAtIndex:groupIndex];
members = pair.second;
}
return members.count;
}
- (void)sort
{
[self sortGroupTitle];
[self sortGroupMember];
}
- (void)sortGroupTitle
{
[_groupTtiles sortUsingComparator:_groupTitleComparator];
[_groups sortUsingComparator:^NSComparisonResult(Pair *pair1, Pair *pair2) {
return _groupTitleComparator(pair1.first, pair2.first);
}];
}
- (void)sortGroupMember
{
[_groups enumerateObjectsUsingBlock:^(Pair *obj, NSUInteger idx, BOOL *stop) {
NSMutableArray *groupedMembers = obj.second;
[groupedMembers sortUsingComparator:^NSComparisonResult(id<NTESGroupMemberProtocol> member1, id<NTESGroupMemberProtocol> member2) {
return _groupMemberComparator([member1 sortKey], [member2 sortKey]);
}];
}];
}
- (void)setGroupTitleComparator:(NSComparator)groupTitleComparator
{
_groupTitleComparator = groupTitleComparator;
[self sortGroupTitle];
}
- (void)setGroupMemberComparator:(NSComparator)groupMemberComparator
{
_groupMemberComparator = groupMemberComparator;
[self sortGroupMember];
}
@end
@@ -0,0 +1,22 @@
//
// NTESGroupedUsrInfo.h
// NIM
//
// Created by Xuhui on 15/3/24.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import "NTESGroupedDataCollection.h"
@interface NTESGroupedUsrInfo : NTESGroupedDataCollection
- (instancetype)initWithContacts:(NSArray *)contacts;
@end
@interface NTESGroupedTeamInfo : NTESGroupedDataCollection
- (instancetype)initWithTeams:(NSArray *)teams;
@end
@@ -0,0 +1,68 @@
//
// NTESGroupedUsrInfo.m
// NIM
//
// Created by Xuhui on 15/3/24.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import "NTESGroupedUsrInfo.h"
#import "NIMTeamInfoData.h"
@implementation NTESGroupedUsrInfo
- (instancetype)init
{
self = [super init];
if(self) {
self.groupTitleComparator = ^NSComparisonResult(NSString *title1, NSString *title2) {
return [title1 localizedCompare:title2];
};
self.groupMemberComparator = ^NSComparisonResult(NSString *key1, NSString *key2) {
return [key1 localizedCompare:key2];
};
}
return self;
}
- (instancetype)initWithContacts:(NSArray *)contacts {
self = [self init];
if(self) {
self.members = contacts;
}
return self;
}
@end
@implementation NTESGroupedTeamInfo
- (instancetype)init
{
self = [super init];
if(self) {
self.groupTitleComparator = ^NSComparisonResult(NSString *title1, NSString *title2) {
return [title1 localizedCompare:title2];
};
self.groupMemberComparator = ^NSComparisonResult(NSString *key1, NSString *key2) {
return [key1 localizedCompare:key2];
};
}
return self;
}
- (instancetype)initWithTeams:(NSArray *)teams{
self = [self init];
if(self) {
NSMutableArray *array = [[NSMutableArray alloc] init];
for (NIMTeam *team in teams) {
NIMTeamInfoData *teamInfo = [[NIMTeamInfoData alloc] initWithTeam:team];
[array addObject:teamInfo];
}
self.members = array;
}
return self;
}
@end
@@ -0,0 +1,86 @@
//
// NTESContactDefines.h
// NIM
//
// Created by chris on 15/2/26.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#ifndef NIM_NTESContactDefines_h
#define NIM_NTESContactDefines_h
@protocol NTESContactItemCollection <NSObject>
@required
//显示的title名
- (NSString*)title;
//返回集合里的成员
- (NSArray*)members;
//重用id
- (NSString*)reuseId;
//需要构造的cell类名
- (NSString*)cellName;
@end
@protocol NTESContactItem<NSObject>
@required
//userId和Vcname必有一个有值,根据有值的状态push进不同的页面
- (NSString*)vcName;
//userId和Vcname必有一个有值,根据有值的状态push进不同的页面
- (NSString*)userId;
//返回行高
- (CGFloat)uiHeight;
//重用id
- (NSString*)reuseId;
//需要构造的cell类名
- (NSString*)cellName;
//badge
- (NSString *)badge;
//显示名
- (NSString *)nick;
//占位图
- (UIImage *)icon;
//头像url
- (NSString *)avatarUrl;
//accessoryView
- (BOOL)showAccessoryView;
@optional
- (NSString *)selName;
@end
@protocol NTESContactCell <NSObject>
- (void)refreshWithContactItem:(id<NTESContactItem>)item;
- (void)addDelegate:(id)delegate;
@end
#endif
#ifndef NIM_NTESContactCellLayoutConstant_h
#define NIM_NTESContactCellLayoutConstant_h
static const CGFloat NTESContactUtilRowHeight = 57;//util类Cell行高
static const CGFloat NTESContactDataRowHeight = 50;//data类Cell行高
static const NSInteger NTESContactAvatarLeft = 10;//没有选择框的时候,头像到左边的距离
static const NSInteger NTESContactAvatarAndAccessorySpacing = 10;//头像和选择框之间的距离
#endif
@@ -0,0 +1,24 @@
//
// NTESContactUtilCell.h
// NIM
//
// Created by chris on 15/2/26.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "NTESContactDefines.h"
@protocol NTESContactUtilCellDelegate <NSObject>
- (void)onPressUtilImage:(NSString *)content;
@end
@interface NTESContactUtilCell : UITableViewCell
@property (nonatomic,weak) id<NTESContactUtilCellDelegate> delegate;
- (void)refreshWithContactItem:(id<NTESContactItem>)item;
@end
@@ -0,0 +1,70 @@
//
// NTESContactUtilCell.m
// NIM
//
// Created by chris on 15/2/26.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import "NTESContactUtilCell.h"
#import "UIView+NTES.h"
#import "NTESBadgeView.h"
@interface NTESContactUtilCell()
@property (nonatomic,strong) NTESBadgeView *badgeView;
@property (nonatomic,strong) id<NTESContactItem> data;
@end
@implementation NTESContactUtilCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
_badgeView = [NTESBadgeView viewWithBadgeTip:@""];
[self addSubview:_badgeView];
}
return self;
}
- (void)refreshWithContactItem:(id<NTESContactItem>)item{
self.data = item;
self.textLabel.text = item.nick;
self.imageView.image = item.icon;
self.imageView.userInteractionEnabled = YES;
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onPressUtilImage:)];
[self.imageView addGestureRecognizer: recognizer];
[self.textLabel sizeToFit];
NSString *badge = [item badge];
self.badgeView.hidden = badge.integerValue == 0;
self.badgeView.badgeValue = badge;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
}
- (void)onPressUtilImage:(id)sender{
if ([self.delegate respondsToSelector:@selector(onPressUtilImage:)]) {
[self.delegate onPressUtilImage:self.data.nick];
}
}
- (void)addDelegate:(id)delegate{
self.delegate = delegate;
}
#define BadgeValueRight 50
- (void)layoutSubviews{
[super layoutSubviews];
self.imageView.left = NTESContactAvatarLeft;
self.imageView.centerY = self.height * .5f;
self.badgeView.right = self.width - BadgeValueRight;
self.badgeView.centerY = self.height * .5f;
}
@end
@@ -0,0 +1,33 @@
//
// NTESContactUtilItem.h
// NIM
//
// Created by chris on 15/2/26.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "NTESContactDefines.h"
#import "NTESGroupedContacts.h"
@interface NTESContactUtilItem : NSObject<NTESContactItemCollection>
@property (nonatomic,copy) NSArray *members;
@end
@interface NTESContactUtilMember : NSObject<NTESContactItem, NTESGroupMemberProtocol>
@property (nonatomic,copy) NSString *nick;
@property (nonatomic,copy) NSString *badge;
@property (nonatomic,copy) UIImage *icon;
@property (nonatomic,copy) NSString *vcName;
@property (nonatomic,copy) NSString *userId;
@property (nonatomic,copy) NSString *selName;
@end
@@ -0,0 +1,61 @@
//
// ContactUtilItem.m
// NIM
//
// Created by chris on 15/2/26.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import "NTESContactUtilItem.h"
@implementation NTESContactUtilItem
- (NSString*)reuseId{
return @"NTESContactUtilItem";
}
- (NSString*)cellName{
return @"NTESContactUtilCell";
}
- (NSString*)title{
return nil;
}
@end
@implementation NTESContactUtilMember
- (NSString *)avatarUrl{
return nil;
}
- (CGFloat)uiHeight{
return NTESContactUtilRowHeight;
}
- (NSString*)reuseId{
return @"NTESContactUtilItem";
}
- (NSString*)cellName{
return @"NTESContactUtilCell";
}
- (NSString *)groupTitle {
return nil;
}
- (NSString *)memberId{
return self.userId;
}
- (BOOL)showAccessoryView{
return YES;
}
- (id)sortKey {
return nil;
}
@end
@@ -0,0 +1,29 @@
//
// NTESUserListCell.h
// NIM
//
// Created by chris on 15/8/18.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import <UIKit/UIKit.h>
@class NIMAvatarImageView;
@class ContactDataMember;
@protocol NTESUserListCellDelegate <NSObject>
- (void)didTouchUserListAvatar:(NSString *)userId;
@end
@interface NTESUserListCell : UITableViewCell
@property (nonatomic,strong) NIMAvatarImageView * avatarImageView;
@property (nonatomic,weak) id<NTESUserListCellDelegate> delegate;
- (void)refreshWithMember:(ContactDataMember *)member;
@end
@@ -0,0 +1,86 @@
//
// NTESUserListCell.m
// NIM
//
// Created by chris on 15/8/18.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import "NTESUserListCell.h"
#import "NIMAvatarImageView.h"
#import "UIView+NTES.h"
#import "NTESContactDataMember.h"
#import "NTESSessionUtil.h"
@interface NTESUserListCell()
@property (nonatomic,strong) NTESContactDataMember *member;
@property (nonatomic,strong) UIView *sep;
@end
@implementation NTESUserListCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
_avatarImageView = [[NIMAvatarImageView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
[_avatarImageView addTarget:self action:@selector(onTouchAvatar:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:_avatarImageView];
_sep = [[UIView alloc] initWithFrame:CGRectZero];
_sep.backgroundColor = [UIColor lightGrayColor];
_sep.height = .5f;
[self addSubview:_sep];
}
return self;
}
- (void)refreshWithMember:(NTESContactDataMember *)member{
self.member = member;
self.textLabel.text = [NTESSessionUtil showNick:member.info.infoId inSession:nil];
[self.textLabel sizeToFit];
NSURL *url;
if (member.info.avatarUrlString.length) {
url = [NSURL URLWithString:member.info.avatarUrlString];
}
[_avatarImageView nim_setImageWithURL:url placeholderImage:member.info.avatarImage options:SDWebImageRetryFailed];
}
- (void)onTouchAvatar:(id)sender{
if ([self.delegate respondsToSelector:@selector(didTouchUserListAvatar:)]) {
[self.delegate didTouchUserListAvatar:self.member.info.infoId];
}
}
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated{
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated{
}
- (void)layoutSubviews{
[super layoutSubviews];
CGFloat scale = self.width / 320;
CGFloat maxTextLabelWidth = 210 * scale;
self.textLabel.width = MIN(self.textLabel.width, maxTextLabelWidth);
static const NSInteger NTESContactAccessoryLeft = 10;//选择框到左边的距离
static const NSInteger NTESContactAvatarAndTitleSpacing = 20;//头像和文字之间的间距
CGFloat avatarLeft = 15.f;
self.avatarImageView.left = avatarLeft;
self.avatarImageView.centerY = self.height * .5f;
self.textLabel.left = self.avatarImageView.right + NTESContactAvatarAndTitleSpacing;
self.sep.width = self.width - avatarLeft - self.avatarImageView.width - NTESContactAvatarAndTitleSpacing;
self.sep.left = avatarLeft + NTESContactAccessoryLeft + self.avatarImageView.width;
self.sep.bottom = self.height - self.sep.height;
}
@end
@@ -0,0 +1,15 @@
//
// NTESBlackListViewController.h
// NIM
//
// Created by chris on 15/8/18.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface NTESBlackListViewController : UIViewController
@property (nonatomic,strong) UITableView *tableView;
@end
@@ -0,0 +1,166 @@
//
// NTESBlackListViewController.m
// NIM
//
// Created by chris on 15/8/18.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import "NTESBlackListViewController.h"
#import "NTESUserListCell.h"
#import "Toast+UIView.h"
#import "NIMContactSelectViewController.h"
#import "NTESListHeader.h"
#import "UIView+NTES.h"
#import "NTESPersonalCardViewController.h"
#import "NTESContactDataMember.h"
@interface NTESBlackListViewController ()<UITableViewDataSource,UITableViewDelegate,NIMContactSelectDelegate,NTESListHeaderDelegate,NTESUserListCellDelegate>
@property (nonatomic,strong) NSMutableArray *data;
@property (nonatomic,strong) NTESListHeader *header;
@end
@implementation NTESBlackListViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setUpNavItem];
self.data = self.myBlackListUser;
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:self.tableView];
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.header = [[NTESListHeader alloc] initWithFrame:CGRectMake(0, 0, self.view.width, 0)];
self.header.autoresizingMask = UIViewAutoresizingFlexibleWidth;
self.header.delegate = self;
[self.header refreshWithType:ListHeaderTypeCommonText value:@"你不会接收到列表中联系人的任何消息"];
[self.view addSubview:self.header];
}
- (void)setUpNavItem{
self.navigationItem.title = @"黑名单";
UIButton *teamBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[teamBtn addTarget:self action:@selector(onOpera:) forControlEvents:UIControlEventTouchUpInside];
[teamBtn setImage:[UIImage imageNamed:@"icon_tinfo_normal"] forState:UIControlStateNormal];
[teamBtn setImage:[UIImage imageNamed:@"icon_tinfo_pressed"] forState:UIControlStateHighlighted];
[teamBtn sizeToFit];
UIBarButtonItem *teamItem = [[UIBarButtonItem alloc] initWithCustomView:teamBtn];
self.navigationItem.rightBarButtonItem = teamItem;
}
- (void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
[self refreshSubviews];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 60.f;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.data.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identity = @"cell";
NTESUserListCell *cell = [tableView dequeueReusableCellWithIdentifier:identity];
if (!cell) {
cell = [[NTESUserListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identity];
cell.delegate = self;
}
ContactDataMember *member = self.data[indexPath.row];
[cell refreshWithMember:member];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
//修正ios7下可以连续点两下 indexPath可能为Nil...这里规避一下
if (editingStyle == UITableViewCellEditingStyleDelete && indexPath) {
NSInteger index = indexPath.row;
if (self.data.count > index) {
NTESContactDataMember *member = self.data[indexPath.row];
__weak typeof(self) wself = self;
[[NIMSDK sharedSDK].userManager removeFromBlackBlackList:member.info.infoId completion:^(NSError *error) {
if (!error) {
[wself.data removeObjectAtIndex:indexPath.row];
[wself.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}else{
[wself.view makeToast:@"删除失败"];
}
}];
}
}
}
- (void)onOpera:(id)sender{
NSMutableArray *users = [[NSMutableArray alloc] init];
for (NTESContactDataMember *member in self.data) {
[users addObject:member.info.infoId];
}
NIMContactFriendSelectConfig *config = [[NIMContactFriendSelectConfig alloc] init];
config.filterIds = users;
NIMContactSelectViewController *vc = [[NIMContactSelectViewController alloc] initWithConfig:config];
vc.delegate = self;
[vc show];
}
#pragma mark - NTESContactSelectDelegate
- (void)didFinishedSelect:(NSArray *)selectedContacts{
if (selectedContacts.count) {
__weak typeof(self) wself = self;
[[NIMSDK sharedSDK].userManager addToBlackList:selectedContacts.firstObject completion:^(NSError *error) {
if (!error) {
[wself.view makeToast:@"操作成功!" ];
wself.data = wself.myBlackListUser;
[wself.tableView reloadData];
}else{
[wself.view makeToast:@"操作失败!"];
}
}];
}
}
#pragma mark - NTESUserListCellDelegate
- (void)didTouchUserListAvatar:(NSString *)userId{
NTESPersonalCardViewController *vc = [[NTESPersonalCardViewController alloc] initWithUserId:userId];
[self.navigationController pushViewController:vc animated:YES];
}
#pragma mark - Private
- (void)refreshSubviews{
self.tableView.top = self.header.height;
self.tableView.height = self.view.height - self.tableView.top;
self.header.bottom = self.tableView.top + self.tableView.contentInset.top;
}
- (NSMutableArray *)myBlackListUser{
NSMutableArray *list = [[NSMutableArray alloc] init];
for (NIMUser *user in [NIMSDK sharedSDK].userManager.myBlackList) {
NTESContactDataMember *member = [[NTESContactDataMember alloc] init];
NIMKitInfo *info = [[NIMKit sharedKit] infoByUser:user.userId];
member.info = info;
[list addObject:member];
}
return list;
}
@end
@@ -0,0 +1,15 @@
//
// NTESContactAddFriendViewController.h
// NIM
//
// Created by chris on 15/8/18.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface NTESContactAddFriendViewController : UIViewController
@property (nonatomic, strong) UITableView *tableView;
@end
@@ -0,0 +1,108 @@
//
// NTESContactAddFriendViewController.m
// NIM
//
// Created by chris on 15/8/18.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import "NTESContactAddFriendViewController.h"
#import "NIMCommonTableDelegate.h"
#import "NIMCommonTableData.h"
#import "Toast+UIView.h"
#import "SVProgressHUD.h"
#import "NTESPersonalCardViewController.h"
@interface NTESContactAddFriendViewController ()
@property (nonatomic,strong) NIMCommonTableDelegate *delegator;
@property (nonatomic,copy ) NSArray *data;
@property (nonatomic,assign) NSInteger inputLimit;
@end
@implementation NTESContactAddFriendViewController
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = @"添加好友";
__weak typeof(self) wself = self;
[self buildData];
self.delegator = [[NIMCommonTableDelegate alloc] initWithTableData:^NSArray *{
return wself.data;
}];
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:self.tableView];
self.tableView.backgroundColor = UIColorFromRGB(0xe3e6ea);
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.delegate = self.delegator;
self.tableView.dataSource = self.delegator;
}
- (void)buildData{
NSArray *data = @[
@{
HeaderTitle:@"",
RowContent :@[
@{
Title : @"请输入帐号",
CellClass : @"NTESTextSettingCell",
RowHeight : @(50),
},
],
FooterTitle:@""
},
];
self.data = [NIMCommonTableSection sectionsWithData:data];
}
#pragma mark - UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
NSString *userId = [textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if (userId.length) {
[self addFriend:userId];
}
return YES;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
return YES;
}
#pragma mark - Private
- (void)addFriend:(NSString *)userId{
__weak typeof(self) wself = self;
[SVProgressHUD show];
[[NIMSDK sharedSDK].userManager fetchUserInfos:@[userId] completion:^(NSArray *users, NSError *error) {
[SVProgressHUD dismiss];
if (users.count) {
NTESPersonalCardViewController *vc = [[NTESPersonalCardViewController alloc] initWithUserId:userId];
[wself.navigationController pushViewController:vc animated:YES];
}else{
if (wself) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"该用户不存在" message:@"请检查你输入的帐号是否正确" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[alert show];
}
}
}];
}
@end
@@ -0,0 +1,15 @@
//
// NTESContactViewController.h
// NIMDemo
//
// Created by chris on 15/2/2.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface NTESContactViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
@property(nonatomic,strong) IBOutlet UITableView *tableView;
@end
@@ -0,0 +1,408 @@
//
// NTESContactViewController.m
// NIMDemo
//
// Created by chris on 15/2/2.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import "NTESContactViewController.h"
#import "NTESSessionUtil.h"
//#import "NTESSessionViewController.h"
#import "IfishSessionViewController.h"
#import "NTESContactUtilItem.h"
#import "NTESContactDefines.h"
#import "NTESGroupedContacts.h"
#import "Toast+UIView.h"
#import "NTESCustomNotificationDB.h"
#import "NTESNotificationCenter.h"
#import "UIActionSheet+NTESBlock.h"
#import "NTESSearchTeamViewController.h"
#import "NTESContactAddFriendViewController.h"
#import "NTESPersonalCardViewController.h"
#import "UIAlertView+NTESBlock.h"
#import "SVProgressHUD.h"
#import "NTESContactUtilCell.h"
#import "NIMContactDataCell.h"
#import "NIMContactSelectViewController.h"
#import "NTESUserUtil.h"
#import "NIMKit.h"
@interface NTESContactViewController ()
<NIMUserManagerDelegate,
NIMSystemNotificationManagerDelegate,
NTESContactUtilCellDelegate,
NIMContactDataCellDelegate,
NIMLoginManagerDelegate> {
UIRefreshControl *_refreshControl;
NTESGroupedContacts *_contacts;
}
@property (nonatomic,strong) NSArray * datas;
@end
@implementation NTESContactViewController
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[[NIMSDK sharedSDK] systemNotificationManager] removeDelegate:self];
[[[NIMSDK sharedSDK] loginManager] removeDelegate:self];
[[[NIMSDK sharedSDK] userManager] removeDelegate:self];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.delegate = self;
self.tableView.dataSource = self;
UIEdgeInsets separatorInset = self.tableView.separatorInset;
separatorInset.right = 0;
self.tableView.separatorInset = separatorInset;
self.tableView.sectionIndexBackgroundColor = [UIColor clearColor];
self.tableView.tableFooterView = [[UIView alloc] init];
[self prepareData];
[[[NIMSDK sharedSDK] systemNotificationManager] addDelegate:self];
[[[NIMSDK sharedSDK] loginManager] addDelegate:self];
[[[NIMSDK sharedSDK] userManager] addDelegate:self];
}
- (void)setUpNavItem{
UIButton *teamBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[teamBtn addTarget:self action:@selector(onOpera:) forControlEvents:UIControlEventTouchUpInside];
[teamBtn setImage:[UIImage imageNamed:@"icon_tinfo_normal"] forState:UIControlStateNormal];
[teamBtn setImage:[UIImage imageNamed:@"icon_tinfo_pressed"] forState:UIControlStateHighlighted];
[teamBtn sizeToFit];
UIBarButtonItem *teamItem = [[UIBarButtonItem alloc] initWithCustomView:teamBtn];
self.navigationItem.rightBarButtonItem = teamItem;
}
- (void)prepareData{
_contacts = [[NTESGroupedContacts alloc] init];
NSString *contactCellUtilIcon = @"icon";
NSString *contactCellUtilVC = @"vc";
NSString *contactCellUtilBadge = @"badge";
NSString *contactCellUtilTitle = @"title";
NSString *contactCellUtilUid = @"uid";
NSString *contactCellUtilSelectorName = @"selName";
//原始数据
NSInteger systemCount = [[[NIMSDK sharedSDK] systemNotificationManager] allUnreadCount];
NSMutableArray *utils =
[@[
@{
contactCellUtilIcon:@"icon_notification_normal",
contactCellUtilTitle:@"验证消息",
contactCellUtilVC:@"NTESSystemNotificationViewController",
contactCellUtilBadge:@(systemCount)
},
@{
contactCellUtilIcon:@"icon_team_advance_normal",
contactCellUtilTitle:@"高级群",
contactCellUtilVC:@"NTESAdvancedTeamListViewController"
},
@{
contactCellUtilIcon:@"icon_team_normal_normal",
contactCellUtilTitle:@"讨论组",
contactCellUtilVC:@"NTESNormalTeamListViewController"
},
@{
contactCellUtilIcon:@"icon_blacklist_normal",
contactCellUtilTitle:@"黑名单",
contactCellUtilVC:@"NTESBlackListViewController"
},
@{
contactCellUtilIcon:@"icon_computer_normal",
contactCellUtilTitle:@"我的电脑",
contactCellUtilSelectorName:@"onEnterMyComputer"
},
] mutableCopy];
self.navigationItem.title = @"通讯录";
[self setUpNavItem];
//构造显示的数据模型
NTESContactUtilItem *contactUtil = [[NTESContactUtilItem alloc] init];
NSMutableArray * members = [[NSMutableArray alloc] init];
for (NSDictionary *item in utils) {
NTESContactUtilMember *utilItem = [[NTESContactUtilMember alloc] init];
utilItem.nick = item[contactCellUtilTitle];
utilItem.icon = [UIImage imageNamed:item[contactCellUtilIcon]];
utilItem.vcName = item[contactCellUtilVC];
utilItem.badge = [item[contactCellUtilBadge] stringValue];
utilItem.userId = item[contactCellUtilUid];
utilItem.selName = item[contactCellUtilSelectorName];
[members addObject:utilItem];
}
contactUtil.members = members;
[_contacts addGroupAboveWithTitle:@"" members:contactUtil.members];
}
#pragma mark - Action
- (void)onEnterMyComputer{
NSString *uid = [[NIMSDK sharedSDK].loginManager currentAccount];
NIMSession *session = [NIMSession session:uid type:NIMSessionTypeP2P];
IfishSessionViewController *vc = [[IfishSessionViewController alloc] initWithSession:session];
[self.navigationController pushViewController:vc animated:YES];
}
- (void)onOpera:(id)sender{
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"选择操作" delegate:nil cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"添加好友",@"创建高级群",@"创建讨论组",@"搜索高级群", nil];
__weak typeof(self) wself = self;
NSString *currentUserId = [[NIMSDK sharedSDK].loginManager currentAccount];
[sheet showInView:self.view completionHandler:^(NSInteger index) {
UIViewController *vc;
switch (index) {
case 0:
vc = [[NTESContactAddFriendViewController alloc] initWithNibName:nil bundle:nil];
break;
case 1:{ //创建高级群
[wself presentMemberSelector:^(NSArray *uids) {
NSArray *members = [@[currentUserId] arrayByAddingObjectsFromArray:uids];
NIMCreateTeamOption *option = [[NIMCreateTeamOption alloc] init];
option.name = @"高级群";
option.type = NIMTeamTypeAdvanced;
option.joinMode = NIMTeamJoinModeNoAuth;
option.postscript = @"邀请你加入群组";
[SVProgressHUD show];
[[NIMSDK sharedSDK].teamManager createTeam:option users:members completion:^(NSError *error, NSString *teamId) {
[SVProgressHUD dismiss];
if (!error) {
NIMSession *session = [NIMSession session:teamId type:NIMSessionTypeTeam];
IfishSessionViewController *vc = [[IfishSessionViewController alloc] initWithSession:session];
[wself.navigationController pushViewController:vc animated:YES];
}else{
[wself.view makeToast:@"创建失败"];
}
}];
}];
break;
}
case 2:{ //创建讨论组
[wself presentMemberSelector:^(NSArray *uids) {
if (!uids.count) {
return; //讨论组必须除自己外必须要有一个群成员
}
NSArray *members = [@[currentUserId] arrayByAddingObjectsFromArray:uids];
NIMCreateTeamOption *option = [[NIMCreateTeamOption alloc] init];
option.name = @"讨论组";
option.type = NIMTeamTypeNormal;
[SVProgressHUD show];
[[NIMSDK sharedSDK].teamManager createTeam:option users:members completion:^(NSError *error, NSString *teamId) {
[SVProgressHUD dismiss];
if (!error) {
NIMSession *session = [NIMSession session:teamId type:NIMSessionTypeTeam];
IfishSessionViewController *vc = [[IfishSessionViewController alloc] initWithSession:session];
[wself.navigationController pushViewController:vc animated:YES];
}else{
[wself.view makeToast:@"创建失败"];
}
}];
}];
break;
}
case 3:
vc = [[NTESSearchTeamViewController alloc] initWithNibName:nil bundle:nil];
break;
default:
break;
}
if (vc) {
[wself.navigationController pushViewController:vc animated:YES];
}
}];
}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
id<NTESContactItem> contactItem = (id<NTESContactItem>)[_contacts memberOfIndex:indexPath];
if ([contactItem respondsToSelector:@selector(selName)] && [contactItem selName].length) {
SEL sel = NSSelectorFromString([contactItem selName]);
SuppressPerformSelectorLeakWarning([self performSelector:sel withObject:nil]);
}
else if (contactItem.vcName.length) {
Class clazz = NSClassFromString(contactItem.vcName);
UIViewController * vc = [[clazz alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:vc animated:YES];
}else if([contactItem respondsToSelector:@selector(userId)]){
NSString * friendId = contactItem.userId;
[self enterPersonalCard:friendId];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
id<NTESContactItem> contactItem = (id<NTESContactItem>)[_contacts memberOfIndex:indexPath];
return contactItem.uiHeight;
}
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [_contacts memberCountOfGroup:section];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return [_contacts groupCount];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
id contactItem = [_contacts memberOfIndex:indexPath];
NSString * cellId = [contactItem reuseId];
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (!cell) {
Class cellClazz = NSClassFromString([contactItem cellName]);
cell = [[cellClazz alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
}
if ([contactItem showAccessoryView]) {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}else{
cell.accessoryType = UITableViewCellAccessoryNone;
}
if ([cell isKindOfClass:[NTESContactUtilCell class]]) {
[(NTESContactUtilCell *)cell refreshWithContactItem:contactItem];
[(NTESContactUtilCell *)cell setDelegate:self];
}else{
[(NIMContactDataCell *)cell refreshUser:contactItem];
[(NIMContactDataCell *)cell setDelegate:self];
}
return cell;
}
- (NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
return [_contacts titleOfGroup:section];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return _contacts.sortedGroupTitles;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
return index + 1;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
id<NTESContactItem> contactItem = (id<NTESContactItem>)[_contacts memberOfIndex:indexPath];
return [contactItem userId].length;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
if (editingStyle == UITableViewCellEditingStyleDelete) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"删除好友" message:@"删除好友后,将同时解除双方的好友关系" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
[alert showAlertWithCompletionHandler:^(NSInteger index) {
if (index == 1) {
[SVProgressHUD show];
id<NTESContactItem,NTESGroupMemberProtocol> contactItem = (id<NTESContactItem,NTESGroupMemberProtocol>)[_contacts memberOfIndex:indexPath];
NSString *userId = [contactItem userId];
__weak typeof(self) wself = self;
[[NIMSDK sharedSDK].userManager deleteFriend:userId completion:^(NSError *error) {
[SVProgressHUD dismiss];
if (!error) {
[_contacts removeGroupMember:contactItem];
}else{
[wself.view makeToast:@"删除失败"];
}
}];
}
}];
}
}
#pragma mark - NIMContactDataCellDelegate
- (void)onPressAvatar:(NSString *)memberId{
[self enterPersonalCard:memberId];
}
#pragma mark - NTESContactUtilCellDelegate
- (void)onPressUtilImage:(NSString *)content{
[self.view makeToast:[NSString stringWithFormat:@"点我干嘛 我是<%@>",content]];
}
#pragma mark - NIMContactSelectDelegate
- (void)didFinishedSelect:(NSArray *)selectedContacts{
}
#pragma mark - NIMSDK Delegate
- (void)onSystemNotificationCountChanged:(NSInteger)unreadCount
{
[self prepareData];
[self.tableView reloadData];
}
- (void)onLogin:(NIMLoginStep)step
{
if (step == NIMLoginStepSyncOK) {
if (self.isViewLoaded) {//没有加载view的话viewDidLoad里会走一遍prepareData
[self prepareData];
[self.tableView reloadData];
}
}
}
- (void)onUserInfoChanged:(NIMUser *)user
{
[self refresh];
}
- (void)onFriendChanged:(NIMUser *)user{
[self refresh];
}
- (void)onBlackListChanged
{
[self refresh];
}
- (void)onMuteListChanged
{
[self refresh];
}
- (void)refresh
{
[self prepareData];
[self.tableView reloadData];
}
#pragma mark - Private
- (void)enterPersonalCard:(NSString *)userId{
NTESPersonalCardViewController *vc = [[NTESPersonalCardViewController alloc] initWithUserId:userId];
[self.navigationController pushViewController:vc animated:YES];
}
- (void)presentMemberSelector:(ContactSelectFinishBlock) block{
NSMutableArray *users = [[NSMutableArray alloc] init];
//使用内置的好友选择器
NIMContactFriendSelectConfig *config = [[NIMContactFriendSelectConfig alloc] init];
//获取自己id
NSString *currentUserId = [[NIMSDK sharedSDK].loginManager currentAccount];
[users addObject:currentUserId];
//将自己的id过滤
config.filterIds = users;
//需要多选
config.needMutiSelected = YES;
//初始化联系人选择器
NIMContactSelectViewController *vc = [[NIMContactSelectViewController alloc] initWithConfig:config];
//回调处理
vc.finshBlock = block;
[vc show];
}
@end
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="NTESContactViewController">
<connections>
<outlet property="tableView" destination="Oau-26-OM6" id="krq-R7-E5l"/>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="Oau-26-OM6">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</tableView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina4"/>
<point key="canvasLocation" x="222" y="190"/>
</view>
</objects>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>
@@ -0,0 +1,28 @@
//
// NTESCustomNotificationDB.h
// NIM
//
// Created by chris on 15/5/26.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "NTESService.h"
@class NTESCustomNotificationObject;
@interface NTESCustomNotificationDB : NTESService
@property (nonatomic,assign) NSInteger unreadCount;
- (NSArray *)fetchNotifications:(NTESCustomNotificationObject *)notification
limit:(NSInteger)limit;
- (BOOL)saveNotification:(NTESCustomNotificationObject *)notification;
- (void)deleteNotification:(NTESCustomNotificationObject *)notification;
- (void)deleteAllNotification;
- (void)markAllNotificationsAsRead;
@end
@@ -0,0 +1,229 @@
//
// NTESCustomNotificationDB.m
// NIM
//
// Created by chris on 15/5/26.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import "NTESCustomNotificationDB.h"
#import "FMDB.h"
#import "NTESFileLocationHelper.h"
#import "NTESCustomNotificationObject.h"
typedef NS_ENUM(NSInteger, CustomNotificationStatus){
CustomNotificationStatusNone = 0,
CustomNotificationStatusRead = 1,
CustomNotificationStatusDeleted = 2,
};
@interface NTESCustomNotificationDB ()
@property (nonatomic,strong) FMDatabase *db;
@end
@implementation NTESCustomNotificationDB
- (instancetype)init
{
if (self = [super init])
{
[self openDatabase];
}
return self;
}
- (NSInteger)unreadCount
{
__block NSInteger count = 0;
io_sync_safe(^{
count = _unreadCount;
});
return count;
}
- (NSArray *)fetchNotifications:(NTESCustomNotificationObject *)notification
limit:(NSInteger)limit{
__block NSArray *result = nil;
NSString *sql = nil;
if (notification)
{
sql = [NSString stringWithFormat:@"select * from notifications where timetag < %f and status != ? order by timetag desc limit ?",
notification.timestamp] ;
}
else
{
sql = @"select * from notifications where status != ? order by timetag desc limit ?";
}
io_sync_safe(^{
NSMutableArray *array = [NSMutableArray array];
FMResultSet *rs = [self.db executeQuery:sql,@(CustomNotificationStatusDeleted),@(limit)];
while ([rs next])
{
NTESCustomNotificationObject *notification = [[NTESCustomNotificationObject alloc] init];
notification.serial = (NSInteger)[rs intForColumn:@"serial"];
notification.timestamp = [rs doubleForColumn:@"timetag"];
notification.sender = [rs stringForColumn:@"sender"];
notification.receiver = [rs stringForColumn:@"receiver"];
notification.content = [rs stringForColumn:@"content"];
[array addObject:notification];
}
[rs close];
result = array;
});
return result;
}
- (BOOL)saveNotification:(NTESCustomNotificationObject *)notification{
__block BOOL result = NO;
io_sync_safe(^{
if (notification)
{
CustomNotificationStatus status = notification.needBadge? CustomNotificationStatusNone : CustomNotificationStatusRead;
NSString *sql = @"insert into notifications(timetag,sender,receiver,content,status) \
values(?,?,?,?,?)";
if (![self.db executeUpdate:sql,
@(notification.timestamp),
notification.sender,
notification.receiver,
notification.content,
@(status)])
{
NSLog(@"update failed %@ error %@",notification,self.db.lastError);
}
else
{
notification.serial = (NSInteger)[self.db lastInsertRowId];
if (notification.needBadge) {
self.unreadCount++;
}
result = YES;
}
}
});
return result;
}
- (void)deleteNotification:(NTESCustomNotificationObject *)notification{
NSString *sql = @"update notifications set status = ? where serial = ?";
io_async(^{
if (![self.db executeUpdate:sql,@(CustomNotificationStatusDeleted),@(notification.serial)])
{
NSLog(@"delete notifications failed");
}
[self queryUnreadCount];
});
}
- (void)deleteAllNotification{
NSString *sql = @"update notifications set status = ? where status < ? or status > ?";
io_async(^{
if (![self.db executeUpdate:sql,@(CustomNotificationStatusDeleted),@(CustomNotificationStatusDeleted),@(CustomNotificationStatusDeleted)])
{
NSLog(@"delete notifications failed");
}
[self queryUnreadCount];
});
}
- (void)markAllNotificationsAsRead{
NSString *sql = @"update notifications set status = ? where status = ?";
io_sync_safe(^{
if (![self.db executeUpdate:sql,@(CustomNotificationStatusRead),@(CustomNotificationStatusNone)])
{
NSLog(@"mark notifications read failed");
}
[self queryUnreadCount];
});
}
- (void)queryUnreadCount{
NSInteger count = 0;
NSString *sql = @"select count(serial) from notifications where status = ?";
FMResultSet *rs = [_db executeQuery:sql,@(CustomNotificationStatusNone)];
if ([rs next])
{
count = (NSInteger)[rs intForColumnIndex:0];
}
[rs close];
if (count != _unreadCount)
{
self.unreadCount = count;
}
}
#pragma mark - Misc
- (void)openDatabase
{
NSString *filepath = [[NTESFileLocationHelper userDirectory] stringByAppendingString:@"notification.db"];
FMDatabase *db = [FMDatabase databaseWithPath:filepath];
if ([db open])
{
_db = db;
NSArray *sqls = @[@"create table if not exists notifications(serial integer primary key, \
timetag integer,sender text,receiver text,content text,status integer)",
@"create index if not exists readindex on notifications(status)",
@"create index if not exists timetagindex on notifications(timetag)"];
for (NSString *sql in sqls)
{
if (![_db executeUpdate:sql])
{
NSLog(@"error: execute sql %@ failed error %@",sql,_db.lastError);
}
}
[self queryUnreadCount];
}
else
{
NSLog(@"error open database failed %@",filepath);
}
}
static const void * const NTESDispatchIOSpecificKey = &NTESDispatchIOSpecificKey;
dispatch_queue_t NTESDispatchIOQueue()
{
static dispatch_queue_t queue;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
queue = dispatch_queue_create("nim.demo.io.queue", 0);
dispatch_queue_set_specific(queue, NTESDispatchIOSpecificKey, (void *)NTESDispatchIOSpecificKey, NULL);
});
return queue;
}
typedef void(^dispatch_block)(void);
void io_sync_safe(dispatch_block block)
{
if (dispatch_get_specific(NTESDispatchIOSpecificKey))
{
block();
}
else
{
dispatch_sync(NTESDispatchIOQueue(), ^() {
block();
});
}
}
void io_async(dispatch_block block){
dispatch_async(NTESDispatchIOQueue(), ^() {
block();
});
}
@end
@@ -0,0 +1,49 @@
//
// NTESCustomNotificationObject.h
// NIM
//
// Created by chris on 15/5/28.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NTESCustomNotificationObject : NSObject
/**
* 存储用的标识
*/
@property (nonatomic,assign) NSInteger serial;
/**
* 时间戳
*/
@property (nonatomic,assign) NSTimeInterval timestamp;
/**
* 通知发起者id
*/
@property (nonatomic,copy) NSString *sender;
/**
* 通知接受者id
*/
@property (nonatomic,copy) NSString *receiver;
/**
* 透传的消息体内容
*/
@property (nonatomic,copy) NSString *content;
/**
* 是否需要未读计数
*/
@property (nonatomic,assign) BOOL needBadge;
- (instancetype)initWithNotification:(NIMCustomSystemNotification *)notification;
@end
@@ -0,0 +1,25 @@
//
// NTESCustomNotificationObject.m
// NIM
//
// Created by chris on 15/5/28.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import "NTESCustomNotificationObject.h"
@implementation NTESCustomNotificationObject
- (instancetype)initWithNotification:(NIMCustomSystemNotification *)notification{
self = [super init];
if (self) {
_sender = notification.sender;
_receiver = notification.receiver;
_timestamp = notification.timestamp;
_content = notification.content;
_needBadge = notification.setting.shouldBeCounted;
}
return self;
}
@end
@@ -0,0 +1,15 @@
//
// NTESCustomSysNotificationViewController.h
// NIM
//
// Created by chris on 15/5/26.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface NTESCustomSysNotificationViewController : UIViewController
@property (nonatomic,strong) IBOutlet UITableView *tableView;
@end
@@ -0,0 +1,175 @@
//
// NTESCustomSysNotificationViewController.m
// NIM
//
// Created by chris on 15/5/26.
// Copyright (c) 2015年 Netease. All rights reserved.
//
#import "NTESCustomSysNotificationViewController.h"
#import "NIMContactSelectViewController.h"
#import "NTESCustomSysNotificationSender.h"
#import "UIAlertView+NTESBlock.h"
#import "NTESCustomNotificationDB.h"
#import "NSDictionary+NTESJson.h"
#import "NTESCustomNotificationObject.h"
#import "UIActionSheet+NTESBlock.h"
#import "NTESNotificationCenter.h"
#import "NTESCustomSysNotificationSender.h"
#define FetchLimit 10
static NSString *reuseIdentifier = @"reuseIdentifier";
@interface NTESCustomSysNotificationViewController ()<NIMContactSelectDelegate>
@property (nonatomic,strong) NSMutableArray *data;
@property (nonatomic,assign) NIMSessionType sendSessionType;
@property (nonatomic,strong) NTESCustomSysNotificationSender *sender;
@end
@implementation NTESCustomSysNotificationViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setupNav];
NTESCustomNotificationDB *db = [NTESCustomNotificationDB sharedInstance];
self.data = [[db fetchNotifications:nil limit:FetchLimit] mutableCopy];
self.tableView.tableFooterView = [[UIView alloc] init];
[db markAllNotificationsAsRead];
extern NSString *NTESCustomNotificationCountChanged;
[[NSNotificationCenter defaultCenter] postNotificationName:NTESCustomNotificationCountChanged object:nil];
_sender = [[NTESCustomSysNotificationSender alloc] init];
}
- (void)setupNav{
self.navigationItem.title = @"自定义系统通知";
UIBarButtonItem *clearBarBtnItem = [[UIBarButtonItem alloc] initWithTitle:@"清空"
style:UIBarButtonItemStylePlain
target:self
action:@selector(clearAll:)];
UIBarButtonItem *addCustomNotiBarBtnItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addCustomNotification:)];
self.navigationItem.rightBarButtonItems = @[clearBarBtnItem,addCustomNotiBarBtnItem];
}
#pragma mark - UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 55.f;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSInteger index = [indexPath row];
NTESCustomNotificationObject *notification = [self.data objectAtIndex:index];
[self.data removeObjectAtIndex:index];
NTESCustomNotificationDB *db = [NTESCustomNotificationDB sharedInstance];
[db deleteNotification:notification];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
#pragma mark - UITableViewDataSource
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
}
NTESCustomNotificationObject *notification = [self.data objectAtIndex:[indexPath row]];
NSString *content = notification.content;
NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding];
if (data)
{
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data
options:0
error:nil];
if ([dict isKindOfClass:[NSDictionary class]])
{
NSString *text = [dict jsonString:NTESCustomContent];
cell.textLabel.text = text;
}
}
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.data.count;
}
#pragma mark - Action
- (void)addCustomNotification:(id)sender{
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"选择操作" delegate:nil cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"单聊",@"群组", nil];
__block NIMContactSelectViewController *vc;
[sheet showInView:self.view completionHandler:^(NSInteger index) {
switch (index) {
case 0:{
NIMContactFriendSelectConfig *config = [[NIMContactFriendSelectConfig alloc] init];
vc = [[NIMContactSelectViewController alloc] initWithConfig:config];
self.sendSessionType = NIMSessionTypeP2P;
vc.delegate = self;
break;
}
case 1:{
NIMContactTeamSelectConfig *config = [[NIMContactTeamSelectConfig alloc] init];
vc = [[NIMContactSelectViewController alloc] initWithConfig:config];
self.sendSessionType = NIMSessionTypeTeam;
vc.delegate = self;
break;
}
default:
return;
}
[vc show];
}];
}
- (void)clearAll:(id)sender{
NTESCustomNotificationDB *db = [NTESCustomNotificationDB sharedInstance];
[db deleteAllNotification];
[self.data removeAllObjects];
[self.tableView reloadData];
}
#pragma mark - NIMContactSelectDelegate
- (void)didFinishedSelect:(NSArray *)selectedContacts{
NSString *selectId = selectedContacts.firstObject;
if (!selectId.length) {
return;
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"自定义发送内容" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确认", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert showAlertWithCompletionHandler:^(NSInteger index) {
switch (index) {
case 0://取消
break;
case 1:{
NSString *content = [[alert textFieldAtIndex:0].text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
content = [content length] ? content : @"";
NIMSession *session = [NIMSession session:selectId type:self.sendSessionType];
[_sender sendCustomContent:content
toSession:session];
}
break;
default:
break;
}
}];
}
@end
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="NTESCustomSysNotificationViewController">
<connections>
<outlet property="tableView" destination="V2m-A8-huH" id="IPg-Fo-K8x"/>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="V2m-A8-huH">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<connections>
<outlet property="dataSource" destination="-1" id="Z1f-MW-Kd5"/>
<outlet property="delegate" destination="-1" id="DrY-m6-TIo"/>
</connections>
</tableView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina4"/>
<point key="canvasLocation" x="276" y="209"/>
</view>
</objects>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>
@@ -0,0 +1,31 @@
//
// NTESSystemNotificationCell.h
// NIM
//
// Created by amao on 3/17/15.
// Copyright (c) 2015 Netease. All rights reserved.
//
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger, NotificationHandleType) {
NotificationHandleTypePending = 0,
NotificationHandleTypeOk,
NotificationHandleTypeNo,
NotificationHandleTypeOutOfDate
};
@class NIMSystemNotification;
@protocol NIMSystemNotificationCellDelegate <NSObject>
- (void)onAccept:(NIMSystemNotification *)notification;
- (void)onRefuse:(NIMSystemNotification *)notification;
@end
@interface NTESSystemNotificationCell : UITableViewCell
@property (strong, nonatomic) IBOutlet UILabel *handleInfoLabel;
@property (strong, nonatomic) IBOutlet UIView *acceptButton;
@property (strong, nonatomic) IBOutlet UIView *refuseButton;
@property (weak, nonatomic) id<NIMSystemNotificationCellDelegate> actionDelegate;
- (void)update:(NIMSystemNotification *)notification;
@end
@@ -0,0 +1,196 @@
//
// NTESSystemNotificationCell.m
// NIM
//
// Created by amao on 3/17/15.
// Copyright (c) 2015 Netease. All rights reserved.
//
#import "NTESSystemNotificationCell.h"
#import "NTESSessionUtil.h"
#import "UIView+NTES.h"
#import <NIMSDK/NIMSDK.h>
#import "NIMAvatarImageView.h"
@interface NTESSystemNotificationCell ()
@property (nonatomic,strong) IBOutlet UILabel *messageLabel;
@property (nonatomic,strong) NIMSystemNotification *notification;
@property (nonatomic,strong) IBOutlet NIMAvatarImageView *avatarImageView;
@end
@implementation NTESSystemNotificationCell
- (void)awakeFromNib{
[super awakeFromNib];
self.textLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
self.detailTextLabel.backgroundColor = [UIColor clearColor];
self.detailTextLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
self.avatarImageView = [[NIMAvatarImageView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
[self addSubview:self.avatarImageView];
}
- (void)update:(NIMSystemNotification *)notification{
self.notification = notification;
[self updateUI];
}
- (void)updateUI{
BOOL hideActionButton = [self shouldHideActionButton];
[self.acceptButton setHidden:hideActionButton];
[self.refuseButton setHidden:hideActionButton];
if(hideActionButton) {
self.handleInfoLabel.hidden = NO;
switch (self.notification.handleStatus) {
case NotificationHandleTypeOk:
self.handleInfoLabel.text = @"已同意";
break;
case NotificationHandleTypeNo:
self.handleInfoLabel.text = @"已拒绝";
break;
case NotificationHandleTypeOutOfDate:
self.handleInfoLabel.text = @"已过期";
break;
default:
self.handleInfoLabel.text = nil;
break;
}
} else {
self.handleInfoLabel.hidden = YES;
}
NSString *sourceID = self.notification.sourceID;
NIMKitInfo *sourceMember = [[NIMKit sharedKit] infoByUser:sourceID];
[self updateSourceMember:sourceMember];
}
- (void)updateSourceMember:(NIMKitInfo *)sourceMember{
NIMSystemNotificationType type = self.notification.type;
NSString *avatarUrlString = sourceMember.avatarUrlString;
NSURL *url;
if (avatarUrlString.length) {
url = [NSURL URLWithString:avatarUrlString];
}
[self.avatarImageView nim_setImageWithURL:url placeholderImage:sourceMember.avatarImage options:SDWebImageRetryFailed];
self.textLabel.text = sourceMember.showName;
[self.textLabel sizeToFit];
switch (type) {
case NIMSystemNotificationTypeTeamApply:
{
NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:self.notification.targetID];
self.detailTextLabel.text = [NSString stringWithFormat:@"申请加入群 %@", team.teamName];
}
break;
case NIMSystemNotificationTypeTeamApplyReject:
{
NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:self.notification.targetID];
self.detailTextLabel.text = [NSString stringWithFormat:@"群 %@ 拒绝你加入", team.teamName];
}
break;
case NIMSystemNotificationTypeTeamInvite:
{
NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:self.notification.targetID];
self.detailTextLabel.text = [NSString stringWithFormat:@"群 %@ 邀请你加入", team.teamName];
}
break;
case NIMSystemNotificationTypeTeamIviteReject:
{
NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:self.notification.targetID];
self.detailTextLabel.text = [NSString stringWithFormat:@"拒绝了群 %@ 邀请", team.teamName];
}
break;
case NIMSystemNotificationTypeFriendAdd:
{
NSString *text = @"未知请求";
id object = self.notification.attachment;
if ([object isKindOfClass:[NIMUserAddAttachment class]]) {
NIMUserOperation operation = [(NIMUserAddAttachment *)object operationType];
switch (operation) {
case NIMUserOperationAdd:
text = @"已添加你为好友";
break;
case NIMUserOperationRequest:
text = @"请求添加你为好友";
break;
case NIMUserOperationVerify:
text = @"通过了你的好友请求";
break;
case NIMUserOperationReject:
text = @"拒绝了你的好友请求";
break;
default:
break;
}
}
self.detailTextLabel.text = text;
}
break;
default:
break;
}
[self.detailTextLabel sizeToFit];
self.messageLabel.text = self.notification.postscript;
[self.messageLabel sizeToFit];
[self setNeedsLayout];
}
- (IBAction)onAccept:(id)sender {
if (_actionDelegate && [_actionDelegate respondsToSelector:@selector(onAccept:)]){
[_actionDelegate onAccept:self.notification];
}
}
- (IBAction)onRefuse:(id)sender {
if (_actionDelegate && [_actionDelegate respondsToSelector:@selector(onRefuse:)]){
[_actionDelegate onRefuse:self.notification];
}
}
- (BOOL)shouldHideActionButton
{
NIMSystemNotificationType type = self.notification.type;
BOOL handled = self.notification.handleStatus != 0;
BOOL needHandle = NO;
if (type == NIMSystemNotificationTypeTeamApply ||
type == NIMSystemNotificationTypeTeamInvite) {
needHandle = YES;
}
if (type == NIMSystemNotificationTypeFriendAdd) {
id object = self.notification.attachment;
if ([object isKindOfClass:[NIMUserAddAttachment class]]) {
NIMUserOperation operation = [(NIMUserAddAttachment *)object operationType];
needHandle = operation == NIMUserOperationRequest;
}
}
return !(!handled && needHandle);
}
#define MaxTextLabelWidth 120.0 * UISreenWidthScale
#define MaxDetailLabelWidth 160.0 * UISreenWidthScale
#define MaxMessageLabelWidth 150.0 * UISreenWidthScale
#define TextLabelAndMessageLabelSpacing 20.f
#define AvatarImageViewLeft 15.f
#define MessageAndAvatarSpacing 15.f
- (void)layoutSubviews{
[super layoutSubviews];
self.avatarImageView.centerY = self.height * .5f;
self.avatarImageView.left = AvatarImageViewLeft;
if (self.textLabel.width > MaxTextLabelWidth) {
self.textLabel.width = MaxTextLabelWidth;
}
if (self.detailTextLabel.width > MaxDetailLabelWidth) {
self.detailTextLabel.width = MaxDetailLabelWidth;
}
self.textLabel.left = self.avatarImageView.right + MessageAndAvatarSpacing;
self.detailTextLabel.left = self.textLabel.left;
self.detailTextLabel.bottom = self.avatarImageView.bottom;
if (self.messageLabel.width > MaxMessageLabelWidth) {
self.messageLabel.width = MaxMessageLabelWidth;
}
self.messageLabel.left = self.textLabel.right + TextLabelAndMessageLabelSpacing;
}
@end
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="8191" systemVersion="14F27" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="6kL-5q-BCS" detailTextLabel="GdR-st-QAn" style="IBUITableViewCellStyleSubtitle" id="KGk-i7-Jjw" customClass="NTESSystemNotificationCell">
<rect key="frame" x="0.0" y="0.0" width="320" height="72"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
<rect key="frame" x="0.0" y="0.0" width="320" height="71.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="6kL-5q-BCS">
<rect key="frame" x="15" y="18" width="33.5" height="20.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="GdR-st-QAn">
<rect key="frame" x="15" y="38.5" width="47" height="16"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="e7S-UR-ojv">
<rect key="frame" x="268" y="32" width="46" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<state key="normal" title="拒绝">
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onRefuse:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="EXj-Sc-V12"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="vgE-ql-Vdw">
<rect key="frame" x="219" y="32" width="46" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<state key="normal" title="同意">
<color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
</state>
<connections>
<action selector="onAccept:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="INP-rI-bL6"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="处理无效" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="TQX-2h-YLX">
<rect key="frame" x="230" y="37" width="75" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="kqp-Kb-bwb">
<rect key="frame" x="85" y="21" width="109" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
<connections>
<outlet property="acceptButton" destination="vgE-ql-Vdw" id="pJJ-KC-y2b"/>
<outlet property="handleInfoLabel" destination="TQX-2h-YLX" id="ziv-hj-LvO"/>
<outlet property="messageLabel" destination="kqp-Kb-bwb" id="MMa-cz-w3I"/>
<outlet property="refuseButton" destination="e7S-UR-ojv" id="m9d-ZE-lya"/>
</connections>
<point key="canvasLocation" x="253" y="254"/>
</tableViewCell>
</objects>
</document>
@@ -0,0 +1,15 @@
//
// SystemNotificationViewController.h
// NIM
//
// Created by amao on 3/17/15.
// Copyright (c) 2015 Netease. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface NTESSystemNotificationViewController : UIViewController
@property (nonatomic, strong) IBOutlet UITableView *tableView;
@end
@@ -0,0 +1,309 @@
//
// SystemNotificationViewController.m
// NIM
//
// Created by amao on 3/17/15.
// Copyright (c) 2015 Netease. All rights reserved.
//
#import "NTESSystemNotificationViewController.h"
#import <NIMSDK/NIMSDK.h>
#import "NTESSystemNotificationCell.h"
#import "Toast+UIView.h"
static const NSInteger MaxNotificationCount = 20;
static NSString *reuseIdentifier = @"reuseIdentifier";
@interface NTESSystemNotificationViewController ()<NIMSystemNotificationManagerDelegate,NIMSystemNotificationCellDelegate,NIMTeamManagerDelegate>
@property (nonatomic,strong) NSMutableArray *notifications;
@property (nonatomic,assign) BOOL shouldMarkAsRead;
@end
@implementation NTESSystemNotificationViewController
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.edgesForExtendedLayout = UIRectEdgeAll;
}
return self;
}
- (void)dealloc
{
if (_shouldMarkAsRead)
{
[[[NIMSDK sharedSDK] systemNotificationManager] markAllNotificationsAsRead];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = @"验证消息";
[self.tableView registerNib:[UINib nibWithNibName:@"NTESSystemNotificationCell" bundle:nil]
forCellReuseIdentifier:reuseIdentifier];
_notifications = [NSMutableArray array];
id<NIMSystemNotificationManager> systemNotificationManager = [[NIMSDK sharedSDK] systemNotificationManager];
[systemNotificationManager addDelegate:self];
NSArray *notifications = [systemNotificationManager fetchSystemNotifications:nil
limit:MaxNotificationCount];
if ([notifications count])
{
[_notifications addObjectsFromArray:notifications];
if (![[notifications firstObject] read])
{
_shouldMarkAsRead = YES;
}
}
if (notifications.count >= MaxNotificationCount) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
[button setFrame:CGRectMake(0, 0, 320, 40)];
[button addTarget:self
action:@selector(loadMore:)
forControlEvents:UIControlEventTouchUpInside];
[button setTitle:@"载入更多" forState:UIControlStateNormal];
self.tableView.tableFooterView = button;
}else{
self.tableView.tableFooterView = [[UIView alloc] init];
}
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"清空"
style:UIBarButtonItemStylePlain
target:self
action:@selector(clearAll:)];
}
- (void)loadMore:(id)sender
{
NSArray *notifications = [[[NIMSDK sharedSDK] systemNotificationManager] fetchSystemNotifications:[_notifications lastObject]
limit:MaxNotificationCount];
if ([notifications count])
{
[_notifications addObjectsFromArray:notifications];
[self.tableView reloadData];
}
}
- (void)clearAll:(id)sender
{
[[[NIMSDK sharedSDK] systemNotificationManager] deleteAllNotifications];
[_notifications removeAllObjects];
[self.tableView reloadData];
}
- (void)onReceiveSystemNotification:(NIMSystemNotification *)notification
{
[_notifications insertObject:notification atIndex:0];
_shouldMarkAsRead = YES;
[self.tableView reloadData];
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_notifications count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NTESSystemNotificationCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
NIMSystemNotification *notification = [_notifications objectAtIndex:[indexPath row]];
[cell update:notification];
cell.actionDelegate = self;
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSInteger index = [indexPath row];
NIMSystemNotification *notification = [_notifications objectAtIndex:index];
[_notifications removeObjectAtIndex:index];
[[[NIMSDK sharedSDK] systemNotificationManager] deleteNotification:notification];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
#pragma mark - SystemNotificationCell
- (void)onAccept:(NIMSystemNotification *)notification
{
__weak typeof(self) wself = self;
switch (notification.type) {
case NIMSystemNotificationTypeTeamApply:{
[[NIMSDK sharedSDK].teamManager passApplyToTeam:notification.targetID userId:notification.sourceID completion:^(NSError *error, NIMTeamApplyStatus applyStatus) {
if (!error) {
[wself.navigationController.view makeToast:@"同意成功"
];
notification.handleStatus = NotificationHandleTypeOk;
[wself.tableView reloadData];
}else {
if(error.code == NIMRemoteErrorCodeTimeoutError) {
[wself.navigationController.view makeToast:@"网络问题,请重试"
];
} else {
notification.handleStatus = NotificationHandleTypeOutOfDate;
}
[wself.tableView reloadData];
NSLog(@"%@",error.localizedDescription);
}
}];
break;
}
case NIMSystemNotificationTypeTeamInvite:{
[[NIMSDK sharedSDK].teamManager acceptInviteWithTeam:notification.targetID invitorId:notification.sourceID completion:^(NSError *error) {
if (!error) {
[wself.navigationController.view makeToast:@"接受成功"
];
notification.handleStatus = NotificationHandleTypeOk;
[wself.tableView reloadData];
}else {
if(error.code == NIMRemoteErrorCodeTimeoutError) {
[wself.navigationController.view makeToast:@"网络问题,请重试"
];
}
else if (error.code == NIMRemoteErrorCodeTeamNotExists) {
[wself.navigationController.view makeToast:@"群不存在"
];
}
else {
notification.handleStatus = NotificationHandleTypeOutOfDate;
}
[wself.tableView reloadData];
NSLog(@"%@",error.localizedDescription);
}
}];
}
break;
case NIMSystemNotificationTypeFriendAdd:
{
NIMUserRequest *request = [[NIMUserRequest alloc] init];
request.userId = notification.sourceID;
request.operation = NIMUserOperationVerify;
[[[NIMSDK sharedSDK] userManager] requestFriend:request
completion:^(NSError *error) {
if (!error) {
[wself.navigationController.view makeToast:@"验证成功"
];
notification.handleStatus = NotificationHandleTypeOk;
}
else
{
[wself.navigationController.view makeToast:@"验证失败,请重试"
];
}
[wself.tableView reloadData];
NSLog(@"%@",error.localizedDescription);
}];
}
break;
default:
break;
}
}
- (void)onRefuse:(NIMSystemNotification *)notification
{
__weak typeof(self) wself = self;
switch (notification.type) {
case NIMSystemNotificationTypeTeamApply:{
[[NIMSDK sharedSDK].teamManager rejectApplyToTeam:notification.targetID userId:notification.sourceID rejectReason:@"" completion:^(NSError *error) {
if (!error) {
[wself.navigationController.view makeToast:@"拒绝成功"
];
notification.handleStatus = NotificationHandleTypeNo;
[wself.tableView reloadData];
}else {
if(error.code == NIMRemoteErrorCodeTimeoutError) {
[wself.navigationController.view makeToast:@"网络问题,请重试"
];
} else {
notification.handleStatus = NotificationHandleTypeOutOfDate;
}
[wself.tableView reloadData];
NSLog(@"%@",error.localizedDescription);
}
}];
}
break;
case NIMSystemNotificationTypeTeamInvite:{
[[NIMSDK sharedSDK].teamManager rejectInviteWithTeam:notification.targetID invitorId:notification.sourceID rejectReason:@"" completion:^(NSError *error) {
if (!error) {
[wself.navigationController.view makeToast:@"拒绝成功"
];
notification.handleStatus = NotificationHandleTypeNo;
[wself.tableView reloadData];
}else {
if(error.code == NIMRemoteErrorCodeTimeoutError) {
[wself.navigationController.view makeToast:@"网络问题,请重试"
];
}
else if (error.code == NIMRemoteErrorCodeTeamNotExists) {
[wself.navigationController.view makeToast:@"群不存在"
];
}
else {
notification.handleStatus = NotificationHandleTypeOutOfDate;
}
[wself.tableView reloadData];
NSLog(@"%@",error.localizedDescription);
}
}];
}
break;
case NIMSystemNotificationTypeFriendAdd:
{
NIMUserRequest *request = [[NIMUserRequest alloc] init];
request.userId = notification.sourceID;
request.operation = NIMUserOperationReject;
[[[NIMSDK sharedSDK] userManager] requestFriend:request
completion:^(NSError *error) {
if (!error) {
[wself.navigationController.view makeToast:@"拒绝成功"
];
notification.handleStatus = NotificationHandleTypeNo;
}
else
{
[wself.navigationController.view makeToast:@"拒绝失败,请重试"
];
}
[wself.tableView reloadData];
NSLog(@"%@",error.localizedDescription);
}];
}
break;
default:
break;
}
}
@end
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="NTESSystemNotificationViewController">
<connections>
<outlet property="tableView" destination="i5M-Pr-FkT" id="DqO-c3-r6s"/>
<outlet property="view" destination="1D7-OJ-ULL" id="BLc-HR-rec"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="1D7-OJ-ULL">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<tableView opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" bouncesZoom="NO" style="plain" rowHeight="72" sectionHeaderHeight="22" sectionFooterHeight="22" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<connections>
<outlet property="dataSource" destination="-1" id="Tng-2m-Rnh"/>
<outlet property="delegate" destination="-1" id="9aC-8N-iBw"/>
</connections>
</tableView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</view>
</objects>
</document>