Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
galaxy-iOS
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mobile-group
galaxy-iOS
Commits
16e049a2
Commit
16e049a2
authored
Nov 27, 2024
by
Alex朱枝文
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
im流程整理
parent
47d012ef
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
330 additions
and
0 deletions
+330
-0
project.pbxproj
galaxy/galaxy.xcodeproj/project.pbxproj
+4
-0
AppDelegate.swift
galaxy/galaxy/AppDelegate.swift
+2
-0
YHIMHelper.swift
...ses/Modules/LivestreamSales(直播销售)/IM(环信)/YHIMHelper.swift
+324
-0
No files found.
galaxy/galaxy.xcodeproj/project.pbxproj
View file @
16e049a2
...
@@ -306,6 +306,7 @@
...
@@ -306,6 +306,7 @@
04564D6C2CF6C414004456E4
/* YHLivePlayerViewController+Api.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
04564D6B2CF6C414004456E4
/* YHLivePlayerViewController+Api.swift */
;
};
04564D6C2CF6C414004456E4
/* YHLivePlayerViewController+Api.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
04564D6B2CF6C414004456E4
/* YHLivePlayerViewController+Api.swift */
;
};
04564D6E2CF6EB3D004456E4
/* YHHuanXinUserModel.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
04564D6D2CF6EB3D004456E4
/* YHHuanXinUserModel.swift */
;
};
04564D6E2CF6EB3D004456E4
/* YHHuanXinUserModel.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
04564D6D2CF6EB3D004456E4
/* YHHuanXinUserModel.swift */
;
};
04564D702CF6EC8A004456E4
/* YHRecordedDetailModel.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
04564D6F2CF6EC8A004456E4
/* YHRecordedDetailModel.swift */
;
};
04564D702CF6EC8A004456E4
/* YHRecordedDetailModel.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
04564D6F2CF6EC8A004456E4
/* YHRecordedDetailModel.swift */
;
};
04564D722CF6F18A004456E4
/* YHIMHelper.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
04564D712CF6F18A004456E4
/* YHIMHelper.swift */
;
};
0457920B2CBCE7B200EBD99B
/* YHResignUploadTravelCardViewModel.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
0457920A2CBCE7B200EBD99B
/* YHResignUploadTravelCardViewModel.swift */
;
};
0457920B2CBCE7B200EBD99B
/* YHResignUploadTravelCardViewModel.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
0457920A2CBCE7B200EBD99B
/* YHResignUploadTravelCardViewModel.swift */
;
};
0457920D2CBCE8A800EBD99B
/* YHResignUploadTravelCardListModel.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
0457920C2CBCE8A800EBD99B
/* YHResignUploadTravelCardListModel.swift */
;
};
0457920D2CBCE8A800EBD99B
/* YHResignUploadTravelCardListModel.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
0457920C2CBCE8A800EBD99B
/* YHResignUploadTravelCardListModel.swift */
;
};
0457920F2CBCE9D000EBD99B
/* YHResignUploadTravelCardListTableViewCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
0457920E2CBCE9D000EBD99B
/* YHResignUploadTravelCardListTableViewCell.swift */
;
};
0457920F2CBCE9D000EBD99B
/* YHResignUploadTravelCardListTableViewCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
0457920E2CBCE9D000EBD99B
/* YHResignUploadTravelCardListTableViewCell.swift */
;
};
...
@@ -1364,6 +1365,7 @@
...
@@ -1364,6 +1365,7 @@
04564D6B2CF6C414004456E4
/* YHLivePlayerViewController+Api.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
"YHLivePlayerViewController+Api.swift"
;
sourceTree
=
"<group>"
;
};
04564D6B2CF6C414004456E4
/* YHLivePlayerViewController+Api.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
"YHLivePlayerViewController+Api.swift"
;
sourceTree
=
"<group>"
;
};
04564D6D2CF6EB3D004456E4
/* YHHuanXinUserModel.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
YHHuanXinUserModel.swift
;
sourceTree
=
"<group>"
;
};
04564D6D2CF6EB3D004456E4
/* YHHuanXinUserModel.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
YHHuanXinUserModel.swift
;
sourceTree
=
"<group>"
;
};
04564D6F2CF6EC8A004456E4
/* YHRecordedDetailModel.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
YHRecordedDetailModel.swift
;
sourceTree
=
"<group>"
;
};
04564D6F2CF6EC8A004456E4
/* YHRecordedDetailModel.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
YHRecordedDetailModel.swift
;
sourceTree
=
"<group>"
;
};
04564D712CF6F18A004456E4
/* YHIMHelper.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
YHIMHelper.swift
;
sourceTree
=
"<group>"
;
};
0457920A2CBCE7B200EBD99B
/* YHResignUploadTravelCardViewModel.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
YHResignUploadTravelCardViewModel.swift
;
sourceTree
=
"<group>"
;
};
0457920A2CBCE7B200EBD99B
/* YHResignUploadTravelCardViewModel.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
YHResignUploadTravelCardViewModel.swift
;
sourceTree
=
"<group>"
;
};
0457920C2CBCE8A800EBD99B
/* YHResignUploadTravelCardListModel.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
YHResignUploadTravelCardListModel.swift
;
sourceTree
=
"<group>"
;
};
0457920C2CBCE8A800EBD99B
/* YHResignUploadTravelCardListModel.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
YHResignUploadTravelCardListModel.swift
;
sourceTree
=
"<group>"
;
};
0457920E2CBCE9D000EBD99B
/* YHResignUploadTravelCardListTableViewCell.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
YHResignUploadTravelCardListTableViewCell.swift
;
sourceTree
=
"<group>"
;
};
0457920E2CBCE9D000EBD99B
/* YHResignUploadTravelCardListTableViewCell.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
YHResignUploadTravelCardListTableViewCell.swift
;
sourceTree
=
"<group>"
;
};
...
@@ -2984,6 +2986,7 @@
...
@@ -2984,6 +2986,7 @@
isa
=
PBXGroup
;
isa
=
PBXGroup
;
children
=
(
children
=
(
A574C8CE2CF4A95900E1E586
/* C */
,
A574C8CE2CF4A95900E1E586
/* C */
,
04564D712CF6F18A004456E4
/* YHIMHelper.swift */
,
);
);
path
=
"IM(环信)"
;
path
=
"IM(环信)"
;
sourceTree
=
"<group>"
;
sourceTree
=
"<group>"
;
...
@@ -6069,6 +6072,7 @@
...
@@ -6069,6 +6072,7 @@
A53A350B2CE88B86002FE6A3
/* YHSingleOptionalItemsView.swift in Sources */
,
A53A350B2CE88B86002FE6A3
/* YHSingleOptionalItemsView.swift in Sources */
,
045EEE982B9F171A0022A143
/* YHPreviewInfoQuestionAndAnswerItemsView.swift in Sources */
,
045EEE982B9F171A0022A143
/* YHPreviewInfoQuestionAndAnswerItemsView.swift in Sources */
,
045EEE7A2B9F171A0022A143
/* YHPreviewForOtherInfoModel.swift in Sources */
,
045EEE7A2B9F171A0022A143
/* YHPreviewForOtherInfoModel.swift in Sources */
,
04564D722CF6F18A004456E4
/* YHIMHelper.swift in Sources */
,
0414BDA92BC7E81500225367
/* YHMyPermissionSettingVC.swift in Sources */
,
0414BDA92BC7E81500225367
/* YHMyPermissionSettingVC.swift in Sources */
,
047F3DE22CE72524001B2A6D
/* YHMyNewSchemeViewController.swift in Sources */
,
047F3DE22CE72524001B2A6D
/* YHMyNewSchemeViewController.swift in Sources */
,
A567E5AA2BD7643D00D5D5A0
/* YHGestureTableView.swift in Sources */
,
A567E5AA2BD7643D00D5D5A0
/* YHGestureTableView.swift in Sources */
,
...
...
galaxy/galaxy/AppDelegate.swift
View file @
16e049a2
...
@@ -80,7 +80,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, WXApiDelegate {
...
@@ -80,7 +80,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, WXApiDelegate {
//初始化 环信IM SDK
//初始化 环信IM SDK
DispatchQueue
.
main
.
async
{
DispatchQueue
.
main
.
async
{
let
options
:
EMOptions
=
EMOptions
(
appkey
:
"1126241122157016#demo"
)
let
options
:
EMOptions
=
EMOptions
(
appkey
:
"1126241122157016#demo"
)
options
.
isAutoLogin
=
false
EMClient
.
shared
()
.
initializeSDK
(
with
:
options
)
EMClient
.
shared
()
.
initializeSDK
(
with
:
options
)
_
=
YHIMHelper
.
sharedHelper
()
}
}
//设置主窗口
//设置主窗口
...
...
galaxy/galaxy/Classes/Modules/LivestreamSales(直播销售)/IM(环信)/YHIMHelper.swift
0 → 100644
View file @
16e049a2
//
// YHIMHelper.swift
// galaxy
//
// Created by alexzzw on 2024/11/27.
// Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
import
HyphenateChat
import
UIKit
class
YHIMHelper
:
NSObject
{
static
let
didLoginEaseIMSuccess
=
Notification
.
Name
(
"com.YHIMHelper.didLoginEaseIMSuccess"
)
static
let
didLogOutEaseIM
=
Notification
.
Name
(
"com.YHIMHelper.didLogOutEaseIM"
)
static
let
didChatManagerReceiveMessages
=
Notification
.
Name
(
"com.YHIMHelper.didChatManagerReceiveMessages"
)
private
let
viewModel
=
YHLiveSalesViewModel
()
var
isCurrentUserLogin
:
Bool
{
guard
let
userId
=
YHLoginManager
.
shared
.
userModel
?
.
id
,
userId
.
count
>
0
else
{
return
false
}
if
EMClient
.
shared
()
.
isLoggedIn
,
EMClient
.
shared
()
.
currentUsername
==
"
\(
userId
)
"
{
return
true
}
return
false
}
static
let
shared
:
YHIMHelper
=
{
let
helper
=
YHIMHelper
()
return
helper
}()
static
func
sharedHelper
()
->
YHIMHelper
{
return
shared
}
override
private
init
()
{
super
.
init
()
initHelper
()
setupNotification
()
registerAndLoginCurrentUser
{
success
in
printLog
(
"registerAndLoginCurrentUser:
\(
success
)
"
)
}
}
deinit
{
EMClient
.
shared
()
.
remove
(
self
)
EMClient
.
shared
()
.
removeDelegate
(
self
)
EMClient
.
shared
()
.
roomManager
?
.
remove
(
self
)
EMClient
.
shared
()
.
chatManager
?
.
remove
(
self
)
NotificationCenter
.
default
.
removeObserver
(
self
)
}
private
func
initHelper
()
{
EMClient
.
shared
()
.
addMultiDevices
(
delegate
:
self
,
queue
:
nil
)
EMClient
.
shared
()
.
add
(
self
,
delegateQueue
:
nil
)
EMClient
.
shared
()
.
roomManager
?
.
add
(
self
,
delegateQueue
:
nil
)
EMClient
.
shared
()
.
chatManager
?
.
add
(
self
,
delegateQueue
:
nil
)
}
private
func
setupNotification
()
{
NotificationCenter
.
default
.
addObserver
(
self
,
selector
:
#selector(
loginSuccess
)
,
name
:
YhConstant
.
YhNotification
.
didLoginSuccessNotifiction
,
object
:
nil
)
NotificationCenter
.
default
.
addObserver
(
self
,
selector
:
#selector(
logoutSuccess
)
,
name
:
YhConstant
.
YhNotification
.
didLogoutSuccessNotifiction
,
object
:
nil
)
}
func
registerAndLoginCurrentUser
(
completion
:
@escaping
(
Bool
)
->
Void
)
{
guard
let
userId
=
YHLoginManager
.
shared
.
userModel
?
.
id
,
userId
.
count
>
0
else
{
completion
(
false
)
return
}
viewModel
.
registerHuanXinUser
{
[
weak
self
]
success
,
_
in
guard
let
self
=
self
else
{
completion
(
false
)
return
}
// 注册成功
if
success
{
viewModel
.
getHuanXinToken
{
[
weak
self
]
tokenModel
,
_
in
guard
let
tokenModel
=
tokenModel
else
{
completion
(
false
)
return
}
guard
let
self
=
self
else
{
completion
(
false
)
return
}
let
token
=
tokenModel
.
accessToken
self
.
loginEaseIM
(
name
:
"
\(
userId
)
"
,
token
:
token
)
{
success
in
completion
(
success
)
}
}
}
}
}
func
getToken
()
{
guard
let
userId
=
YHLoginManager
.
shared
.
userModel
?
.
id
,
userId
.
count
>
0
else
{
return
}
viewModel
.
getHuanXinToken
{
tokenModel
,
_
in
guard
let
tokenModel
=
tokenModel
else
{
return
}
}
}
@objc
private
func
loginSuccess
()
{
registerAndLoginCurrentUser
{
_
in
//
}
}
@objc
private
func
logoutSuccess
()
{
logoutEaseIM
{
_
in
//
}
}
}
extension
YHIMHelper
{
/// 登录环信
func
loginEaseIM
(
name
:
String
,
token
:
String
,
completion
:
@escaping
(
Bool
)
->
Void
)
{
let
loginEvent
=
{
EMClient
.
shared
()
.
login
(
withUsername
:
name
.
lowercased
(),
token
:
token
)
{
_
,
err
in
DispatchQueue
.
main
.
async
{
guard
let
err
=
err
else
{
NotificationCenter
.
default
.
post
(
name
:
YHIMHelper
.
didLoginEaseIMSuccess
,
object
:
nil
)
completion
(
true
)
return
}
// 已经登录
if
err
.
code
==
.
userAlreadyLoginSame
{
completion
(
true
)
NotificationCenter
.
default
.
post
(
name
:
YHIMHelper
.
didLoginEaseIMSuccess
,
object
:
nil
)
}
else
{
completion
(
false
)
}
printLog
(
"
\(
err
)
"
)
}
}
}
if
EMClient
.
shared
()
.
isLoggedIn
{
logoutEaseIM
(
unbindDeviceToken
:
true
,
completion
:
{
_
in
loginEvent
()
})
}
else
{
loginEvent
()
}
}
/// 登出环信
func
logoutEaseIM
(
unbindDeviceToken
:
Bool
=
true
,
completion
:
@escaping
(
EMError
?)
->
Void
)
{
EMClient
.
shared
()
.
logout
(
unbindDeviceToken
)
{
err
in
DispatchQueue
.
main
.
async
{
completion
(
err
)
guard
let
err
=
err
else
{
NotificationCenter
.
default
.
post
(
name
:
YHIMHelper
.
didLogOutEaseIM
,
object
:
nil
)
completion
(
nil
)
return
}
printLog
(
"
\(
err
)
"
)
}
}
}
/// 获取聊天室人数
func
fetchRoomMemberList
(
roomID
:
String
,
completion
:
@escaping
(
Int
?,
EMError
?)
->
Void
)
{
EMClient
.
shared
()
.
roomManager
?
.
getChatroomMemberListFromServer
(
withId
:
roomID
,
cursor
:
nil
,
pageSize
:
20
,
completion
:
{
result
,
error
in
DispatchQueue
.
main
.
async
{
if
let
err
=
error
{
printLog
(
"
\(
err
)
"
)
completion
(
nil
,
err
)
}
else
{
var
count
:
Int
=
0
if
let
ret
=
result
{
count
=
(
ret
.
list
?
.
count
??
0
)
+
1
printLog
(
"聊天室人数:
\(
count
)
"
)
}
completion
(
count
,
nil
)
}
}
})
}
/// 获取聊天室历史消息
func
fetchHistoryMessage
(
roomID
:
String
,
completion
:
@escaping
([
EMChatMessage
]?,
EMError
?)
->
Void
)
{
let
option
=
EMFetchServerMessagesOption
()
EMClient
.
shared
()
.
chatManager
?
.
fetchMessagesFromServer
(
by
:
roomID
,
conversationType
:
.
chatRoom
,
cursor
:
nil
,
pageSize
:
50
,
option
:
option
,
completion
:
{
result
,
err
in
DispatchQueue
.
main
.
async
{
if
let
err
=
err
{
// 获取失败
printLog
(
"获取历史消息--失败"
)
printLog
(
err
)
completion
(
nil
,
err
)
}
else
{
// 获取成功
printLog
(
result
)
if
let
ret
=
result
,
let
arr
=
ret
.
list
,
arr
.
count
>
0
{
printLog
(
"获取历史消息
\(
arr
.
count
)
条"
)
}
else
{
printLog
(
"获取历史消息 (0) 条"
)
}
completion
(
result
?
.
list
as?
[
EMChatMessage
],
err
)
}
}
})
}
/// 加入聊天室
func
joinChatRoom
(
roomID
:
String
,
nickname
:
String
,
leaveOtherRooms
:
Bool
,
completion
:
@escaping
(
EMError
?)
->
Void
)
{
EMClient
.
shared
()
.
roomManager
?
.
joinChatroom
(
roomID
,
ext
:
"fromNickName=
\(
nickname
)
"
,
leaveOtherRooms
:
leaveOtherRooms
,
completion
:
{
_
,
err
in
DispatchQueue
.
main
.
async
{
if
let
err
=
err
{
printLog
(
err
.
errorDescription
)
}
else
{
printLog
(
"加入聊天室-成功"
)
}
completion
(
err
)
}
})
}
/// 退出聊天室
func
quitChatRoom
(
roomID
:
String
,
completion
:
@escaping
(
EMError
?)
->
Void
)
{
EMClient
.
shared
()
.
roomManager
?
.
leaveChatroom
(
roomID
,
completion
:
{
err
in
DispatchQueue
.
main
.
async
{
if
let
error
=
err
{
printLog
(
error
.
errorDescription
)
}
else
{
printLog
(
"退出聊天室-成功"
)
}
completion
(
err
)
}
})
}
/// 发送消息
func
sendMessage
(
roomID
:
String
,
nickname
:
String
,
sendText
:
String
,
completion
:
@escaping
(
EMError
?)
->
Void
)
{
let
textMessageBody
=
EMTextMessageBody
(
text
:
sendText
)
// 消息接收方,单聊为对端用户的 ID,群聊为群组 ID,聊天室为聊天室 ID。
let
message
=
EMChatMessage
(
conversationID
:
roomID
,
body
:
textMessageBody
,
ext
:
[
"fromNickName"
:
nickname
])
// 会话类型,单聊为 `EMChatTypeChat`,群聊为 `EMChatTypeGroupChat`,聊天室为 `EMChatTypeChatRoom`,默认为单聊。
message
.
chatType
=
.
chatRoom
EMClient
.
shared
()
.
chatManager
?
.
send
(
message
,
progress
:
nil
,
completion
:
{
_
,
error
in
DispatchQueue
.
main
.
async
{
if
let
err
=
error
{
printLog
(
err
.
errorDescription
)
}
else
{
printLog
(
"消息发送-成功"
)
}
completion
(
error
)
}
})
}
}
extension
YHIMHelper
:
EMChatroomManagerDelegate
{
func
userDidJoin
(
_
aChatroom
:
EMChatroom
,
user
aUsername
:
String
,
ext
:
String
?)
{
printLog
(
"
\(
aChatroom
)
加入聊天室了1"
)
}
func
userDidJoin
(
_
aChatroom
:
EMChatroom
,
user
aUsername
:
String
)
{
let
memberCount
=
aChatroom
.
occupantsCount
printLog
(
memberCount
)
printLog
(
"
\(
aUsername
)
加入 聊天室了2"
)
}
func
userDidLeave
(
_
aChatroom
:
EMChatroom
,
user
aUsername
:
String
)
{
let
memberCount
=
aChatroom
.
occupantsCount
printLog
(
memberCount
)
printLog
(
"
\(
aUsername
)
离开 聊天室了"
)
}
}
extension
YHIMHelper
:
EMChatManagerDelegate
{
// 收到消息
func
messagesDidReceive
(
_
aMessages
:
[
EMChatMessage
])
{
/*
for (i, t) in aMessages.enumerated() {
printLog(t.ext)
var nickName: String = ""
if let ext = t.ext {
nickName = ext["fromNickName"] as? String ?? "YinHe"
}
if let body = t.body as? EMTextMessageBody, body.type == .text {
printLog(body.text)
printLog("\(nickName) : \(body.text)")
}
}
*/
NotificationCenter
.
default
.
post
(
name
:
YHIMHelper
.
didChatManagerReceiveMessages
,
object
:
aMessages
)
}
}
extension
YHIMHelper
:
EMClientDelegate
{
/// 自动登录
func
autoLoginDidCompleteWithError
(
_
aError
:
EMError
?)
{
guard
aError
==
nil
else
{
return
}
// 自动登录也发送提醒
NotificationCenter
.
default
.
post
(
name
:
YHIMHelper
.
didLoginEaseIMSuccess
,
object
:
nil
)
}
/// 被强制登出
func
userAccountDidForced
(
toLogout
aError
:
EMError
?)
{
guard
aError
==
nil
else
{
return
}
NotificationCenter
.
default
.
post
(
name
:
YHIMHelper
.
didLogOutEaseIM
,
object
:
nil
)
}
}
extension
YHIMHelper
:
EMMultiDevicesDelegate
{
func
multiDevicesContactEventDidReceive
(
_
aEvent
:
EMMultiDevicesEvent
,
username
aUsername
:
String
,
ext
aExt
:
String
?)
{
//
}
func
multiDevicesGroupEventDidReceive
(
_
aEvent
:
EMMultiDevicesEvent
,
groupId
aGroupId
:
String
,
ext
aExt
:
Any
?)
{
//
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment