更新时间: 2021-03-08
# 功能描述
开发者可根据下面步骤集成位置共享功能。
# 效果展示


# 集成步骤
下面以 Demo
中的代码为例,说明集成步骤。以下代码,可以在 SealTalk
的 RCDChatViewController.m
中找到。
SealTalk 源码下载地址 (opens new window)
- 导入功能包
将源码中的 Sections/Chat/RealTimeLocation 导入工程
- 引入头文件
在会话页面中导入下面头文件
#import "RealTimeLocationEndCell.h" #import "RealTimeLocationStartCell.h" #import "RealTimeLocationStatusView.h" #import "RealTimeLocationViewController.h" #import "RealTimeLocationDefine.h" static const char *kRealTimeLocationKey = "kRealTimeLocationKey"; static const char *kRealTimeLocationStatusViewKey = "kRealTimeLocationStatusViewKey";
已复制
1
2
3
4
5
6
7
2
3
4
5
6
7
- 设置协议和代理
@interface RCDChatViewController () < RCRealTimeLocationObserver, RealTimeLocationStatusViewDelegate> @property(nonatomic, weak) id<RCRealTimeLocationProxy> realTimeLocation; @property(nonatomic, strong) RealTimeLocationStatusView *realTimeLocationStatusView;
已复制
1
2
3
4
5
2
3
4
5
- 初始化状态 View
- (void)initRealTimeLocationStatusView { self.realTimeLocationStatusView = [[RealTimeLocationStatusView alloc] initWithFrame:CGRectMake(0, 62, self.view.frame.size.width, 0)]; self.realTimeLocationStatusView.delegate = self; [self.view addSubview:self.realTimeLocationStatusView]; }
已复制
1
2
3
4
5
6
2
3
4
5
6
- 注册消息
- (void)registerRealTimeLocationCell { [self initRealTimeLocationStatusView]; [self registerClass:[RealTimeLocationStartCell class] forMessageClass:[RCRealTimeLocationStartMessage class]]; [self registerClass:[RealTimeLocationEndCell class] forMessageClass:[RCRealTimeLocationEndMessage class]]; }
已复制
1
2
3
4
5
2
3
4
5
- 获取服务
获取实时位置共享服务
//RCDChatViewController Class //获取实时位置共享代理 - (void)getRealTimeLocationProxy { __weak typeof(self) weakSelf = self; [[RCRealTimeLocationManager sharedManager] getRealTimeLocationProxy:self.conversationType targetId:self.targetId success:^(id<RCRealTimeLocationProxy> realTimeLocation) { weakSelf.realTimeLocation = realTimeLocation; [weakSelf.realTimeLocation addRealTimeLocationObserver:weakSelf]; [weakSelf updateRealTimeLocationStatus]; } error:^(RCRealTimeLocationErrorCode status) { NSLog(@"get location share failure with code %d", (int)status); }]; }
已复制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- 弹出位置实时共享
在点击位置时弹出位置实时共享
//RCDChatViewController Class - (void)pluginBoardView:(RCPluginBoardView *)pluginBoardView clickedItemWithTag:(NSInteger)tag { switch (tag) { case PLUGIN_BOARD_ITEM_LOCATION_TAG: { if (self.realTimeLocation) { UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:RCDLocalizedString(@"cancel") style:UIAlertActionStyleCancel handler:nil]; UIAlertAction *sendLocationAction = [UIAlertAction actionWithTitle:RCDLocalizedString(@"send_location") style:UIAlertActionStyleDefault handler:^(UIAlertAction *_Nonnull action) { [super pluginBoardView:self.chatSessionInputBarControl.pluginBoardView clickedItemWithTag:PLUGIN_BOARD_ITEM_LOCATION_TAG]; }]; UIAlertAction *locationShareAction = [UIAlertAction actionWithTitle:RCDLocalizedString(@"location_share") style:UIAlertActionStyleDefault handler:^(UIAlertAction *_Nonnull action) { [self showRealTimeLocationViewController]; }]; [RCKitUtility showAlertController:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet actions:@[ cancelAction, sendLocationAction, locationShareAction ] inViewController:self]; } else { [super pluginBoardView:pluginBoardView clickedItemWithTag:tag]; } } break;
已复制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
- 代理方法
实时位置共享监听代理方法
//RCDChatViewController Class - (void)onRealTimeLocationStatusChange:(RCRealTimeLocationStatus)status { __weak typeof(self) weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf updateRealTimeLocationStatus]; }); } - (void)onReceiveLocation:(CLLocation *)location type:(RCRealTimeLocationType)type fromUserId:(NSString *)userId { __weak typeof(self) weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf updateRealTimeLocationStatus]; }); } - (void)onParticipantsJoin:(NSString *)userId { __weak typeof(self) weakSelf = self; if ([userId isEqualToString:[RCIMClient sharedRCIMClient].currentUserInfo.userId]) { [self notifyParticipantChange:RCDLocalizedString(@"you_join_location_share")]; } else { [[RCIM sharedRCIM] .userInfoDataSource getUserInfoWithUserId:userId completion:^(RCUserInfo *userInfo) { if (userInfo.name.length) { [weakSelf notifyParticipantChange:[NSString stringWithFormat:RCDLocalizedString(@"someone_join_share_location"),userInfo.name]]; } else { [weakSelf notifyParticipantChange:[NSString stringWithFormat:RCDLocalizedString(@"user_join_share_location"),userId]]; } }]; } } - (void)onParticipantsQuit:(NSString *)userId { __weak typeof(self) weakSelf = self; if ([userId isEqualToString:[RCIMClient sharedRCIMClient].currentUserInfo.userId]) { [self notifyParticipantChange:RCDLocalizedString(@"you_quit_location_share")]; } else { [[RCIM sharedRCIM] .userInfoDataSource getUserInfoWithUserId:userId completion:^(RCUserInfo *userInfo) { if (userInfo.name.length) { [weakSelf notifyParticipantChange:[NSString stringWithFormat:RCDLocalizedString(@"someone_quit_location_share"),userInfo.name]]; } else { [weakSelf notifyParticipantChange:[NSString stringWithFormat:RCDLocalizedString(@"user_quit_location_share"),userId]]; } }]; } } - (void)onRealTimeLocationStartFailed:(long)messageId { dispatch_async(dispatch_get_main_queue(), ^{ for (int i = 0; i < self.conversationDataRepository.count; i++) { RCMessageModel *model = [self.conversationDataRepository objectAtIndex:i]; if (model.messageId == messageId) { model.sentStatus = SentStatus_FAILED; } } NSArray *visibleItem = [self.conversationMessageCollectionView indexPathsForVisibleItems]; for (int i = 0; i < visibleItem.count; i++) { NSIndexPath *indexPath = visibleItem[i]; RCMessageModel *model = [self.conversationDataRepository objectAtIndex:indexPath.row]; if (model.messageId == messageId) { [self.conversationMessageCollectionView reloadItemsAtIndexPaths:@[ indexPath ]]; } } }); } - (void)notifyParticipantChange:(NSString *)text { __weak typeof(self) weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf.realTimeLocationStatusView updateText:text]; [weakSelf performSelector:@selector(updateRealTimeLocationStatus) withObject:nil afterDelay:0.5]; }); } - (void)onFailUpdateLocation:(NSString *)description { } #pragma mark - 实时位置共享状态 view 代理方法 - (void)onJoin { [self showRealTimeLocationViewController]; } - (RCRealTimeLocationStatus)getStatus { return [self.realTimeLocation getStatus]; } - (void)onShowRealTimeLocationView { [self showRealTimeLocationViewController]; } - (void)setRealTimeLocation:(id<RCRealTimeLocationProxy>)realTimeLocation { objc_setAssociatedObject(self, kRealTimeLocationKey, realTimeLocation, OBJC_ASSOCIATION_ASSIGN); } - (id<RCRealTimeLocationProxy>)realTimeLocation { return objc_getAssociatedObject(self, kRealTimeLocationKey); } - (void)setRealTimeLocationStatusView:(RealTimeLocationStatusView *)realTimeLocationStatusView { objc_setAssociatedObject(self, kRealTimeLocationStatusViewKey, realTimeLocationStatusView, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (RealTimeLocationStatusView *)realTimeLocationStatusView { return objc_getAssociatedObject(self, kRealTimeLocationStatusViewKey); }
已复制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
当前类中相关私有方法
//弹出实时位置共享页面 - (void)showRealTimeLocationViewController { RealTimeLocationViewController *lsvc = [[RealTimeLocationViewController alloc] init]; lsvc.realTimeLocationProxy = self.realTimeLocation; if ([self.realTimeLocation getStatus] == RC_REAL_TIME_LOCATION_STATUS_INCOMING) { [self.realTimeLocation joinRealTimeLocation]; } else if ([self.realTimeLocation getStatus] == RC_REAL_TIME_LOCATION_STATUS_IDLE) { [self.realTimeLocation startRealTimeLocation]; } lsvc.modalPresentationStyle = UIModalPresentationFullScreen; [self.navigationController presentViewController:lsvc animated:YES completion:^{ }]; } //更新实时位置共享状态 - (void)updateRealTimeLocationStatus { if (self.realTimeLocation) { [self.realTimeLocationStatusView updateRealTimeLocationStatus]; __weak typeof(self) weakSelf = self; NSArray *participants = nil; switch ([self.realTimeLocation getStatus]) { case RC_REAL_TIME_LOCATION_STATUS_OUTGOING: [self.realTimeLocationStatusView updateText:RTLLocalizedString(@"you_location_sharing")]; break; case RC_REAL_TIME_LOCATION_STATUS_CONNECTED: case RC_REAL_TIME_LOCATION_STATUS_INCOMING: participants = [self.realTimeLocation getParticipants]; if (participants.count == 1) { NSString *userId = participants[0]; [weakSelf.realTimeLocationStatusView updateText:[NSString stringWithFormat:RTLLocalizedString(@"user_location_sharing"), userId]]; [[RCIM sharedRCIM] .userInfoDataSource getUserInfoWithUserId:userId completion:^(RCUserInfo *userInfo) { if (userInfo.name.length) { dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf.realTimeLocationStatusView updateText:[NSString stringWithFormat:RTLLocalizedString(@"someone_location_sharing"),userInfo.name]]; }); } }]; } else { if (participants.count < 1) [self.realTimeLocationStatusView removeFromSuperview]; else [self.realTimeLocationStatusView updateText:[NSString stringWithFormat:@"%d人正在共享地理位置", (int)participants.count]]; } break; default: break; } } }
已复制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
- 实时位置共享功能仅支持单聊。
- 将上面所有方法以及方法中相关的的代码都拷贝到工程中,就可以正常使用位置实时共享功能了。
- 参与位置实时共享人员的用户信息需要提前设置好,具体方法参考 设置用户信息。