diff --git a/plugin.xml b/plugin.xml
index c42209f..afc7d3d 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -20,128 +20,62 @@
-
-
-
--->
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
+
+
+
+
+
+
+
-
+
+
@@ -158,8 +92,8 @@
-
-用户没有允许需要的权限,加入通话失败
+
+ 用户没有允许需要的权限,加入通话失败
基础功能
语音通话
双人/多人语音通话、包含静音/免提等功能
@@ -211,7 +145,7 @@
-
+
@@ -258,7 +192,7 @@
-
+
diff --git a/src/android/java/com/tencent/trtc/CordovaEventKit.java b/src/android/java/com/tencent/trtc/CordovaEventKit.java
index 8af6b43..6ff1c90 100644
--- a/src/android/java/com/tencent/trtc/CordovaEventKit.java
+++ b/src/android/java/com/tencent/trtc/CordovaEventKit.java
@@ -17,6 +17,7 @@ public class CordovaEventKit {
}
public static void init(CordovaPlugin plugin){
+ Log.d(TAG, "init");
if(CordovaEventKit.kit == null){
CordovaEventKit.kit = new CordovaEventKit(plugin);
}
diff --git a/src/android/java/com/tencent/trtc/CustomVideoView.java b/src/android/java/com/tencent/trtc/CustomVideoView.java
index 286f6e5..0a62564 100644
--- a/src/android/java/com/tencent/trtc/CustomVideoView.java
+++ b/src/android/java/com/tencent/trtc/CustomVideoView.java
@@ -69,7 +69,7 @@ public class CustomVideoView extends RelativeLayout {
Log.d(TAG,"TRTC - changeUser: main?:"+mainView+",alwaysHide?:"+alwaysHide+",user:" + (userInfo == null ? null : userInfo.getPersonid()));
this.setBackgroundColor(Color.TRANSPARENT);
if(userInfo == null){
- setVisibility(View.GONE);;
+ setVisibility(View.GONE);
}else {
setVisibility(alwaysHide?INVISIBLE:VISIBLE);
}
@@ -88,7 +88,9 @@ public class CustomVideoView extends RelativeLayout {
mTRTCCloud.setRemoteRenderParams(this.userInfo.getPersonid(),mainView ? TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG : TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_SUB,params);
try {
- Thread.sleep(1000);
+ if(this.userInfo.isShareUser()){
+ Thread.sleep(1000);
+ }
} catch (InterruptedException e) {
e.printStackTrace();
}
@@ -133,12 +135,14 @@ public class CustomVideoView extends RelativeLayout {
}
public CustomVideoView setMainView(boolean mainView) {
+ Log.d(TAG,"TRTC - setMainView mainView:"+mainView);
if(this.mTRTCCloud == null){
this.mTRTCCloud = TRTCCloud.sharedInstance(mContext);
}
this.mainView = mainView;
if(!mainView){
Events.addListener("subview.always.hide",(extra)->{
+ Log.d(TAG,"TRTC - event listener (subview.always.hide):"+extra);
this.alwaysHide = extra.getBoolean("alwaysHide",false);
if(this.alwaysHide){
this.setVisibility(INVISIBLE);
@@ -161,6 +165,7 @@ public class CustomVideoView extends RelativeLayout {
});
}
Events.addListener("userinfo.update",(extra) -> {
+ Log.d(TAG,"TRTC - event listener (userinfo.update):"+extra + ",userinfo:"+this.userInfo);
if(this.userInfo !=null && !this.userInfo.isLocal() && extra.getString("userId").equals(this.userInfo.getPersonid())){
this.userInfo.setDisplayName(extra.getString("displayName"));
this.titleView.setText(this.userInfo.getDisplayName() + (this.userInfo.isShareUser() ? "的屏幕分享": ""));
diff --git a/src/android/java/com/tencent/trtc/videocall/UserInfo.java b/src/android/java/com/tencent/trtc/videocall/UserInfo.java
index 9527f43..8149d07 100644
--- a/src/android/java/com/tencent/trtc/videocall/UserInfo.java
+++ b/src/android/java/com/tencent/trtc/videocall/UserInfo.java
@@ -68,4 +68,14 @@ public class UserInfo {
}
return false;
}
+
+ @Override
+ public String toString() {
+ return "UserInfo{" +
+ "personid='" + personid + '\'' +
+ ", displayName='" + displayName + '\'' +
+ ", local=" + local +
+ ", frontCamera=" + frontCamera +
+ '}';
+ }
}
diff --git a/src/android/java/com/tencent/trtc/videocall/VideoCallingActivity.java b/src/android/java/com/tencent/trtc/videocall/VideoCallingActivity.java
index a598278..380e32d 100644
--- a/src/android/java/com/tencent/trtc/videocall/VideoCallingActivity.java
+++ b/src/android/java/com/tencent/trtc/videocall/VideoCallingActivity.java
@@ -347,6 +347,7 @@ public class VideoCallingActivity extends TRTCBaseActivity implements View.OnCli
@Override
public void onUserVideoAvailable(String userId, boolean available) {
+ super.onUserVideoAvailable(userId, available);
Log.d(TAG, "onUserVideoAvailable userId " + userId + ", mUserCount " + mUserCount + ",available " + available);
UserInfo info = new UserInfo().setPersonid(userId);
int index = mUserList.indexOf(info);
diff --git a/src/ios/CordovaEventKit.h b/src/ios/CordovaEventKit.h
new file mode 100644
index 0000000..f743900
--- /dev/null
+++ b/src/ios/CordovaEventKit.h
@@ -0,0 +1,22 @@
+//
+// CordovaEventKit.h
+// shuto-cne
+//
+// Created by 范大德 on 2022/3/18.
+//
+#import
+
+#ifndef CordovaEventKit_h
+#define CordovaEventKit_h
+
+
+#endif /* CordovaEventKit_h */
+@interface CordovaEventKit
+{}
++ (void)init: (CDVPlugin*)plugin;
+
++ (void) fireEvent:(NSString*)event obj:(NSDictionary*) obj;
+
++ (void) fireEvent:(NSString*) event msg:(NSString*) msg;
+
+@end
diff --git a/src/ios/CordovaEventKit.m b/src/ios/CordovaEventKit.m
new file mode 100644
index 0000000..4e09595
--- /dev/null
+++ b/src/ios/CordovaEventKit.m
@@ -0,0 +1,71 @@
+//
+// CordovaEventKit.m
+// 触发Cordova事件
+//
+// Created by 范大德 on 2022/3/18.
+//
+#import
+
+#import
+#import "CordovaEventKit.h"
+@interface CordovaEventKit()
+{}
+@end
+@implementation CordovaEventKit
+
+static CDVPlugin* cdvPlugin;
+
++ (void)init: (CDVPlugin*)plugin{
+ cdvPlugin = plugin;
+}
+
++ (void) fireEvent:(NSString*)event obj:(NSDictionary*) obj{
+ NSString* jsonData = [self toJSON:obj];
+ [CordovaEventKit fireEvent:event msg:jsonData];
+}
+
++ (void) fireEvent:(NSString*) event msg:(NSString*) msg{
+ NSLog(@"TRTC - CordovaEventKit::fireEvent --- event:%@,msg:%@",event,msg);
+
+ if (cdvPlugin == nil || event == nil || msg == nil) {
+ NSLog(@"TRTC - CordovaEventKit::fireEvent --- cdvPlugin%@,event:%@,msg:%@",cdvPlugin,event,msg);
+ return;
+ }
+ event = [event stringByReplacingOccurrencesOfString:@"\\" withString:@"_"];
+
+ NSString* js = [[NSString alloc] initWithFormat:@"window.cordova.plugin.trtc.fireEvent('%@',%@)", event, msg];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [cdvPlugin.commandDelegate evalJs:js];
+ });
+}
+
++(NSString*) toJSON:(NSDictionary*)obj{
+ NSError *error = nil;
+ NSData *jsonData = nil;
+ NSMutableDictionary *dict = [NSMutableDictionary dictionary];
+ [obj enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
+ NSString *keyString = nil;
+ NSString *valueString = nil;
+ if ([key isKindOfClass:[NSString class]]) {
+ keyString = key;
+ }else{
+ keyString = [NSString stringWithFormat:@"%@",key];
+ }
+
+ if ([obj isKindOfClass:[NSString class]]) {
+ valueString = obj;
+ }else{
+ valueString = [NSString stringWithFormat:@"%@",obj];
+ }
+
+ [dict setObject:valueString forKey:keyString];
+ }];
+ jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&error];
+ if ([jsonData length] == 0 || error != nil) {
+ return nil;
+ }
+ NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
+ return jsonString;
+}
+
+@end
diff --git a/src/ios/Events.h b/src/ios/Events.h
new file mode 100644
index 0000000..da5ffd9
--- /dev/null
+++ b/src/ios/Events.h
@@ -0,0 +1,22 @@
+//
+// Events.h
+// shuto-cne
+//
+// Created by 范大德 on 2022/3/17.
+//
+
+#ifndef Events_h
+#define Events_h
+
+
+#endif /* Events_h */
+
+#import "Listener.h"
+
+@interface Events
+{}
++ (void)fireEvent: (NSString*)event;
++ (void)fireEvent: (NSString*)event extra:(NSDictionary*)extra;
++ (void)addListener: (NSString*)event listener:(Listener*)listener;
++ (void)removeListener: (NSString*)event listener:(Listener*)listener;
+@end
diff --git a/src/ios/Events.m b/src/ios/Events.m
new file mode 100644
index 0000000..59fb608
--- /dev/null
+++ b/src/ios/Events.m
@@ -0,0 +1,64 @@
+//
+// Events.m
+// 插件中事件流转
+//
+// Created by 范大德 on 2022/3/17.
+//
+
+#import
+#import "Events.h"
+@interface Events()
+{}
+@end
+@implementation Events
+
+static NSString* PREFIX = @"com.tencent.trtc.event";
+static NSMutableDictionary*> *events = nil;
+
++ (void)fireEvent: (NSString*)event{
+ [Events fireEvent: nil];
+}
++ (void)fireEvent: (NSString*)event extra:(NSDictionary*)extra{
+ [Events init];
+ NSLog(@"TRTC - Events::fireEvent --- event:%@,extra:%@",event,extra);
+ NSMutableOrderedSet* listeners = [self getEventListener:event];
+ if(listeners != nil && listeners.count > 0 ){
+ for (Listener* listener in listeners) {
+ NSLog(@"TRTC - Events::fireEvent --- event:%@,listener:%@",event,listener);
+ [listener on:extra];
+ }
+ }
+}
++ (void)addListener: (NSString*)event listener:(Listener*)listener{
+ [Events init];
+ NSLog(@"TRTC - Events::addListener --- event:%@,listener:%@",event,listener);
+ NSMutableOrderedSet* listeners = [self getEventListener:event];
+ if(![listeners containsObject:listener]){
+ [listeners addObject:listener];
+ }
+}
++ (void)removeListener: (NSString*)event listener:(Listener*)listener{
+ [Events init];
+ NSLog(@"TRTC - Events::removeListener --- event:%@,listener:%@",event,listener);
+ NSMutableOrderedSet* listeners = [self getEventListener:event];
+ if([listeners containsObject:listener]){
+ [listeners removeObject:listener];
+ }
+}
+
++ (void)init{
+ if( events == nil){
+ events = [NSMutableDictionary dictionary];
+ }
+}
++ (NSMutableOrderedSet*) getEventListener: (NSString*)event{
+ [Events init];
+ NSString* key = [[NSString alloc] initWithFormat:@"%@%@", PREFIX, event ];
+ NSMutableOrderedSet* listeners =[events valueForKey:key];
+ if(listeners == nil){
+ listeners = [[NSMutableOrderedSet alloc] init];
+ [events setObject:listeners forKey:key];
+ }
+ return [events valueForKey:key];
+}
+@end
diff --git a/src/ios/Listener.h b/src/ios/Listener.h
new file mode 100644
index 0000000..9ce0c35
--- /dev/null
+++ b/src/ios/Listener.h
@@ -0,0 +1,16 @@
+//
+// Listener.h
+// shuto-cne
+//
+// Created by 范大德 on 2022/3/17.
+//
+
+#ifndef Listener_h
+#define Listener_h
+
+#endif /* Listener_h */
+@interface Listener:NSObject
+{}
+- (instancetype)init;
+- (void)on: (NSDictionary*)extra;
+@end
diff --git a/src/ios/Listener.m b/src/ios/Listener.m
new file mode 100644
index 0000000..6264930
--- /dev/null
+++ b/src/ios/Listener.m
@@ -0,0 +1,21 @@
+//
+// Listener.m
+// shuto-cne
+//
+// Created by 范大德 on 2022/3/30.
+//
+
+#import
+#import "Listener.h"
+@interface Listener()
+{}
+- (instancetype)init;
+- (void)on: (NSDictionary*)extra;
+@end
+
+@implementation Listener
+- (instancetype)init{
+ return self;
+}
+- (void)on: (NSDictionary*)extra{}
+@end
diff --git a/src/ios/Trtc/Info.plist b/src/ios/Trtc/Info.plist
deleted file mode 100644
index 49a2d21..0000000
--- a/src/ios/Trtc/Info.plist
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- $(DEVELOPMENT_LANGUAGE)
- CFBundleExecutable
- $(EXECUTABLE_NAME)
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- $(PRODUCT_NAME)
- CFBundlePackageType
- APPL
- CFBundleShortVersionString
- 1.0
- CFBundleURLTypes
-
-
- CFBundleTypeRole
- Editor
- CFBundleURLName
- trtcdayisheng
- CFBundleURLSchemes
-
- trtcdayisheng
-
-
-
- CFBundleVersion
- 1
- LSApplicationCategoryType
-
- LSRequiresIPhoneOS
-
- NSAppTransportSecurity
-
- NSAllowsArbitraryLoads
-
-
- NSCameraUsageDescription
- 请点击“好”以允许访问。
-
- NSMicrophoneUsageDescription
- 请点击“好”以允许访问。
-
- UIBackgroundModes
-
- audio
-
- UIMainStoryboardFile
- Main
- UIRequiredDeviceCapabilities
-
- armv7
-
- UISupportedInterfaceOrientations
-
- UIInterfaceOrientationPortrait
-
- UISupportedInterfaceOrientations~ipad
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
- UIViewControllerBasedStatusBarAppearance
-
-
-
diff --git a/src/ios/Trtc/TCLiveConfigDefine.h b/src/ios/Trtc/TCLiveConfigDefine.h
deleted file mode 100644
index 0b5a783..0000000
--- a/src/ios/Trtc/TCLiveConfigDefine.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// TCLiveConfigDefine.h
-// TRTC
-//
-// Created by xiaowei li on 2018/6/22.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-#ifndef TCLiveConfigDefine_h
-#define TCLiveConfigDefine_h
-
-#define Login_Info_Url @"https://xzb.qcloud.com/webrtc/weapp/webrtc_room/get_login_info" //业务后台登录信息拉取,可替换为自己的业务后台
-#define AuthBuffer_Info_Url @"https://xzb.qcloud.com/webrtc/weapp/webrtc_room/get_privatemapkey"
-#define Default_Role @"ed640" //用户角色配置画面参数,可在控制台进行配置 https://cloud.tencent.com/document/product/647/17308
-#endif /* TCLiveConfigDefine_h */
diff --git a/src/ios/Trtc/TCLiveJoinRoomViewController.h b/src/ios/Trtc/TCLiveJoinRoomViewController.h
deleted file mode 100644
index b5a1a98..0000000
--- a/src/ios/Trtc/TCLiveJoinRoomViewController.h
+++ /dev/null
@@ -1,17 +0,0 @@
-//
-// ViewController.h
-// TRTC
-//
-// Created by Tencent on 2018/5/31.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-#import
-
-@interface TCLiveJoinRoomViewController : UIViewController
-
-@property (nonatomic) NSString *defaultRoomId;
-
-@end
-
-
diff --git a/src/ios/Trtc/TCLiveJoinRoomViewController.m b/src/ios/Trtc/TCLiveJoinRoomViewController.m
deleted file mode 100644
index d5ec8ee..0000000
--- a/src/ios/Trtc/TCLiveJoinRoomViewController.m
+++ /dev/null
@@ -1,112 +0,0 @@
-//
-// ViewController.m
-// TRTC
-//
-// Created by Tencent on 2018/5/31.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-#import "TCLiveJoinRoomViewController.h"
-#import "UIColorEX.h"
-#import "TCLiveRoomViewController.h"
-#import "UIToastView.h"
-#import "TCLiveConfigDefine.h"
-
-@interface TCLiveJoinRoomViewController ()
-@property(nonatomic,strong)UITextField *inputTextField;
-@property(nonatomic,strong)UIButton *joinRoomBtn;
-@property(nonatomic,strong) UIView *botoomLine;
-@property(nonatomic,strong) UIImageView *bgImageView;
-@end
-
-@implementation TCLiveJoinRoomViewController
-
-- (void)viewDidLoad {
- [super viewDidLoad];
- // Do any additional setup after loading the view.
- self.title = @"视频通话";
-
- [self.navigationController.navigationBar setTranslucent:NO];
-
- [self.view addSubview:self.bgImageView];
-
- [self.view addSubview:self.inputTextField];
-
- [self.view addSubview:self.joinRoomBtn];
-
-}
--(void)viewWillAppear:(BOOL)animated{
- if (self.defaultRoomId) {
- self.inputTextField.text = self.defaultRoomId;
- }
- [super viewWillAppear:animated];
- [self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor blackColor]}];
-}
--(UIImageView *)bgImageView{
- if (!_bgImageView) {
- _bgImageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
- [_bgImageView setImage:[UIImage imageNamed:@"bg.png"]];
- _bgImageView.userInteractionEnabled = YES;
- }
- return _bgImageView;
-}
-
-- (UIButton *)joinRoomBtn{
- if (!_joinRoomBtn) {
- _joinRoomBtn = [[UIButton alloc] initWithFrame:CGRectMake(20, _inputTextField.frame.size.height + _inputTextField.frame.origin.y + 50, self.view.frame.size.width - 40, 50)];
- _joinRoomBtn.layer.cornerRadius = 25;
- [_joinRoomBtn setTitle:@"加入房间" forState:UIControlStateNormal];
- _joinRoomBtn.backgroundColor = [UIColor colorWithRGBHex:0x1472fc];
- [_joinRoomBtn addTarget:self action:@selector(joinRoomBtnClick:) forControlEvents:UIControlEventTouchUpInside];
- [_joinRoomBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
- }
- return _joinRoomBtn;
-}
-- (UITextField *)inputTextField{
- if (!_inputTextField) {
- _inputTextField = [[UITextField alloc] initWithFrame:CGRectMake(5, 20 , self.view.frame.size.width-10, 40)];
- _inputTextField.delegate = self;
- _inputTextField.backgroundColor= [UIColor clearColor];
- NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:@"请输入房间号码" attributes:@{NSForegroundColorAttributeName:[UIColor grayColor]}];
- _inputTextField.attributedPlaceholder = str;
- _inputTextField.textColor = [UIColor grayColor];
- _inputTextField.returnKeyType = UIReturnKeyDone;
- _inputTextField.keyboardType = UIKeyboardTypeNumberPad;
-
- _botoomLine = [[UIView alloc] initWithFrame:CGRectMake(0, 40-1, _inputTextField.frame.size.width, 1)];
- _botoomLine.backgroundColor = [UIColor colorWithRGBHex:0x1472fc];
- [_inputTextField addSubview:_botoomLine];
- }
- return _inputTextField;
-}
-
-- (void)joinRoomBtnClick:(UIButton *)sender{
- if (self.inputTextField.text.length > 0) {
- TCLiveRoomViewController *vc = [[TCLiveRoomViewController alloc] initWithRoomID:self.inputTextField.text role:Default_Role];
- [self.navigationController pushViewController:vc animated:YES];
- }
- else{
- [[UIToastView getInstance] showToastWithMessage:@"请输入房间号" toastMode:UIToastShowMode_fail];
- }
-}
-
-// 自动跳转
-//- (void)autoNav:(NSString *)roomId {
-// TCLiveRoomViewController *vc = [[TCLiveRoomViewController alloc] initWithRoomID:roomId role:Default_Role];
-// [self.navigationController pushViewController:vc animated:YES];
-//}
-
-
-#pragma mark - UITextFieldDelegate
-- (BOOL)textFieldShouldReturn:(UITextField *)textField{
- [textField resignFirstResponder];
- return YES;
-}
-
-- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
-{
- NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet];
- NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
- return [string isEqualToString:filtered];
-}
-@end
diff --git a/src/ios/Trtc/TCLiveRequestManager.h b/src/ios/Trtc/TCLiveRequestManager.h
deleted file mode 100644
index 47ebda8..0000000
--- a/src/ios/Trtc/TCLiveRequestManager.h
+++ /dev/null
@@ -1,21 +0,0 @@
-//
-// TCLiveRequestManager.h
-// TRTC
-//
-// Created by Tencent on 2018/5/31.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-#import
-
-typedef void (^LiveLoginInfoBlock)(int code);
-typedef void (^LiveAuthBufferBlock)(NSDictionary *info);
-@interface TCLiveRequestManager : NSObject
-@property(nonatomic,assign)int sdkAppID; //app标识,可在实时音视频控制台(https://console.cloud.tencent.com/rav)创建自己的应用生成
-@property(nonatomic,assign)int accountType; //登录实时音视频应用的帐号类型,在控制台创建应用后分配
-@property(nonatomic,strong)NSString *userID; //用户id标识(可由业务后台自己管理)
-@property(nonatomic,strong)NSString *userSig; //用于用户鉴权,生成方法https://cloud.tencent.com/document/product/647/17275 (可由业务后台自己管理)
-+ (TCLiveRequestManager *)getInstance;
-- (void)requestLoginInfo:(LiveLoginInfoBlock)block;
-- (void)reqGetAuthBufferInfoWithParams:(NSDictionary *)params block:(LiveAuthBufferBlock)block;
-@end
diff --git a/src/ios/Trtc/TCLiveRequestManager.m b/src/ios/Trtc/TCLiveRequestManager.m
deleted file mode 100644
index 51b7489..0000000
--- a/src/ios/Trtc/TCLiveRequestManager.m
+++ /dev/null
@@ -1,98 +0,0 @@
-//
-// TCLiveRequestManager.m
-// TRTC
-//
-// Created by Tencent on 2018/5/31.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-#import "TCLiveRequestManager.h"
-#import "UIToastView.h"
-#import "TCLiveConfigDefine.h"
-@implementation TCLiveRequestManager
-+ (TCLiveRequestManager *)getInstance{
- static TCLiveRequestManager *singleTon = nil;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- singleTon = [TCLiveRequestManager new];
- });
- return singleTon;
-}
-
-- (void)requestLoginInfo:(LiveLoginInfoBlock)block{
- NSString *user = [[NSUserDefaults standardUserDefaults] objectForKey:@"TCLIVE_USER"];
- if (user.length == 0) {
- user = @"";
- }
- NSDictionary *params = @{@"userID":user};
- NSMutableURLRequest *request = [self getSendPostRequest:Login_Info_Url body:params];//加备注
-
- NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
- [sessionConfig setTimeoutIntervalForRequest:30];
-
- __weak TCLiveRequestManager *weakself = self;
- NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig];
- NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
- if (error|| data == nil) {
- block(-1);
- [[UIToastView getInstance] showToastWithMessage:@"登录请求失败" toastMode:UIToastShowMode_fail];
- }
- else{
- //无error data解不出
- NSDictionary *info = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
- if (info) {
- weakself.sdkAppID = [info[@"sdkAppID"] intValue];
- weakself.accountType = [info[@"accountType"]intValue];
- weakself.userID = info[@"userID"];
- weakself.userSig = info[@"userSig"];
- [[NSUserDefaults standardUserDefaults] setObject:info[@"userID"] forKey:@"TCLIVE_USER"];
- block(0);
- }
- else{
- block(-1);
- [[UIToastView getInstance] showToastWithMessage:@"登录信息解包失败" toastMode:UIToastShowMode_fail];
- }
- }
- }];
- [task resume];
-}
-
--(void)reqGetAuthBufferInfoWithParams:(NSDictionary *)params block:(LiveAuthBufferBlock)block{
- NSMutableURLRequest *request = [self getSendPostRequest:AuthBuffer_Info_Url body:params];
-
- NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
- [sessionConfig setTimeoutIntervalForRequest:30];
-
- NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig];
- NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
- if (error|| data == nil) {
- [[UIToastView getInstance] showToastWithMessage:@"获取authBuffer请求失败" toastMode:UIToastShowMode_fail];
- }
- else{
- //无error data解不出
- NSDictionary *info = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
- if (info) {
- block(info);
- }
- else{
- [[UIToastView getInstance] showToastWithMessage:@"获取authBuffer解包失败" toastMode:UIToastShowMode_fail];
- }
- }
- }];
- [task resume];
-}
-
-- (NSMutableURLRequest *)getSendPostRequest:(NSString *)url body:(NSDictionary *)body{
-
- NSData *dataBody = [NSJSONSerialization dataWithJSONObject:body options:NSJSONWritingPrettyPrinted error:nil];
- NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10];
- [request setValue:[NSString stringWithFormat:@"%ld", (long) [dataBody length]] forHTTPHeaderField:@"Content-Length"];
- [request setHTTPMethod:@"POST"];
- [request setValue:@"application/json; charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
- [request setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];
- [request setHTTPBody:dataBody];
-
- return request;
-}
-@end
-
diff --git a/src/ios/Trtc/TCLiveRoomVC/TCLiveChatTableView.h b/src/ios/Trtc/TCLiveRoomVC/TCLiveChatTableView.h
deleted file mode 100644
index 383bdb1..0000000
--- a/src/ios/Trtc/TCLiveRoomVC/TCLiveChatTableView.h
+++ /dev/null
@@ -1,17 +0,0 @@
-//
-// TCLiveChatTableView.h
-// TRTC
-//
-// Created by Tencent on 2018/6/3.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-#import
-#import
-
-@interface TCLiveChatTableView : UITableView
-//添加信息到聊天列表
-- (void)addChatMessage:(NSArray *)msgList withContentColor:(UIColor *)contentColor nickColor:(UIColor *)nickColor;
-//发送信息
-- (void)sendMessage:(NSString *)message;
-@end
diff --git a/src/ios/Trtc/TCLiveRoomVC/TCLiveChatTableView.m b/src/ios/Trtc/TCLiveRoomVC/TCLiveChatTableView.m
deleted file mode 100644
index eb15ce5..0000000
--- a/src/ios/Trtc/TCLiveRoomVC/TCLiveChatTableView.m
+++ /dev/null
@@ -1,177 +0,0 @@
-//
-// TCLiveChatTableView.m
-// TRTC
-//
-// Created by Tencent on 2018/6/3.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-#import
-#import
-#import
-#import "TCLiveChatTableView.h"
-#import "TCLiveChatTableViewCell.h"
-#import "UIColorEX.h"
-#import "UIToastView.h"
-#import "TCLiveRequestManager.h"
-
-@interface TCLiveChatTableView ()
-@property(nonatomic,strong)NSMutableArray *chatMessageList;
-@property(nonatomic,strong)UIColor *contentColor;
-@property(nonatomic,strong)UIColor *nickColor;
-@end
-
-@implementation TCLiveChatTableView
-
-- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style{
- if (self = [super initWithFrame:frame style:style]) {
- _chatMessageList = [[NSMutableArray alloc] initWithCapacity:1];
- self.delegate = self;
- self.dataSource = self;
- self.separatorStyle = UITableViewCellSeparatorStyleNone;
- self.transform = CGAffineTransformMakeScale(1, -1);
- self.layer.cornerRadius = 4;
- self.layer.masksToBounds = YES;
- self.scrollEnabled = NO;
- //设置消息监听
- [[[ILiveSDK getInstance] getTIMManager] setMessageListener:self];
- }
- return self;
-}
-
-//接收消息
--(void)onNewMessage:(NSArray *)msgs{
- [self addChatMessage:msgs withContentColor:nil nickColor:nil];
-}
-//消息处理
-- (void)addChatMessage:(NSArray *)msgList withContentColor:(UIColor *)contentColor nickColor:(UIColor *)nickColor{
- self.contentColor = contentColor;
- self.nickColor = nickColor;
- for (id item in msgList) {
- [self.chatMessageList insertObject:item atIndex:0];
- }
- //过滤非文本消息
- NSMutableArray *tempArr = [NSMutableArray array];
- for (int i = 0; i < msgList.count;i++) {
- TIMMessage *msg = msgList[i];
- if (![self isTextMsg:msg]) {
- [tempArr addObject:msg];
- }
- }
- [self.chatMessageList removeObjectsInArray:tempArr];
-
- dispatch_async(dispatch_get_main_queue(), ^{
- [self reloadData];
- });
-}
-- (BOOL)isTextMsg:(TIMMessage *)msg {
- TIMOfflinePushInfo *info = msg.getOfflinePushInfo;
- if ([info.ext hasPrefix:@"TEXT"]) {
- return YES;
- }
- int count = [msg elemCount];
- for(int i = 0; i < count; i++) {
- TIMElem *elem = [msg getElem:i];
- if ([elem isKindOfClass:[TIMCustomElem class]]){
- if ([((TIMCustomElem*)elem).ext hasPrefix:@"TEXT"]) {
- return YES;
- }
- }
- else if ([elem isKindOfClass:[TIMTextElem class]]){
- return YES;
- }
- }
- return NO;
-}
-//发送消息
-- (void)sendMessage:(NSString *)message{
- //消息组装
- TIMMessage *msge = [[TIMMessage alloc] init];
- TIMCustomElem *textElem = [[TIMCustomElem alloc] init];
- textElem.data = [message dataUsingEncoding:NSUTF8StringEncoding];
- NSDictionary *descDic = @{@"nickName":[TCLiveRequestManager getInstance].userID};
- NSString *desc = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:descDic options:NSJSONReadingAllowFragments error:nil] encoding:NSUTF8StringEncoding];
- textElem.desc = desc;
- textElem.ext = @"TEXT";
- [msge addElem:textElem];
- //调用发送接口
- [[ILiveRoomManager getInstance] sendGroupMessage:msge succ:^{
- NSLog(@"send message succ");
- } failed:^(NSString *module, int errId, NSString *errMsg) {
- NSLog(@"send message fail");
- [[UIToastView getInstance] showToastWithMessage:@"发送消息失败" toastMode:UIToastShowMode_fail];
- }];
- [self addChatMessage:@[msge] withContentColor:nil nickColor:nil];
-}
-#pragma mark - UITableViewDelegate
-
--(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
- TCLiveChatTableViewCell *cell = [self createChatTableViewCell:tableView withIndexPath:indexPath];
- return cell.cellHeight;
-}
-#pragma mark - UITableViewDataSource
-
--(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
- return self.chatMessageList.count;
-}
-
--(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
- TCLiveChatTableViewCell *cell = [self createChatTableViewCell:tableView withIndexPath:indexPath];
- return cell;
-}
-//创建消息cell
-- (TCLiveChatTableViewCell *)createChatTableViewCell:(UITableView *)tableView withIndexPath:(NSIndexPath *)indexPath{
- TCLiveChatTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ChatTableviewCell"];
- if (!cell) {
- cell = [[TCLiveChatTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"ChatTableviewCell"];
- cell.selectionStyle = UITableViewCellSelectionStyleNone;
- cell.backgroundColor = [UIColor clearColor];
- cell.contentView.transform = CGAffineTransformMakeScale (1,-1);
- }
- TIMMessage *msg = self.chatMessageList[indexPath.row];
- int count = [msg elemCount];
- for(int i = 0; i < count; i++) {
- TIMElem *elem = [msg getElem:i];
- //收到消息展示
- NSMutableAttributedString *msgInfo = [[NSMutableAttributedString alloc] initWithString:@""];
- if([elem isKindOfClass:[TIMTextElem class]]){
- msgInfo = [self getContentWithNick:msg.sender andContentTex:((TIMTextElem *)elem).text];
- [cell setModel:msgInfo];
- break;
- }
- else if ([elem isKindOfClass:[TIMCustomElem class]]){
- NSString *nick = msg.sender;
- NSString *dataStr = [[NSString alloc] initWithData:((TIMCustomElem *)elem).data encoding:NSUTF8StringEncoding];
- NSDictionary *descDic = [NSJSONSerialization JSONObjectWithData:[((TIMCustomElem *)elem).desc dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil];
- NSString *nickNmae = descDic[@"nickName"];
- if (nickNmae.length > 0) {
- nick = nickNmae;
- }
- msgInfo = [self getContentWithNick:nick andContentTex:dataStr];
- [cell setModel:msgInfo];
- break;
- }
- }
- return cell;
-}
-- (NSMutableAttributedString *)getContentWithNick:(NSString *)nick andContentTex:(NSString *)contentText{
- NSString *content = [NSString stringWithFormat:@"%@:%@",nick, contentText];
- NSMutableAttributedString *msgInfo = [[NSMutableAttributedString alloc] initWithString:content];
- UIColor *contentColor = [UIColor whiteColor];
- UIColor *nickColor = [UIColor colorWithRGBHex:0xFF4081];
- if (self.contentColor) {
- contentColor = self.contentColor;
- }
- if(self.nickColor){
- nickColor = self.nickColor;
- }
- [msgInfo addAttribute:NSForegroundColorAttributeName value:contentColor range:[content rangeOfString:contentText]];
- [msgInfo addAttribute:NSForegroundColorAttributeName value:nickColor range:[content rangeOfString:nick]];
-
- return msgInfo;
-}
-//点击事件透传
--(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
- return nil;
-}
-@end
diff --git a/src/ios/Trtc/TCLiveRoomVC/TCLiveChatTableViewCell.h b/src/ios/Trtc/TCLiveRoomVC/TCLiveChatTableViewCell.h
deleted file mode 100644
index 8140059..0000000
--- a/src/ios/Trtc/TCLiveRoomVC/TCLiveChatTableViewCell.h
+++ /dev/null
@@ -1,14 +0,0 @@
-//
-// TCLiveChatTableViewCell.h
-// TRTC
-//
-// Created by Tencent on 2018/6/8.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-#import
-
-@interface TCLiveChatTableViewCell : UITableViewCell
-@property(nonatomic,assign)CGFloat cellHeight;
--(void)setModel:(NSMutableAttributedString *)model;
-@end
diff --git a/src/ios/Trtc/TCLiveRoomVC/TCLiveChatTableViewCell.m b/src/ios/Trtc/TCLiveRoomVC/TCLiveChatTableViewCell.m
deleted file mode 100644
index 79bebde..0000000
--- a/src/ios/Trtc/TCLiveRoomVC/TCLiveChatTableViewCell.m
+++ /dev/null
@@ -1,59 +0,0 @@
-//
-// TCLiveChatTableViewCell.m
-// TRTC
-//
-// Created by Tencent on 2018/6/8.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-
-#import "TCLiveChatTableViewCell.h"
-
-@interface TCLiveChatTableViewCell ()
-@property(nonatomic,strong) UILabel *contentLabel;
-@property(nonatomic,strong) UIView *backMaskView;
-@end
-
-@implementation TCLiveChatTableViewCell
-
-- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
- if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
-
- [self.contentView addSubview:self.backMaskView];
- [_backMaskView addSubview:self.contentLabel];
- }
- return self;
-}
-
--(UILabel *)contentLabel{
- if (!_contentLabel) {
- _contentLabel = [[UILabel alloc] initWithFrame:CGRectZero];
- _contentLabel.backgroundColor = [UIColor clearColor];
- _contentLabel.textAlignment = NSTextAlignmentLeft;
- _contentLabel.font = [UIFont systemFontOfSize:13];
- _contentLabel.textColor = [UIColor whiteColor];
- _contentLabel.numberOfLines = 0;
- }
- return _contentLabel;
-}
-
--(UIView *)backMaskView{
- if (!_backMaskView) {
- _backMaskView = [[UIView alloc] initWithFrame:CGRectZero];
- _backMaskView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
- _backMaskView.layer.cornerRadius = 10;
- _backMaskView.layer.masksToBounds = YES;
- }
- return _backMaskView;
-}
-
--(void)setModel:(NSMutableAttributedString *)model{
- _contentLabel.attributedText = model;
- CGSize size = [_contentLabel sizeThatFits:CGSizeMake(230, 10000)];
-
- _contentLabel.frame = CGRectMake(5, 5, size.width, size.height );
- _backMaskView.frame = CGRectMake(5, 5, size.width + 10, size.height + 10);
- self.cellHeight = size.height+20;
-}
-
-@end
diff --git a/src/ios/Trtc/TCLiveRoomVC/TCLiveRoomViewController.h b/src/ios/Trtc/TCLiveRoomVC/TCLiveRoomViewController.h
deleted file mode 100644
index 4e33f53..0000000
--- a/src/ios/Trtc/TCLiveRoomVC/TCLiveRoomViewController.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// TCLiveRoomViewController.h
-// TRTC
-//
-// Created by Tencent on 2018/5/31.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-#import
-#import "TCLiveVideoLayoutView.h"
-
-@interface TCLiveRoomViewController : UIViewController
-//传入roomid(房间号)进入指定房间 设置role配置画面参数
--(instancetype)initWithRoomID:(NSString *)roomid role:(NSString *)role;
-@end
diff --git a/src/ios/Trtc/TCLiveRoomVC/TCLiveRoomViewController.m b/src/ios/Trtc/TCLiveRoomVC/TCLiveRoomViewController.m
deleted file mode 100644
index ccd07de..0000000
--- a/src/ios/Trtc/TCLiveRoomVC/TCLiveRoomViewController.m
+++ /dev/null
@@ -1,275 +0,0 @@
-//
-// TCLiveRoomViewController.m
-// TRTC
-//
-// Created by Tencent on 2018/5/31.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-#import "TCLiveRoomViewController.h"
-#import
-#import
-#import
-#import
-#import
-#import
-#import
-#import "TCLiveRequestManager.h"
-#import "TCLiveVideoControlBar.h"
-#import "TCLiveChatTableView.h"
-#import "UIToastView.h"
-
-#define LIVE_VIEW_HEIGHT 370
-#define LIVE_CONTROL_BAR_HEIGHT 70
-#define LIVE_INPUTTEXTFIELD_HEIGHT 40
-
-@interface TCLiveRoomViewController ()
-@property(nonatomic,strong) TCLiveVideoLayoutView *videoLayoutView;
-@property(nonatomic,strong) TCLiveVideoControlBar *controlBar;
-@property(nonatomic,strong) TCLiveChatTableView *chatTableView;
-@property(nonatomic,strong) UITextField *inputTextField;
-@property(nonatomic,strong) NSString *roomID;
-@property(nonatomic,strong) UIImageView *bgImageView;
-@property(nonatomic,strong) NSTimer *logTimer;
-@property(nonatomic,strong) NSTimer *heartBeatTimer;
-@property(nonatomic,assign) CGRect origInputTextFieldFrame;
-@property(nonatomic,assign) CGRect origChatTableViewFrame;
-@property(nonatomic,strong) NSString *role;
-@end
-
-@implementation TCLiveRoomViewController
-
--(instancetype)initWithRoomID:(NSString *)roomid role:(NSString *)role{
- if (self = [super init]) {
- self.roomID = roomid;
- self.role = role;
- }
- return self;
-}
-
-- (void)viewDidLoad {
- [super viewDidLoad];
- // Do any additional setup after loading the view.
- self.title = self.roomID;
- [self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}];
-
- [self enterRoom];
-
- [self customLeftButton];
-
- [self.view addSubview:self.bgImageView];
-
- [_bgImageView addSubview:self.videoLayoutView];
-
- [_bgImageView addSubview:self.chatTableView];
-
- [_bgImageView addSubview:self.controlBar];
-
- [_bgImageView addSubview:self.inputTextField];
-
- //监听键盘变化
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
-}
--(void)viewWillAppear:(BOOL)animated{
- [super viewWillAppear:animated];
- //导航栏透明化
- [self setNavigationBarTransparent];
- [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
-}
-
-- (void)viewWillDisappear:(BOOL)animated{
- [super viewWillDisappear:animated];
- [self.navigationController.navigationBar setTranslucent:NO];
- [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;
-}
-- (void)setNavigationBarTransparent{
- [self.navigationController.navigationBar setTranslucent:YES];
- [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc]init] forBarMetrics:UIBarMetricsDefault];
- [self.navigationController.navigationBar setShadowImage:[[UIImage alloc]init]];
- [self.navigationController.navigationBar setBackgroundColor:[UIColor clearColor]];
-}
-
-- (void)enterRoom{
- [[TCLiveRequestManager getInstance] reqGetAuthBufferInfoWithParams:@{@"roomID":self.roomID,@"userID":[TCLiveRequestManager getInstance].userID} block:^(NSDictionary *info) {
- ILiveRoomOption *option = [ILiveRoomOption defaultHostLiveOption];
- option.imOption.imSupport = YES;
- option.memberStatusListener = self.videoLayoutView;
- option.roomDisconnectListener = self;
- option.controlRole = self.role;
- option.avOption.privateMapKey = [info[@"privateMapKey"] dataUsingEncoding:NSUTF8StringEncoding];
-
- [[ILiveRoomManager getInstance] createRoom:[self.roomID intValue] option:option succ:^{
- NSLog(@"-----> create room succ");
- [[UIToastView getInstance] showToastWithMessage:@"创建房间成功" toastMode:UIToastShowMode_Succ];
- [self.controlBar enableBeauty:YES];//进入房间默认开启美颜
- } failed:^(NSString *module, int errId, NSString *errMsg) {
- if(errId == 10021){
- //表示房间已存在直接加入房间
- [[ILiveRoomManager getInstance] joinRoom:[self.roomID intValue] option:option succ:^{
- NSLog(@"-----> join room succ");
- [[UIToastView getInstance] showToastWithMessage:@"加入房间成功" toastMode:UIToastShowMode_Succ];
- [self.controlBar enableBeauty:YES];//进入房间默认开启美颜
- } failed:^(NSString *module, int errId, NSString *errMsg) {
- NSLog(@"-----> join room fail,%@ %d %@",module, errId, errMsg);
- [[UIToastView getInstance] showToastWithMessage:errMsg toastMode:UIToastShowMode_fail];
- }];
- }
- else{
- NSLog(@"-----> create room fail,%@ %d %@",module, errId, errMsg);
- [[UIToastView getInstance] showToastWithMessage:errMsg toastMode:UIToastShowMode_fail];
- }
- }];
- }];
-
-}
-
-- (void)customLeftButton{
- UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
- backBtn.frame = CGRectMake(0, 0, 44, 44);
- [backBtn setImage:[UIImage imageNamed:@"ui_title_arrow_left.png"] forState:UIControlStateNormal];
- [backBtn addTarget:self action:@selector(backBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
- backBtn.frame = CGRectMake(0, 0, 44, 44);
- [backBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
- backBtn.imageEdgeInsets = UIEdgeInsetsMake(10, 0, 10, 20);
- UIBarButtonItem *item = [[UIBarButtonItem alloc]initWithCustomView:backBtn];
- self.navigationItem.leftBarButtonItem = item;
-}
-
-- (UIImageView *)bgImageView{
- if (!_bgImageView) {
- _bgImageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
- [_bgImageView setImage:[UIImage imageNamed:@"bg.png"]];
- _bgImageView.userInteractionEnabled = YES;
- }
- return _bgImageView;
-}
-
-//视频区域
--(TCLiveVideoLayoutView *)videoLayoutView{
- if (!_videoLayoutView) {
- _videoLayoutView = [[TCLiveVideoLayoutView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
- }
- return _videoLayoutView;
-}
-//控制bar
-- (TCLiveVideoControlBar *)controlBar{
- if (!_controlBar) {
- _controlBar = [[TCLiveVideoControlBar alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height - LIVE_CONTROL_BAR_HEIGHT, self.view.frame.size.width, LIVE_CONTROL_BAR_HEIGHT)];
- _controlBar.delegate = self;
- }
- return _controlBar;
-}
-//消息列表
-- (UITableView *)chatTableView{
- if (!_chatTableView) {
- _chatTableView = [[TCLiveChatTableView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height - LIVE_CONTROL_BAR_HEIGHT - 400, 250, 400) style:UITableViewStylePlain];
- _chatTableView.backgroundColor = [UIColor clearColor];
- self.origChatTableViewFrame = self.chatTableView.frame;
- }
- return _chatTableView;
-}
-//输入框
-- (UITextField *)inputTextField{
- if (!_inputTextField) {
- _inputTextField = [[UITextField alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height , self.view.frame.size.width, LIVE_INPUTTEXTFIELD_HEIGHT)];
- _inputTextField.delegate = self;
- _inputTextField.backgroundColor= [[UIColor whiteColor] colorWithAlphaComponent:0.9];
- _inputTextField.placeholder = @"请输入内容";
- _inputTextField.returnKeyType = UIReturnKeySend;
- self.origInputTextFieldFrame = self.inputTextField.frame;
- }
- return _inputTextField;
-}
-//关闭界面退出房间
-- (void)backBtnClicked:(UIButton *)sender{
- [self.navigationController popViewControllerAnimated:YES];
- [[ILiveRoomManager getInstance] quitRoom:^{
- NSLog(@"-----> quit room succ");
- [[UIToastView getInstance] showToastWithMessage:@"退出房间成功" toastMode:UIToastShowMode_Succ];
- } failed:^(NSString *module, int errId, NSString *errMsg) {
- NSLog(@"-----> quit room fail,%@ %d %@",module, errId, errMsg);
- [[UIToastView getInstance] showToastWithMessage:@"退出房间失败" toastMode:UIToastShowMode_fail];
- }];
- [_logTimer invalidate];
- _logTimer = nil;
-
-}
-#pragma mark - ILiveRoomDisconnectListener
-- (BOOL)onRoomDisconnect:(int)reason;{
- [self backBtnClicked:nil];
- return YES;
-}
-#pragma mark - UITextFieldDelegate
-
-- (BOOL)textFieldShouldReturn:(UITextField *)textField;{
- [textField resignFirstResponder];
- NSString *text = textField.text;
- if (text.length > 0) {
- [self.chatTableView sendMessage:text];
- textField.text = nil;
- }
- else{
- return NO;
- }
- return YES;
-}
-#pragma mark - TCLiveVideoControlBarDelegate
--(void)logBtnClick:(UIButton *)sender{
- if (sender.selected) {
- if (!_logTimer) {
- [self logUpdate];
- _logTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(logUpdate) userInfo:nil repeats:YES];
- }
- }
- else{
- [_logTimer invalidate];
- _logTimer = nil;
- [_videoLayoutView closeLogView];
- }
-}
-- (void)chatBtnClick:(UIButton *)sender{
- [self.inputTextField becomeFirstResponder];
-}
-- (void)logUpdate{
- QAVContext *avContext = [[ILiveSDK getInstance] getAVContext];
- NSString *qualityStr = [avContext.room getQualityTips];
- [_videoLayoutView showLogView:qualityStr];
-}
-
-- (void)beautyBtnClick:(UIButton *)sender{
- if (sender.selected) {
- [self.videoLayoutView setBeautyLevel:9];
- }
- else{
- [self.videoLayoutView setBeautyLevel:0];
- }
-}
-#pragma mark - 键盘事件
-- (void)keybaordAnimationWithDuration:(CGFloat)duration keyboardOriginY:(CGFloat)keyboardOriginY{
-
- __block TCLiveRoomViewController *blockSelf = self;
- //作为视图的键盘,弹出动画也是UIViewAnimationOptionCurveEaseIn的方式
- [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
- //text field
- if(keyboardOriginY == blockSelf.view.frame.size.height){
- blockSelf.inputTextField.frame = blockSelf.origInputTextFieldFrame;
- blockSelf.chatTableView.frame = blockSelf.origChatTableViewFrame;
- }
- else{
- blockSelf.inputTextField.frame = CGRectMake(blockSelf.inputTextField.frame.origin.x,keyboardOriginY - blockSelf.inputTextField.frame.size.height, blockSelf.inputTextField.frame.size.width, blockSelf.inputTextField.frame.size.height);
- blockSelf.chatTableView.frame = CGRectMake(blockSelf.chatTableView.frame.origin.x,keyboardOriginY - blockSelf.chatTableView.frame.size.height - LIVE_INPUTTEXTFIELD_HEIGHT, blockSelf.chatTableView.frame.size.width, blockSelf.chatTableView.frame.size.height);
- }
-
- } completion:nil];
-}
-- (void)keyboardWillChangeFrame:(NSNotification *)notify{
- NSDictionary * info = notify.userInfo;
- //动画时间
- CGFloat animationDuration = [info[UIKeyboardAnimationDurationUserInfoKey] floatValue];
- //键盘目标位置
- CGRect keyboardAimFrame = [info[UIKeyboardFrameEndUserInfoKey] CGRectValue];
- if ([self.inputTextField isFirstResponder]) {
- [self keybaordAnimationWithDuration:animationDuration keyboardOriginY:keyboardAimFrame.origin.y];
- }
-}
-@end
diff --git a/src/ios/Trtc/TCLiveRoomVC/TCLiveUITools/UIColorEX.h b/src/ios/Trtc/TCLiveRoomVC/TCLiveUITools/UIColorEX.h
deleted file mode 100644
index b3a8650..0000000
--- a/src/ios/Trtc/TCLiveRoomVC/TCLiveUITools/UIColorEX.h
+++ /dev/null
@@ -1,13 +0,0 @@
-//
-// UIColorEX.h
-// TRTC
-//
-// Created by Tencent on 2018/6/5.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-#import
-
-@interface UIColor (EX)
-+ (UIColor *)colorWithRGBHex: (unsigned int)hex;
-@end
diff --git a/src/ios/Trtc/TCLiveRoomVC/TCLiveUITools/UIColorEX.m b/src/ios/Trtc/TCLiveRoomVC/TCLiveUITools/UIColorEX.m
deleted file mode 100644
index 458f5fc..0000000
--- a/src/ios/Trtc/TCLiveRoomVC/TCLiveUITools/UIColorEX.m
+++ /dev/null
@@ -1,25 +0,0 @@
-//
-// UIColorEX.m
-// TRTC
-//
-// Created by Tencent on 2018/6/5.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-#import "UIColorEX.h"
-
-@implementation UIColor (EX)
-
-+ (UIColor *)colorWithRGBHex: (unsigned int)hex
-{
- int r = (hex >> 16) & 0xFF;
- int g = (hex >> 8) & 0xFF;
- int b = (hex) & 0xFF;
-
- return [UIColor colorWithRed:r / 255.0f
- green:g / 255.0f
- blue:b / 255.0f
- alpha:1.0f];
-}
-
-@end
diff --git a/src/ios/Trtc/TCLiveRoomVC/TCLiveUITools/UIToastView.h b/src/ios/Trtc/TCLiveRoomVC/TCLiveUITools/UIToastView.h
deleted file mode 100644
index 4103160..0000000
--- a/src/ios/Trtc/TCLiveRoomVC/TCLiveUITools/UIToastView.h
+++ /dev/null
@@ -1,20 +0,0 @@
-//
-// UIToastView.h
-// TRTC
-//
-// Created by Tencent on 2018/6/9.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-#import
-
-typedef enum {
- UIToastShowMode_Default = 1,
- UIToastShowMode_Succ,
- UIToastShowMode_fail,
-}UIToastShowMode;
-
-@interface UIToastView : UIView
-+ (UIToastView *)getInstance;
-- (void)showToastWithMessage:(NSString *)text toastMode:(UIToastShowMode )mode;
-@end
diff --git a/src/ios/Trtc/TCLiveRoomVC/TCLiveUITools/UIToastView.m b/src/ios/Trtc/TCLiveRoomVC/TCLiveUITools/UIToastView.m
deleted file mode 100644
index e5d631b..0000000
--- a/src/ios/Trtc/TCLiveRoomVC/TCLiveUITools/UIToastView.m
+++ /dev/null
@@ -1,96 +0,0 @@
-//
-// UIToastView.m
-// TRTC
-//
-// Created by Tencent on 2018/6/9.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-#import "UIToastView.h"
-
-#define UITOAST_HEIGHT 30
-#define UITOAST_IMAGE_HEIGHT 15
-@interface UIToastView ()
-@property(nonatomic,strong)UILabel *toastLabel;
-@property(nonatomic,strong)UIImageView *toastImageView;
-@end
-
-@implementation UIToastView
-
-+ (UIToastView *)getInstance{
- static UIToastView *singleTon = nil;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- singleTon = [UIToastView new];
- });
- return singleTon;
-}
-
--(instancetype)initWithFrame:(CGRect)frame{
- if (self = [super initWithFrame:frame]) {
- self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
- self.layer.cornerRadius = 4;
- self.layer.masksToBounds = YES;
-
- [self addSubview:self.toastImageView];
- [self addSubview:self.toastLabel];
- }
- return self;
-}
-- (UILabel *)toastLabel{
- if (!_toastLabel) {
- _toastLabel = [[UILabel alloc] initWithFrame:CGRectZero];
- _toastLabel.numberOfLines = 1;
- _toastLabel.textAlignment = NSTextAlignmentCenter;
- _toastLabel.textColor = [UIColor whiteColor];
- _toastLabel.font = [UIFont systemFontOfSize:16];
- }
- return _toastLabel;
-}
-
--(UIImageView *)toastImageView{
- if (!_toastImageView) {
- _toastImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
-
- }
- return _toastImageView;
-}
-
-- (void)showToastWithMessage:(NSString *)text toastMode:(UIToastShowMode )mode{
- dispatch_async(dispatch_get_main_queue(), ^{
- UIToastView *view = [UIToastView new];
- CGRect rect = [text boundingRectWithSize:CGSizeMake([UIScreen mainScreen].bounds.size.width - 80, 20) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16]} context:nil];
- view.frame = CGRectMake(0, 0, rect.size.width + 10 + 20, UITOAST_HEIGHT);
- view.toastImageView.frame = CGRectMake(5, 0, UITOAST_IMAGE_HEIGHT, UITOAST_IMAGE_HEIGHT);
- view.toastImageView.center = CGPointMake(view.toastImageView.center.x, view.frame.size.height/2);
- view.toastLabel.frame = CGRectMake(25, 0, rect.size.width, UITOAST_HEIGHT);
- view.toastLabel.text = text;
- if (UIToastShowMode_Succ == mode){
- view.toastImageView.image = [UIImage imageNamed:@"ic_toast_success@2x"];
- }
- else if(UIToastShowMode_fail == mode){
- view.toastImageView.image = [UIImage imageNamed:@"icon_sign@2x"];
- }
- else{
- view.toastImageView.frame = CGRectZero;
- view.frame = CGRectMake(0, 0, rect.size.width + 10 , UITOAST_HEIGHT);
- view.toastLabel.frame = CGRectMake(5, 0, rect.size.width, UITOAST_HEIGHT);
- }
- view.center = [[UIApplication sharedApplication] keyWindow].center;
- [[[UIApplication sharedApplication] keyWindow] addSubview:view];
- [UIView animateWithDuration:0.5 animations:^{
- view.alpha = 1;
- } completion:^(BOOL finished) {
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- [UIView animateWithDuration:0.5 animations:^{
- view.alpha = 0;
- } completion:^(BOOL finished) {
- [view removeFromSuperview];
- }];
- });
- }];
- });
-
-}
-
-@end
diff --git a/src/ios/Trtc/TCLiveRoomVC/TCLiveVideoControlBar.h b/src/ios/Trtc/TCLiveRoomVC/TCLiveVideoControlBar.h
deleted file mode 100644
index 93f1a42..0000000
--- a/src/ios/Trtc/TCLiveRoomVC/TCLiveVideoControlBar.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//
-// TCLiveVideoControlBar.h
-// TRTC
-//
-// Created by Tencent on 2018/6/3.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-#import
-
-@protocol TCLiveVideoControlBarDelegate
-@optional
-//切换摄像头
-- (void)switchCameraBtnClick:(UIButton *)sender;
-//开关美颜
-- (void)beautyBtnClick:(UIButton *)sender;
-//开关麦克风
-- (void)voiceBtnClick:(UIButton *)sender;
-//展示日志
-- (void)logBtnClick:(UIButton *)sender;
-//反馈
-- (void)feedBackBtnClick:(UIButton *)sender;
-//切换配置
-- (void)changeRoleBtnClick:(UIButton *)sender;
-//聊天
-- (void)chatBtnClick:(UIButton *)sender;
-@end
-
-@interface TCLiveVideoControlBar : UIView
-@property(nonatomic,weak)id delegate;
-@property(nonatomic,strong) UIButton *logBtn;
-- (void)enableLog:(BOOL)endable;
-- (void)enableBeauty:(BOOL)enable;
-@end
diff --git a/src/ios/Trtc/TCLiveRoomVC/TCLiveVideoControlBar.m b/src/ios/Trtc/TCLiveRoomVC/TCLiveVideoControlBar.m
deleted file mode 100644
index 0eb7c7d..0000000
--- a/src/ios/Trtc/TCLiveRoomVC/TCLiveVideoControlBar.m
+++ /dev/null
@@ -1,298 +0,0 @@
-//
-// TCLiveVideoControlBar.m
-// TRTC
-//
-// Created by Tencent on 2018/6/3.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-
-
-#import "TCLiveVideoControlBar.h"
-#import
-#import
-#import
-#import "TCLiveRequestManager.h"
-#import "UIToastView.h"
-#import "TCLiveRoomViewController.h"
-
-#define CONTROLBAR_BUTTON_WIDTH 50
-
-@interface TCLiveVideoControlBar ()
-@property(nonatomic,strong) UIButton *chatBtn;
-@property(nonatomic,strong) UIButton *switchCamera;
-@property(nonatomic,strong) UIButton *beautyBtn;
-@property(nonatomic,strong) UIButton *voiceBtn;
-@property(nonatomic,strong) UIButton *changeRoleBtn;
-@property(nonatomic,strong) UIButton *feedBackBtn;
-@end
-
-@implementation TCLiveVideoControlBar
-
--(instancetype)initWithFrame:(CGRect)frame
-{
- if (self = [super initWithFrame:frame]) {
-// [self addSubview:self.chatBtn];
-// [self addSubview:self.beautyBtn];
- [self addSubview:self.voiceBtn];
-// [self addSubview:self.logBtn];
- [self addSubview:self.switchCamera];
-// [self addSubview:self.feedBackBtn];
-// [self addSubview:self.changeRoleBtn];
- self.backgroundColor = [UIColor clearColor];
- }
- return self;
-}
-
--(UIButton *)chatBtn{
- if(!_chatBtn){
- _chatBtn = [self createCustomControlBtn:@"聊天" withImage:[UIImage imageNamed:@"chat.png"] selectedImage:nil];
- [_chatBtn addTarget:self action:@selector(chatBtnClick:) forControlEvents:UIControlEventTouchUpInside];
- }
- _chatBtn.frame = CGRectMake(self.frame.size.width / 2 - CONTROLBAR_BUTTON_WIDTH * 3.5, 0, CONTROLBAR_BUTTON_WIDTH, self.frame.size.height);
- return _chatBtn;
-}
--(UIButton *)switchCamera{
- if (!_switchCamera) {
- _switchCamera = [self createCustomControlBtn:@"翻转" withImage:[UIImage imageNamed:@"camera.png"] selectedImage:[UIImage imageNamed:@"camera-gray.png"]];
- [_switchCamera addTarget:self action:@selector(switchCameraClick:) forControlEvents:UIControlEventTouchUpInside];
- }
-// _switchCamera.frame = CGRectMake(self.frame.size.width/2 - CONTROLBAR_BUTTON_WIDTH * 2.5,0,CONTROLBAR_BUTTON_WIDTH,self.frame.size.height);
- _switchCamera.frame = CGRectMake(self.frame.size.width/2 - CONTROLBAR_BUTTON_WIDTH * 1.5,0,CONTROLBAR_BUTTON_WIDTH,self.frame.size.height);
- return _switchCamera;
-}
-
-- (UIButton *)beautyBtn{
- if (!_beautyBtn) {
- _beautyBtn = [self createCustomControlBtn:@"美颜" withImage:[UIImage imageNamed:@"beauty.png"] selectedImage:[UIImage imageNamed:@"beauty-dis.png"]];
- [_beautyBtn addTarget:self action:@selector(beautyBtnClick:) forControlEvents:UIControlEventTouchUpInside];
- }
- _beautyBtn.frame = CGRectMake(self.frame.size.width/2 - CONTROLBAR_BUTTON_WIDTH *1.5, 0, CONTROLBAR_BUTTON_WIDTH, self.frame.size.height);
- return _beautyBtn;
-}
-
-- (UIButton *)voiceBtn{
- if (!_voiceBtn) {
- _voiceBtn = [self createCustomControlBtn:@"声音" withImage:[UIImage imageNamed:@"mic-dis.png"] selectedImage:[UIImage imageNamed:@"mic.png"]];
- [_voiceBtn addTarget:self action:@selector(voiceBtnClick:) forControlEvents:UIControlEventTouchUpInside];
- }
-// _voiceBtn.frame = CGRectMake(self.frame.size.width/2 - CONTROLBAR_BUTTON_WIDTH * 0.5, 0, CONTROLBAR_BUTTON_WIDTH, self.frame.size.height);
- _voiceBtn.frame = CGRectMake(self.frame.size.width/2 + CONTROLBAR_BUTTON_WIDTH * 0.5, 0, CONTROLBAR_BUTTON_WIDTH, self.frame.size.height);
- return _voiceBtn;
-}
-
--(UIButton *)changeRoleBtn{
- if (!_changeRoleBtn) {
- _changeRoleBtn = [self createCustomControlBtn:@"配置" withImage:[UIImage imageNamed:@"role.png"] selectedImage:[UIImage imageNamed:@"role.png"]];
- [_changeRoleBtn addTarget:self action:@selector(changeRoleBtnClick:) forControlEvents:UIControlEventTouchUpInside];
- }
- _changeRoleBtn.frame = CGRectMake(self.frame.size.width/2 + CONTROLBAR_BUTTON_WIDTH * 0.5, 0, CONTROLBAR_BUTTON_WIDTH, self.frame.size.height);
- return _changeRoleBtn;
-}
-
-- (UIButton *)feedBackBtn{
- if (!_feedBackBtn) {
- _feedBackBtn = [self createCustomControlBtn:@"反馈" withImage:[UIImage imageNamed:@"feedback.png"] selectedImage:[UIImage imageNamed:@"feedback.png"]];
- [_feedBackBtn addTarget:self action:@selector(feedBackBtnClick:) forControlEvents:UIControlEventTouchUpInside];
- }
- _feedBackBtn.frame = CGRectMake(self.frame.size.width/2 + CONTROLBAR_BUTTON_WIDTH * 1.5, 0, CONTROLBAR_BUTTON_WIDTH, self.frame.size.height);
- return _feedBackBtn;
-}
-
-- (UIButton *)logBtn{
- if (!_logBtn) {
- _logBtn = [self createCustomControlBtn:@"信息" withImage:[UIImage imageNamed:@"log.png"] selectedImage:[UIImage imageNamed:@"log2.png"]];
- [_logBtn addTarget:self action:@selector(logBtnClick:) forControlEvents:UIControlEventTouchUpInside];
- }
- _logBtn.frame = CGRectMake(self.frame.size.width/2 + CONTROLBAR_BUTTON_WIDTH * 2.5, 0, CONTROLBAR_BUTTON_WIDTH, self.frame.size.height);
- return _logBtn;
-}
-
-- (UIButton *)createCustomControlBtn:(NSString *)wording withImage:(UIImage *)image selectedImage:(UIImage *)highlightImage{
- UIButton *customButton = [[UIButton alloc] initWithFrame:CGRectZero];
- [customButton setTitle:wording forState:UIControlStateNormal];
- customButton.titleLabel.font = [UIFont systemFontOfSize:11];
- [customButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
- [customButton setImage:image forState:UIControlStateNormal];
- [customButton setImage:highlightImage forState:UIControlStateSelected];
- CGFloat imageHeight = image.size.height;
- CGFloat imageWidth = image.size.width;
- [customButton setTitleEdgeInsets:UIEdgeInsetsMake(15, -60, -15, 0)];
- [customButton setImageEdgeInsets:UIEdgeInsetsMake(10, 10, self.frame.size.height - (CONTROLBAR_BUTTON_WIDTH - 20)/imageWidth *imageHeight -10, 10)];
- return customButton;
-}
-#pragma mark - Handle Event
-//聊天按钮
-- (void)chatBtnClick:(UIButton *)sender{
- if (!sender.selected) {
- sender.selected = YES;
- }
- else{
- sender.selected = NO;
- }
- if ([_delegate respondsToSelector:@selector(chatBtnClick:)]) {
- [_delegate chatBtnClick:sender];
- }
-}
-//切换摄像头
-- (void)switchCameraClick:(UIButton *)sender{
- ILiveFrameDispatcher *frameDispatcher = [[ILiveRoomManager getInstance] getFrameDispatcher];
- ILiveRenderView *renderView = [frameDispatcher getRenderView:[TCLiveRequestManager getInstance].userID srcType:QAVVIDEO_SRC_TYPE_CAMERA];
- if (!sender.selected) {
- sender.selected = YES;
- renderView.isMirror = NO;
- }
- else{
- sender.selected = NO;
- renderView.isMirror = YES;
- }
- [[ILiveRoomManager getInstance] switchCamera:^{
- NSLog(@"switch camera succ");
- } failed:^(NSString *module, int errId, NSString *errMsg) {
- NSLog(@"switch camera fail");
- [[UIToastView getInstance] showToastWithMessage:@"切换摄像头失败" toastMode:UIToastShowMode_fail];
- }];
- if ([_delegate respondsToSelector:@selector(switchCameraClick:)]) {
- [_delegate switchCameraBtnClick:sender];
- }
-}
-//美颜
-- (void)beautyBtnClick:(UIButton *)sender{
- if (!sender.selected) {
- sender.selected = YES;
- }
- else{
- sender.selected = NO;
- }
- if ([_delegate respondsToSelector:@selector(beautyBtnClick:)]) {
- [_delegate beautyBtnClick:sender];
- }
-}
-- (void)enableBeauty:(BOOL)enable{
- if (enable) {
- _beautyBtn.selected = YES;
- }
- else{
- _beautyBtn.selected = NO;
- }
- if ([_delegate respondsToSelector:@selector(beautyBtnClick:)]) {
- [_delegate beautyBtnClick:_beautyBtn];
- }
-}
-//语音开关
-- (void)voiceBtnClick:(UIButton *)sender{
- if (!sender.selected) {
- sender.selected = YES;
- }
- else{
- sender.selected = NO;
- }
- [[ILiveRoomManager getInstance] enableMic:!sender.selected succ:^{
- NSLog(@"enable mic succ");
- } failed:^(NSString *module, int errId, NSString *errMsg) {
- NSLog(@"enable mic fail");
- [[UIToastView getInstance] showToastWithMessage:@"关麦失败" toastMode:UIToastShowMode_fail];
- }];
- if ([_delegate respondsToSelector:@selector(voiceBtnClick:)]) {
- [_delegate voiceBtnClick:sender];
- }
-
-}
-//配置角色
-- (void)changeRoleBtnClick:(UIButton *)sender{
- if (!sender.selected) {
- sender.selected = YES;
- }
- else{
- sender.selected = NO;
- }
- if ([_delegate respondsToSelector:@selector(changeRoleBtnClick:)]) {
- [_delegate changeRoleBtnClick:sender];
- }
- if ([_delegate isKindOfClass:[UIViewController class]]) {
- [self showChangeRoleMenuOnVC:(UIViewController *)_delegate];
- }
-}
-//日志
-- (void)logBtnClick:(UIButton *)sender{
- if (!sender.selected) {
- sender.selected = YES;
- }
- else{
- sender.selected = NO;
- }
- if ([_delegate respondsToSelector:@selector(logBtnClick:)]) {
- [_delegate logBtnClick:sender];
- }
-}
-//问题反馈
-- (void)feedBackBtnClick:(UIButton *)sender{
- if (!sender.selected) {
- sender.selected = YES;
- }
- else{
- sender.selected = NO;
- }
- if ([_delegate respondsToSelector:@selector(feedBackBtnClick:)]) {
- [_delegate feedBackBtnClick:sender];
- }
- if ([_delegate isKindOfClass:[UIViewController class]]) {
- UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"若您在接入过程中有疑问可直接反馈给我们" message:@"邮箱联系地址:trtcfb@qq.com" preferredStyle:UIAlertControllerStyleAlert];
- [alert addAction:[UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:nil]];
- [((UIViewController *)self.delegate) presentViewController:alert animated:YES completion:nil];
- }
-}
-//log展示开关
-- (void)enableLog:(BOOL)endable{
- self.logBtn.selected = endable;
- if ([_delegate respondsToSelector:@selector(logBtnClick:)]) {
- [_delegate logBtnClick:self.logBtn];
- }
-}
-//弹出配置菜单
--(void)showChangeRoleMenuOnVC:(UIViewController *)vc{
- UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"请选择配置分辨率" message:nil preferredStyle:UIAlertControllerStyleAlert];
- [alertController addAction:[UIAlertAction actionWithTitle:@"1280x720 1000-1800kbps 20fps" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
- [[ILiveRoomManager getInstance] changeRole:@"ed1280" succ:^{
- NSLog(@"更换ed1280 succ");
- [self enableLog:YES];
- } failed:^(NSString *module, int errId, NSString *errMsg) {
- NSLog(@"更换ed1280 fail");
- }];
- }]];
- [alertController addAction:[UIAlertAction actionWithTitle:@"960x540 500-800kbps 15fps" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
- [[ILiveRoomManager getInstance] changeRole:@"ed960" succ:^{
- NSLog(@"更换ed960 succ");
- [self enableLog:YES];
- } failed:^(NSString *module, int errId, NSString *errMsg) {
- NSLog(@"更换ed960 fail");
- }];
- }]];
- [alertController addAction:[UIAlertAction actionWithTitle:@"640x480 400-800kbps 15fps" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
- [[ILiveRoomManager getInstance] changeRole:@"ed640" succ:^{
- NSLog(@"更换ed640 succ");
- [self enableLog:YES];
- } failed:^(NSString *module, int errId, NSString *errMsg) {
- NSLog(@"更换ed640 fail");
- }];
- }]];
- [alertController addAction:[UIAlertAction actionWithTitle:@"480x360 300-600kbps 15fps" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
- [[ILiveRoomManager getInstance] changeRole:@"ed480" succ:^{
- NSLog(@"更换ed480 succ");
- [self enableLog:YES];
- } failed:^(NSString *module, int errId, NSString *errMsg) {
- NSLog(@"更换ed480 fail");
- }];
- }]];
- [alertController addAction:[UIAlertAction actionWithTitle:@"320x240 200-400kbps 15fps" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
- [[ILiveRoomManager getInstance] changeRole:@"ed320" succ:^{
- NSLog(@"更换ed320 succ");
- [self enableLog:YES];
- } failed:^(NSString *module, int errId, NSString *errMsg) {
- NSLog(@"更换ed320 fail");
- }];
- }]];
- [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]];
- [vc presentViewController:alertController animated:YES completion:nil];
-}
-@end
diff --git a/src/ios/Trtc/TCLiveRoomVC/TCLiveVideoLayoutView.h b/src/ios/Trtc/TCLiveRoomVC/TCLiveVideoLayoutView.h
deleted file mode 100644
index 1898d10..0000000
--- a/src/ios/Trtc/TCLiveRoomVC/TCLiveVideoLayoutView.h
+++ /dev/null
@@ -1,42 +0,0 @@
-//
-// TCLiveVideoLayoutView.h
-// TRTC
-//
-// Created by Tencent on 2018/6/3.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-#import
-#import
-
-@class TCLiveVideoElementView;
-
-typedef enum {
- TCLiveRoomVideoLayoutStyle_1v3,
- TCLiveRoomVideoLayoutStyle_4_geizi,
-}TCLiveRoomVideoLayoutStyle;
-
-@protocol TCLiveVideoElementViewDelegate
-- (void)tapHandle:(TCLiveVideoElementView *)view;
-@end
-
-@interface TCLiveVideoLayoutView : UIView
-//画面布局样式
-@property(nonatomic,assign) TCLiveRoomVideoLayoutStyle layoutStyle;
-//显示日志信息
-- (void)showLogView:(NSString *)qualityParams;
-//关闭日志信息
-- (void)closeLogView;
-//设置美颜
-- (void)setBeautyLevel:(NSInteger)level;
-@end
-
-@interface TCLiveVideoElementView: UIView
-//展示userID
-@property(nonatomic,strong)UILabel *userIdLabel;
-//展示视频分辨率、帧率等信息
-@property(nonatomic,strong)UILabel *videoInfoLable;
-@property(nonatomic,weak)TCLiveVideoLayoutView *delegate;
-//可拖动开关
-- (void)ennableDraggable:(BOOL)draggable;
-@end
diff --git a/src/ios/Trtc/TCLiveRoomVC/TCLiveVideoLayoutView.m b/src/ios/Trtc/TCLiveRoomVC/TCLiveVideoLayoutView.m
deleted file mode 100644
index b13299e..0000000
--- a/src/ios/Trtc/TCLiveRoomVC/TCLiveVideoLayoutView.m
+++ /dev/null
@@ -1,403 +0,0 @@
-//
-// TCLiveVideoLayoutView.m
-// TRTC
-//
-// Created by Tencent on 2018/6/3.
-// Copyright © 2018年 Tencent. All rights reserved.
-//
-
-#import "TCLiveVideoLayoutView.h"
-#import
-#import
-#import
-#import "TCLiveRequestManager.h"
-#import "UIColorEX.h"
-#import "TXCVideoPreprocessor.h"
-#define LIVE_VIDEO_NUM 4
-
-@interface TCLiveVideoLayoutView ()
-@property(nonatomic,strong)NSMutableArray *liveVideos;
-@property(nonatomic,strong)NSMutableArray *liveRnederView;
-@property(nonatomic,strong)UITextView *logView;
-@property(nonatomic,assign) BOOL isShowLogInfo;
-@property(nonatomic,assign) NSDate *startTime;
-@property (nonatomic, strong) TXCVideoPreprocessor *preProcessor;
-@property (nonatomic, assign) Byte *processorBytes;
-@end
-
-@implementation TCLiveVideoLayoutView
-
--(instancetype)initWithFrame:(CGRect)frame{
- if (self = [super initWithFrame:frame]) {
- self.backgroundColor = [UIColor clearColor];
- self.layoutStyle = TCLiveRoomVideoLayoutStyle_1v3;
- [self initialVideoViews];
- [[TILLiveManager getInstance] setAVListener:self];
- [[ILiveRoomManager getInstance] setLocalVideoDelegate:self];
- [[ILiveRoomManager getInstance] setRemoteVideoDelegate:self];
- [[ILiveRoomManager getInstance] setScreenVideoDelegate:self];
- //美颜处理器
- self.preProcessor = [[TXCVideoPreprocessor alloc] init];
- [self.preProcessor setDelegate:self];
- //记录进入时间
- self.startTime = [NSDate date];
- }
- return self;
-}
-//初始化每路视频view
-- (void)initialVideoViews{
- _liveVideos = [NSMutableArray array];
- //自定义视窗数组
- NSArray *frames = [self customLayoutFrames];
- for (int i = 0; i < frames.count; i++) {
- TCLiveVideoElementView *view = [[TCLiveVideoElementView alloc] initWithFrame:CGRectZero];
- view.delegate = self;
- [self addSubview:view];
- [_liveVideos addObject:view];
- }
-}
--(UITextView *)logView{
- if(!_logView){
- _logView = [[UITextView alloc] initWithFrame:CGRectMake(0, self.frame.size.height/5, self.frame.size.width/3*2, self.frame.size.height/2)];
- _logView.textColor = [UIColor colorWithRGBHex:0xFF4081];
- _logView.font = [UIFont systemFontOfSize:14];
- _logView.backgroundColor = [UIColor clearColor];
- _logView.editable = NO;
- }
- return _logView;
-}
-
-//自定义布局(开发者可自定义每个视窗的frame来实现,视窗个数即为frames数组个数)
-- (NSArray *)customLayoutFrames{
- NSMutableArray *frames = [NSMutableArray array];
- if (TCLiveRoomVideoLayoutStyle_1v3 == _layoutStyle) {
- [frames removeAllObjects];
- int smallViewWidth = ((self.frame.size.height - 20 - 150 - 10 *2)/3)*(3.0/4.0);
- int smallViewHeight = (self.frame.size.height - 20 - 150 - 10 *2)/3;
- CGRect frame1 = self.bounds;
- CGRect frame2 = CGRectMake(self.bounds.size.width - 10 - smallViewWidth, 84 , smallViewWidth, smallViewHeight);
- CGRect frame3 = CGRectMake(self.bounds.size.width - 10 - smallViewWidth, frame2.origin.y + frame2.size.height + 10, smallViewWidth, smallViewHeight);
- CGRect frame4 = CGRectMake(self.bounds.size.width - 10 - smallViewWidth, frame3.origin.y + frame3.size.height + 10, smallViewWidth, smallViewHeight);
-
- [frames addObject:[NSValue valueWithCGRect:frame1]];
- [frames addObject:[NSValue valueWithCGRect:frame2]];
- [frames addObject:[NSValue valueWithCGRect:frame3]];
- [frames addObject:[NSValue valueWithCGRect:frame4]];
- }
- else if (TCLiveRoomVideoLayoutStyle_4_geizi == _layoutStyle) {
- [frames removeAllObjects];
- CGRect frame1 = CGRectMake(20, 50, (self.frame.size.width -40)/2, (self.frame.size.height - 100)/2);
- CGRect frame2 = CGRectMake(20 + (self.frame.size.width -40)/2 +1, 50, (self.frame.size.width -40)/2, (self.frame.size.height - 100)/2);
- CGRect frame3 = CGRectMake(20, 50 + (self.frame.size.height - 100)/2 +1, (self.frame.size.width -40)/2, (self.frame.size.height - 100)/2);
- CGRect frame4 = CGRectMake(20 + (self.frame.size.width -40)/2 +1, 50 + (self.frame.size.height - 100)/2 +1,(self.frame.size.width -40)/2, (self.frame.size.height - 100)/2);
- [frames addObject:[NSValue valueWithCGRect:frame1]];
- [frames addObject:[NSValue valueWithCGRect:frame2]];
- [frames addObject:[NSValue valueWithCGRect:frame3]];
- [frames addObject:[NSValue valueWithCGRect:frame4]];
- }
- return frames;
-}
-
-//添加视频画面
--(void)addLiveRenderView:(ILiveRenderView *)renderView{
- NSArray *frames = [self customLayoutFrames];
- for (int i = 0; i < _liveVideos.count;i++) {
- TCLiveVideoElementView *videoView = _liveVideos[i];
- videoView.frame = [frames[i] CGRectValue];
- if (![self getLiveRenderViewOnElementView:videoView]) {
- renderView.frame = videoView.bounds;
- [videoView insertSubview:renderView atIndex:0];
- break;
- }
- }
-}
-//移除视频画面
-- (void)removeLiverRenderVeiw:(ILiveRenderView *)renderView{
- if ([[renderView superview] isKindOfClass:[TCLiveVideoElementView class]]) {
- TCLiveVideoElementView *videoView = (TCLiveVideoElementView *)[renderView superview];
- videoView.frame = CGRectZero;
- [renderView removeFromSuperview];
- }
-}
-
-//画面切换
-- (void)tapHandle:(TCLiveVideoElementView *)view{
- NSUInteger index = [_liveVideos indexOfObject:view];
- TCLiveVideoElementView *bigView = _liveVideos[0];
- ILiveRenderView *bigRenderView = [self getLiveRenderViewOnElementView:bigView];
- ILiveRenderView *renderView = [self getLiveRenderViewOnElementView:view];
- if (index > 0) {
- [UIView animateWithDuration:0.5 animations:^{
- bigView.frame = view.frame;
- view.frame = [[self customLayoutFrames][0] CGRectValue];
- bigRenderView.frame = bigView.bounds;
- renderView.frame = view.bounds;
- [self.liveVideos exchangeObjectAtIndex:0 withObjectAtIndex:index];
- [self exchangeSubviewAtIndex:0 withSubviewAtIndex:index];
- } completion:^(BOOL finished) {
-
- }];
-
- }
-
-}
-//获取指定视窗的渲染view
-- (ILiveRenderView *)getLiveRenderViewOnElementView:(TCLiveVideoElementView *)elementView{
- ILiveRenderView *renderView = nil;
- for (id view in [elementView subviews]) {
- if ([view isKindOfClass:[ILiveRenderView class]]) {
- renderView = view;
- }
- }
- return renderView;
-}
--(void)setBeautyLevel:(NSInteger)level{
- [self.preProcessor setBeautyLevel:level];
-}
-#pragma mark - ILiveMemStatusListener
-//房间成员状态变化事件
-- (BOOL)onEndpointsUpdateInfo:(QAVUpdateEvent)event updateList:(NSArray *)endpoints{
- if (endpoints.count <= 0) {
- return NO;
- }
- for (QAVEndpoint *endoption in endpoints) {
- switch (event) {
- case QAV_EVENT_ID_ENDPOINT_HAS_CAMERA_VIDEO:
- {
- ILiveFrameDispatcher *frameDispatcher = [[ILiveRoomManager getInstance] getFrameDispatcher];
- ILiveRenderView *renderView = [frameDispatcher addRenderAt:CGRectZero forIdentifier:endoption.identifier srcType:QAVVIDEO_SRC_TYPE_CAMERA];
- renderView.isRotate = NO;
- renderView.autoRotate = NO;
- renderView.isMirror = YES;
- renderView.identifier = endoption.identifier;
- renderView.diffDirectionRenderMode = ILIVERENDERMODE_SCALEASPECTFILL;
- if ([[TCLiveRequestManager getInstance].userID isEqualToString:endoption.identifier]) {
- renderView.rotateAngle = ILIVEROTATION_90;
- }
- [self addLiveRenderView:renderView];
- }
- break;
- case QAV_EVENT_ID_ENDPOINT_NO_CAMERA_VIDEO:
- {
- ILiveFrameDispatcher *frameDispatcher = [[ILiveRoomManager getInstance] getFrameDispatcher];
- ILiveRenderView *renderView = [frameDispatcher removeRenderViewFor:endoption.identifier srcType:QAVVIDEO_SRC_TYPE_CAMERA];
- [self removeLiverRenderVeiw:renderView];
- }
- break;
-
- default:
- break;
- }
- }
- return YES;
-}
-/***本地画面帧数据回调***/
-#pragma mark - QAVLocalVideoDelegate
-- (void)OnLocalVideoPreview:(QAVVideoFrame *)frameData{
- [self showElementVideoInfoWithVideoFrame:frameData];
-}
-
-- (void)OnLocalVideoPreProcess:(QAVVideoFrame *)frameData{
-
-
- [self.preProcessor setOutputSize:CGSizeMake(frameData.frameDesc.width, frameData.frameDesc.height)];
- [self.preProcessor setCropRect:CGRectMake(0, 0,frameData.frameDesc.width, frameData.frameDesc.height)];
- [self.preProcessor processFrame:frameData.data width:frameData.frameDesc.width height:frameData.frameDesc.height orientation:TXE_ROTATION_0 inputFormat:TXE_FRAME_FORMAT_NV12 outputFormat:TXE_FRAME_FORMAT_NV12];
- //将处理完的数据拷贝到原来的地址空间,如果是同步处理,此时会先执行didProcessFrame回调
- if(self.processorBytes){
- memcpy(frameData.data, self.processorBytes, frameData.frameDesc.width * frameData.frameDesc.height * 3 / 2);
- }
-}
-
-- (void)OnLocalVideoRawSampleBuf:(CMSampleBufferRef)buf result:(CMSampleBufferRef *)ret{
-
-}
-
-/***远端视频帧数据回调***/
-#pragma mark - QAVRemoteVideoDelegate
-- (void)OnVideoPreview:(QAVVideoFrame *)frameData{
- [self showElementVideoInfoWithVideoFrame:frameData];
-}
-/***远端屏幕分享帧数据回调***/
-#pragma mark - ILiveScreenVideoDelegate
-
--(void)onScreenVideoPreview:(QAVVideoFrame *)frameData{
- [self showElementVideoInfoWithVideoFrame:frameData];
-}
-/***首帧回调***/
-#pragma mark - ILVLiveAVListener
-- (void)onFirstFrameRecved:(int)width height:(int)height identifier:(NSString *)identifier srcType:(avVideoSrcType)srcType;{
-
-}
-/***美颜相关处理***/
-#pragma mark - TXIVideoPreprocessorDelegate
-- (void)didProcessFrame:(Byte *)bytes width:(NSInteger)width height:(NSInteger)height format:(TXEFrameFormat)format timeStamp:(UInt64)timeStamp
-{
- self.processorBytes = bytes;
-}
-#pragma mark - LOG相关
-- (void)showLogView:(NSString *)qualityParams{
- NSString *role = [[[[qualityParams componentsSeparatedByString:@"ControlRole="] lastObject] componentsSeparatedByString:@","] firstObject];
-
- self.logView.text = [NSString stringWithFormat:@"发送速率:%ldkbps 丢包率:%.1f%%\n接收速率:%ldkbps 丢包率:%.1f%%\n应用CPU:%.1f%% 系统CPU:%.1f%%\n角色:%@\nSDKAPPID:%d\nSDKVersion:%@",(long)[[ILiveRoomManager getInstance] getQualityData].sendRate,[[ILiveRoomManager getInstance] getQualityData].sendLossRate/100.0,(long)[[ILiveRoomManager getInstance] getQualityData].recvRate,[[ILiveRoomManager getInstance] getQualityData].recvLossRate/100.0,[[ILiveRoomManager getInstance] getQualityData].appCPURate/100.0,[[ILiveRoomManager getInstance] getQualityData].sysCPURate/100.0,role,[TCLiveRequestManager getInstance].sdkAppID,[[ILiveSDK getInstance] getVersion]];
- if(![_logView superview]){
- [self addSubview:_logView];
- }
- self.isShowLogInfo = YES;
-}
-
-- (void)showElementVideoInfoWithVideoFrame:(QAVVideoFrame *)frame{
- if(!self.isShowLogInfo){
- return;
- }
- NSString *userId = frame.identifier;
- NSString *fps = @"";
- if (userId.length == 0){
- userId = [TCLiveRequestManager getInstance].userID;
- }
- else{
- NSString *qualityParams = [[[ILiveSDK getInstance] getAVContext].room getQualityTips];
- NSString *decode = [[qualityParams componentsSeparatedByString:@"音频部分:========"] firstObject];
- NSString *itemDecode = [[[[decode componentsSeparatedByString:[NSString stringWithFormat:@"成员:%@",userId]] lastObject] componentsSeparatedByString:@"接收参数"] firstObject];
- fps = [[[[itemDecode componentsSeparatedByString:@"FPS="] lastObject] componentsSeparatedByString:@","] firstObject];
- }
- int width = frame.frameDesc.width;
- int height = frame.frameDesc.height;
- for (int i = 0; i < _liveVideos.count;i++) {
- TCLiveVideoElementView *videoView = _liveVideos[i];
- ILiveRenderView *renderView = [self getLiveRenderViewOnElementView:videoView];
- if ([renderView.identifier isEqualToString:userId]) {
- if ([userId isEqualToString:[TCLiveRequestManager getInstance].userID]) {
- videoView.videoInfoLable.text = [NSString stringWithFormat:@"%dx%d",width,height];
- }
- else{
- videoView.videoInfoLable.text = [NSString stringWithFormat:@"%dx%d fps:%d",width,height,[fps intValue]/10];
- }
- videoView.userIdLabel.text = [NSString stringWithFormat:@"%@",userId];
-
- }
- }
-}
-
-- (void)closeLogView{
- [_logView removeFromSuperview];
- _logView = nil;
- for (int i = 0; i < _liveVideos.count;i++) {
- TCLiveVideoElementView *videoView = _liveVideos[i];
- [videoView.userIdLabel removeFromSuperview];
- videoView.userIdLabel = nil;
- [videoView.videoInfoLable removeFromSuperview];
- videoView.videoInfoLable = nil;
- }
- self.isShowLogInfo = NO;
-}
-@end
-
-@interface TCLiveVideoElementView()
-@property(nonatomic,strong) UIPanGestureRecognizer *panGesture;
-@end
-
-@implementation TCLiveVideoElementView
-
--(instancetype)initWithFrame:(CGRect)frame{
- if (self = [super initWithFrame:frame]) {
- [self ennableDraggable:YES];
- UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestuer:)];
- [self addGestureRecognizer:tap];
- }
- return self;
-}
-- (UILabel *)userIdLabel{
- if (!_userIdLabel) {
- _userIdLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 12, self.bounds.size.width, 8)];
- _userIdLabel.textColor = [UIColor colorWithRGBHex:0xFF4081];
- _userIdLabel.textAlignment = NSTextAlignmentLeft;
- _userIdLabel.font = [UIFont systemFontOfSize:9];
- [self addSubview:_userIdLabel];
- }
- return _userIdLabel;
-}
--(UILabel *)videoInfoLable{
- if (!_videoInfoLable) {
- _videoInfoLable = [[UILabel alloc] initWithFrame:CGRectMake(0, 0 , self.bounds.size.width, 12)];
- _videoInfoLable.textColor = [UIColor colorWithRGBHex:0xFF4081];
- _videoInfoLable.textAlignment = NSTextAlignmentLeft;
- _videoInfoLable.font = [UIFont systemFontOfSize:13];
- [self addSubview:_videoInfoLable];
- }
- return _videoInfoLable;
-}
-- (void)layoutSubviews{
- if (self.bounds.size.width == [UIScreen mainScreen].bounds.size.width) {
- _videoInfoLable.frame = CGRectMake(0, 84 , self.bounds.size.width, 12);
- _userIdLabel.frame = CGRectMake(0, 12 + 84, self.bounds.size.width, 8);
- }
- else{
- _videoInfoLable.frame = CGRectMake(0, 0 , self.bounds.size.width, 12);
- _userIdLabel.frame = CGRectMake(0, 12, self.bounds.size.width, 8);
- }
-}
-//可拖动能力
--(void)ennableDraggable:(BOOL)draggable {
- [self setUserInteractionEnabled:YES];
- [self removeConstraints:self.constraints];
- for (NSLayoutConstraint *constraint in self.superview.constraints) {
- if ([constraint.firstItem isEqual:self]) {
- [self.superview removeConstraint:constraint];
- }
- }
- [self setTranslatesAutoresizingMaskIntoConstraints:YES];
- if (draggable) {
- if (!_panGesture) {
- _panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
- _panGesture.delegate = self;
- [self addGestureRecognizer:_panGesture];
- }
- }else{
- if (_panGesture) {
- _panGesture = nil;
- [self removeGestureRecognizer:_panGesture];
- }
- }
-}
-- (void)tapGestuer:(UITapGestureRecognizer *)gesture{
- if ([_delegate respondsToSelector:@selector(tapHandle:)]) {
- [_delegate tapHandle:self];
- }
-}
-- (void)pan:(UIPanGestureRecognizer *)panGestureRecognizer {
- switch (panGestureRecognizer.state) {
- case UIGestureRecognizerStateBegan: {
- [self dragging:panGestureRecognizer];
- }
- break;
- case UIGestureRecognizerStateChanged: {
- [self dragging:panGestureRecognizer];
- }
- break;
- default:
- break;
- }
-}
-
--(void)dragging:(UIPanGestureRecognizer *)panGestureRecognizer {
- UIView *view = panGestureRecognizer.view;
- CGPoint translation = [panGestureRecognizer translationInView:view.superview];
- CGPoint center = CGPointMake(view.center.x + translation.x, view.center.y + translation.y);
- //不能拖过边界
- CGSize size = view.frame.size;
- CGSize superSize = view.superview.frame.size;
- CGFloat width = size.width;
- CGFloat height = size.height;
- CGFloat superWidth = superSize.width;
- CGFloat superHeight = superSize.height;
- center.x = (center.xsuperWidth)?superWidth-width/2:center.x;
- center.y = (center.ysuperHeight)?superHeight-height/2:center.y;
-
- [view setCenter:center];
- [panGestureRecognizer setTranslation:CGPointZero inView:view.superview];
-}
-@end
-
diff --git a/src/ios/TrtcPlugin.h b/src/ios/TrtcPlugin.h
index 1da8479..0c246e1 100644
--- a/src/ios/TrtcPlugin.h
+++ b/src/ios/TrtcPlugin.h
@@ -1,13 +1,15 @@
//
// TrtcPlugin.h
//
-// Created by 布丁丸子酱 on 2018/12/26.
//
#import
@interface TrtcPlugin : CDVPlugin
+{
+}
-- (void) showCreatePage:(CDVInvokedUrlCommand*)command;
+- (void)joinChannel:(CDVInvokedUrlCommand *)command;
+- (void)userInfoChange:(CDVInvokedUrlCommand *)command;
@end
diff --git a/src/ios/TrtcPlugin.m b/src/ios/TrtcPlugin.m
index 0bfa416..28a11fd 100644
--- a/src/ios/TrtcPlugin.m
+++ b/src/ios/TrtcPlugin.m
@@ -1,16 +1,21 @@
//
// TrtcPlugin.m
//
-// Created by 布丁丸子酱 on 2018/12/26.
//
#import "TrtcPlugin.h"
-#import "TCLiveRequestManager.h"
-#import
-#import "TCLiveJoinRoomViewController.h"
-#import
-#import "UIToastView.h"
-#import
+
+#import "VideoCallingViewController.h"
+// #import "TCLiveRequestManager.h"
+// #import
+// #import "TCLiveJoinRoomViewController.h"
+// #import
+// #import "UIToastView.h"
+// #import
+#import
+
+#import "Events.h";
+#import "CordovaEventKit.h";
@interface TrtcPlugin()
{}
@@ -18,32 +23,56 @@
@implementation TrtcPlugin
-- (void) showCreatePage:(CDVInvokedUrlCommand*)command {
- NSLog(@"showCreatePage");
- [[TCLiveRequestManager getInstance] requestLoginInfo:^(int code) {
- if (code == 0) {
- dispatch_async(dispatch_get_main_queue(), ^{
- int retCode = [[ILiveSDK getInstance] initSdk:[TCLiveRequestManager getInstance].sdkAppID accountType:[TCLiveRequestManager getInstance].accountType];
- NSLog(@"initSdk success %d",retCode);
- if (retCode == 0) {
- NSLog(@"userId & sig:");
- NSLog(@"%@", [TCLiveRequestManager getInstance].userID);
- NSLog(@"%@", [TCLiveRequestManager getInstance].userSig);
- [[ILiveLoginManager getInstance] iLiveLogin:[TCLiveRequestManager getInstance].userID sig:[TCLiveRequestManager getInstance].userSig succ:^{
- NSLog(@"-----> login succ");
- [[UIToastView getInstance] showToastWithMessage:@"登录成功" toastMode:UIToastShowMode_Succ];
- } failed:^(NSString *module, int errId, NSString *errMsg) {
- NSLog(@"-----> login fail,%@ %d %@",module, errId, errMsg);
- [[UIToastView getInstance] showToastWithMessage:@"登录失败" toastMode:UIToastShowMode_fail];
- }];
- }
- });
+
+
+-(void)joinChannel:(CDVInvokedUrlCommand*)command {
+ NSDictionary* params = [command.arguments objectAtIndex:0];
+ NSLog(@"TRTC - joinChannel::%@",params);
+ CDVPluginResult* pluginResult = nil;
+ VideoCallingViewController *vc = [[VideoCallingViewController alloc]
+ initWithRoomId:[params[@"ROOM_ID"] intValue]
+ userId:params[@"USER_ID"]
+ appId:[params[@"SDK_APP_ID"] intValue]
+ userSig:params[@"USER_SIG"]];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ if (@available(iOS 13.0, *)){
+ vc.modalPresentationStyle = UIModalPresentationFullScreen;
}
- }];
- TCLiveJoinRoomViewController *vc = [TCLiveJoinRoomViewController new];
-// vc.defaultRoomId = self.defaultRoomId;
- UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
- [self.viewController presentViewController:nav animated:YES completion:nil];
+ [self.viewController presentViewController:vc animated:YES completion:nil];
+ });
+}
+
+
+-(void)userInfoChange:(CDVInvokedUrlCommand*)command {
+ NSDictionary* params = [command.arguments objectAtIndex:0];
+ NSLog(@"TRTC - userInfoChange::%@",params);
+ [Events fireEvent:@"userinfo.update" extra:params];
+}
+
+
+
+#ifdef __CORDOVA_4_0_0
+
+- (void)pluginInitialize {
+ NSLog(@"TRTC - pluginInitialize ");
+ [self initPlugin];
+}
+
+#else
+
+- (CDVPlugin*)initWithWebView:(WKWebView*)theWebView{
+ NSLog(@"TRTC - initWithWebView ");
+ if (self=[super initWithWebView:theWebView]) {
+ }
+ [self initPlugin];
+ return self;
+}
+
+#endif
+
+-(void)initPlugin{
+ NSLog(@"TRTC - initPlugin ");
+ [CordovaEventKit init:self];
}
@end
diff --git a/src/ios/TrtcUserInfo.h b/src/ios/TrtcUserInfo.h
new file mode 100644
index 0000000..2bb8371
--- /dev/null
+++ b/src/ios/TrtcUserInfo.h
@@ -0,0 +1,31 @@
+//
+// TrtcUserInfo.h
+// shuto-cne
+//
+// Created by 范大德 on 2022/3/30.
+//
+
+#ifndef TrtcUserInfo_h
+#define TrtcUserInfo_h
+
+
+#endif /* TrtcUserInfo_h */
+@interface TrtcUserInfo: NSObject
+{}
+// 自定义类的初始化方法
+
+// 过去类型instancetype 是 id 类型
+
+- (instancetype)initWithPersonid:(NSString *)personid;
+
+- (NSString*) personid;
+-(NSString *)displayName;
+
+-(BOOL)isShareUser;
+
+-(BOOL)isLocalUser;
+
+-(void)setLocal:(BOOL) value;
+-(void)setDisplayName:(NSString *)value;
+
+@end
diff --git a/src/ios/TrtcUserInfo.m b/src/ios/TrtcUserInfo.m
new file mode 100644
index 0000000..5bb1c32
--- /dev/null
+++ b/src/ios/TrtcUserInfo.m
@@ -0,0 +1,68 @@
+//
+// TrtcUserInfo.m
+// shuto-cne
+//
+// Created by 范大德 on 2022/3/21.
+//
+
+#import
+#import "TrtcUserInfo.h"
+@interface TrtcUserInfo()
+{
+ NSString* personid;
+ NSString* displayName;
+ BOOL local;
+}
+
+@end
+@implementation TrtcUserInfo
+
+- (instancetype)initWithPersonid:(NSString *)userId
+{
+ personid = userId;
+ return self; // 返回类本身不能忘
+}
+
+- (NSString*) personid{
+ return personid;
+}
+
+
+-(NSString *)displayName{
+ return displayName;
+}
+
+-(BOOL)isShareUser{
+ return personid != nil && [personid hasPrefix:@"share_"];
+}
+
+-(BOOL)isLocalUser{
+ return local;
+}
+
+-(void)setLocal:(BOOL) value{
+ local = value;
+}
+-(void)setDisplayName:(NSString *)value{
+ displayName = value;
+}
+- (NSUInteger)hash
+{
+ return [personid hash];
+}
+
+- (BOOL)isEqual: (id)obj
+{
+ if( obj == nil){
+ return NO;
+ }
+ if([obj isKindOfClass: [TrtcUserInfo class]]){
+ TrtcUserInfo *user = (TrtcUserInfo*)obj;
+ return personid == nil ? [user personid] == nil : [personid isEqual: [user personid]];
+ } else if([obj isKindOfClass: [NSString class]]){
+ return personid == nil ? obj == nil : [personid isEqual: obj];
+ } else {
+ return NO;
+ }
+}
+@end
diff --git a/src/ios/UIView+Toast.h b/src/ios/UIView+Toast.h
new file mode 100644
index 0000000..e2b258b
--- /dev/null
+++ b/src/ios/UIView+Toast.h
@@ -0,0 +1,446 @@
+//
+// UIView+Toast.h
+// Toast
+//
+// Copyright (c) 2011-2017 Charles Scalesse.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#import
+
+extern const NSString * CSToastPositionTop;
+extern const NSString * CSToastPositionCenter;
+extern const NSString * CSToastPositionBottom;
+
+@class CSToastStyle;
+
+/**
+ Toast is an Objective-C category that adds toast notifications to the UIView
+ object class. It is intended to be simple, lightweight, and easy to use. Most
+ toast notifications can be triggered with a single line of code.
+
+ The `makeToast:` methods create a new view and then display it as toast.
+
+ The `showToast:` methods display any view as toast.
+
+ */
+@interface UIView (Toast)
+
+/**
+ Creates and presents a new toast view with a message and displays it with the
+ default duration and position. Styled using the shared style.
+
+ @param message The message to be displayed
+ */
+- (void)makeToast:(NSString *)message;
+
+/**
+ Creates and presents a new toast view with a message. Duration and position
+ can be set explicitly. Styled using the shared style.
+
+ @param message The message to be displayed
+ @param duration The toast duration
+ @param position The toast's center point. Can be one of the predefined CSToastPosition
+ constants or a `CGPoint` wrapped in an `NSValue` object.
+ */
+- (void)makeToast:(NSString *)message
+ duration:(NSTimeInterval)duration
+ position:(id)position;
+
+/**
+ Creates and presents a new toast view with a message. Duration, position, and
+ style can be set explicitly.
+
+ @param message The message to be displayed
+ @param duration The toast duration
+ @param position The toast's center point. Can be one of the predefined CSToastPosition
+ constants or a `CGPoint` wrapped in an `NSValue` object.
+ @param style The style. The shared style will be used when nil
+ */
+- (void)makeToast:(NSString *)message
+ duration:(NSTimeInterval)duration
+ position:(id)position
+ style:(CSToastStyle *)style;
+
+/**
+ Creates and presents a new toast view with a message, title, and image. Duration,
+ position, and style can be set explicitly. The completion block executes when the
+ toast view completes. `didTap` will be `YES` if the toast view was dismissed from
+ a tap.
+
+ @param message The message to be displayed
+ @param duration The toast duration
+ @param position The toast's center point. Can be one of the predefined CSToastPosition
+ constants or a `CGPoint` wrapped in an `NSValue` object.
+ @param title The title
+ @param image The image
+ @param style The style. The shared style will be used when nil
+ @param completion The completion block, executed after the toast view disappears.
+ didTap will be `YES` if the toast view was dismissed from a tap.
+ */
+- (void)makeToast:(NSString *)message
+ duration:(NSTimeInterval)duration
+ position:(id)position
+ title:(NSString *)title
+ image:(UIImage *)image
+ style:(CSToastStyle *)style
+ completion:(void(^)(BOOL didTap))completion;
+
+/**
+ Creates a new toast view with any combination of message, title, and image.
+ The look and feel is configured via the style. Unlike the `makeToast:` methods,
+ this method does not present the toast view automatically. One of the showToast:
+ methods must be used to present the resulting view.
+
+ @warning if message, title, and image are all nil, this method will return nil.
+
+ @param message The message to be displayed
+ @param title The title
+ @param image The image
+ @param style The style. The shared style will be used when nil
+ @return The newly created toast view
+ */
+- (UIView *)toastViewForMessage:(NSString *)message
+ title:(NSString *)title
+ image:(UIImage *)image
+ style:(CSToastStyle *)style;
+
+/**
+ Hides the active toast. If there are multiple toasts active in a view, this method
+ hides the oldest toast (the first of the toasts to have been presented).
+
+ @see `hideAllToasts` to remove all active toasts from a view.
+
+ @warning This method has no effect on activity toasts. Use `hideToastActivity` to
+ hide activity toasts.
+ */
+- (void)hideToast;
+
+/**
+ Hides an active toast.
+
+ @param toast The active toast view to dismiss. Any toast that is currently being displayed
+ on the screen is considered active.
+
+ @warning this does not clear a toast view that is currently waiting in the queue.
+ */
+- (void)hideToast:(UIView *)toast;
+
+/**
+ Hides all active toast views and clears the queue.
+ */
+- (void)hideAllToasts;
+
+/**
+ Hides all active toast views, with options to hide activity and clear the queue.
+
+ @param includeActivity If `true`, toast activity will also be hidden. Default is `false`.
+ @param clearQueue If `true`, removes all toast views from the queue. Default is `true`.
+ */
+- (void)hideAllToasts:(BOOL)includeActivity clearQueue:(BOOL)clearQueue;
+
+/**
+ Removes all toast views from the queue. This has no effect on toast views that are
+ active. Use `hideAllToasts` to hide the active toasts views and clear the queue.
+ */
+- (void)clearToastQueue;
+
+/**
+ Creates and displays a new toast activity indicator view at a specified position.
+
+ @warning Only one toast activity indicator view can be presented per superview. Subsequent
+ calls to `makeToastActivity:` will be ignored until hideToastActivity is called.
+
+ @warning `makeToastActivity:` works independently of the showToast: methods. Toast activity
+ views can be presented and dismissed while toast views are being displayed. `makeToastActivity:`
+ has no effect on the queueing behavior of the showToast: methods.
+
+ @param position The toast's center point. Can be one of the predefined CSToastPosition
+ constants or a `CGPoint` wrapped in an `NSValue` object.
+ */
+- (void)makeToastActivity:(id)position;
+
+/**
+ Dismisses the active toast activity indicator view.
+ */
+- (void)hideToastActivity;
+
+/**
+ Displays any view as toast using the default duration and position.
+
+ @param toast The view to be displayed as toast
+ */
+- (void)showToast:(UIView *)toast;
+
+/**
+ Displays any view as toast at a provided position and duration. The completion block
+ executes when the toast view completes. `didTap` will be `YES` if the toast view was
+ dismissed from a tap.
+
+ @param toast The view to be displayed as toast
+ @param duration The notification duration
+ @param position The toast's center point. Can be one of the predefined CSToastPosition
+ constants or a `CGPoint` wrapped in an `NSValue` object.
+ @param completion The completion block, executed after the toast view disappears.
+ didTap will be `YES` if the toast view was dismissed from a tap.
+ */
+- (void)showToast:(UIView *)toast
+ duration:(NSTimeInterval)duration
+ position:(id)position
+ completion:(void(^)(BOOL didTap))completion;
+
+@end
+
+/**
+ `CSToastStyle` instances define the look and feel for toast views created via the
+ `makeToast:` methods as well for toast views created directly with
+ `toastViewForMessage:title:image:style:`.
+
+ @warning `CSToastStyle` offers relatively simple styling options for the default
+ toast view. If you require a toast view with more complex UI, it probably makes more
+ sense to create your own custom UIView subclass and present it with the `showToast:`
+ methods.
+ */
+@interface CSToastStyle : NSObject
+
+/**
+ The background color. Default is `[UIColor blackColor]` at 80% opacity.
+ */
+@property (strong, nonatomic) UIColor *backgroundColor;
+
+/**
+ The title color. Default is `[UIColor whiteColor]`.
+ */
+@property (strong, nonatomic) UIColor *titleColor;
+
+/**
+ The message color. Default is `[UIColor whiteColor]`.
+ */
+@property (strong, nonatomic) UIColor *messageColor;
+
+/**
+ A percentage value from 0.0 to 1.0, representing the maximum width of the toast
+ view relative to it's superview. Default is 0.8 (80% of the superview's width).
+ */
+@property (assign, nonatomic) CGFloat maxWidthPercentage;
+
+/**
+ A percentage value from 0.0 to 1.0, representing the maximum height of the toast
+ view relative to it's superview. Default is 0.8 (80% of the superview's height).
+ */
+@property (assign, nonatomic) CGFloat maxHeightPercentage;
+
+/**
+ The spacing from the horizontal edge of the toast view to the content. When an image
+ is present, this is also used as the padding between the image and the text.
+ Default is 10.0.
+ */
+@property (assign, nonatomic) CGFloat horizontalPadding;
+
+/**
+ The spacing from the vertical edge of the toast view to the content. When a title
+ is present, this is also used as the padding between the title and the message.
+ Default is 10.0.
+ */
+@property (assign, nonatomic) CGFloat verticalPadding;
+
+/**
+ The corner radius. Default is 10.0.
+ */
+@property (assign, nonatomic) CGFloat cornerRadius;
+
+/**
+ The title font. Default is `[UIFont boldSystemFontOfSize:16.0]`.
+ */
+@property (strong, nonatomic) UIFont *titleFont;
+
+/**
+ The message font. Default is `[UIFont systemFontOfSize:16.0]`.
+ */
+@property (strong, nonatomic) UIFont *messageFont;
+
+/**
+ The title text alignment. Default is `NSTextAlignmentLeft`.
+ */
+@property (assign, nonatomic) NSTextAlignment titleAlignment;
+
+/**
+ The message text alignment. Default is `NSTextAlignmentLeft`.
+ */
+@property (assign, nonatomic) NSTextAlignment messageAlignment;
+
+/**
+ The maximum number of lines for the title. The default is 0 (no limit).
+ */
+@property (assign, nonatomic) NSInteger titleNumberOfLines;
+
+/**
+ The maximum number of lines for the message. The default is 0 (no limit).
+ */
+@property (assign, nonatomic) NSInteger messageNumberOfLines;
+
+/**
+ Enable or disable a shadow on the toast view. Default is `NO`.
+ */
+@property (assign, nonatomic) BOOL displayShadow;
+
+/**
+ The shadow color. Default is `[UIColor blackColor]`.
+ */
+@property (strong, nonatomic) UIColor *shadowColor;
+
+/**
+ A value from 0.0 to 1.0, representing the opacity of the shadow.
+ Default is 0.8 (80% opacity).
+ */
+@property (assign, nonatomic) CGFloat shadowOpacity;
+
+/**
+ The shadow radius. Default is 6.0.
+ */
+@property (assign, nonatomic) CGFloat shadowRadius;
+
+/**
+ The shadow offset. The default is `CGSizeMake(4.0, 4.0)`.
+ */
+@property (assign, nonatomic) CGSize shadowOffset;
+
+/**
+ The image size. The default is `CGSizeMake(80.0, 80.0)`.
+ */
+@property (assign, nonatomic) CGSize imageSize;
+
+/**
+ The size of the toast activity view when `makeToastActivity:` is called.
+ Default is `CGSizeMake(100.0, 100.0)`.
+ */
+@property (assign, nonatomic) CGSize activitySize;
+
+/**
+ The fade in/out animation duration. Default is 0.2.
+ */
+@property (assign, nonatomic) NSTimeInterval fadeDuration;
+
+/**
+ Creates a new instance of `CSToastStyle` with all the default values set.
+ */
+- (instancetype)initWithDefaultStyle NS_DESIGNATED_INITIALIZER;
+
+/**
+ @warning Only the designated initializer should be used to create
+ an instance of `CSToastStyle`.
+ */
+- (instancetype)init NS_UNAVAILABLE;
+
+@end
+
+/**
+ `CSToastManager` provides general configuration options for all toast
+ notifications. Backed by a singleton instance.
+ */
+@interface CSToastManager : NSObject
+
+/**
+ Sets the shared style on the singleton. The shared style is used whenever
+ a `makeToast:` method (or `toastViewForMessage:title:image:style:`) is called
+ with with a nil style. By default, this is set to `CSToastStyle`'s default
+ style.
+
+ @param sharedStyle the shared style
+ */
++ (void)setSharedStyle:(CSToastStyle *)sharedStyle;
+
+/**
+ Gets the shared style from the singlton. By default, this is
+ `CSToastStyle`'s default style.
+
+ @return the shared style
+ */
++ (CSToastStyle *)sharedStyle;
+
+/**
+ Enables or disables tap to dismiss on toast views. Default is `YES`.
+
+ @param tapToDismissEnabled YES or NO
+ */
++ (void)setTapToDismissEnabled:(BOOL)tapToDismissEnabled;
+
+/**
+ Returns `YES` if tap to dismiss is enabled, otherwise `NO`.
+ Default is `YES`.
+
+ @return BOOL YES or NO
+ */
++ (BOOL)isTapToDismissEnabled;
+
+/**
+ Enables or disables queueing behavior for toast views. When `YES`,
+ toast views will appear one after the other. When `NO`, multiple Toast
+ views will appear at the same time (potentially overlapping depending
+ on their positions). This has no effect on the toast activity view,
+ which operates independently of normal toast views. Default is `NO`.
+
+ @param queueEnabled YES or NO
+ */
++ (void)setQueueEnabled:(BOOL)queueEnabled;
+
+/**
+ Returns `YES` if the queue is enabled, otherwise `NO`.
+ Default is `NO`.
+
+ @return BOOL
+ */
++ (BOOL)isQueueEnabled;
+
+/**
+ Sets the default duration. Used for the `makeToast:` and
+ `showToast:` methods that don't require an explicit duration.
+ Default is 3.0.
+
+ @param duration The toast duration
+ */
++ (void)setDefaultDuration:(NSTimeInterval)duration;
+
+/**
+ Returns the default duration. Default is 3.0.
+
+ @return duration The toast duration
+*/
++ (NSTimeInterval)defaultDuration;
+
+/**
+ Sets the default position. Used for the `makeToast:` and
+ `showToast:` methods that don't require an explicit position.
+ Default is `CSToastPositionBottom`.
+
+ @param position The default center point. Can be one of the predefined
+ CSToastPosition constants or a `CGPoint` wrapped in an `NSValue` object.
+ */
++ (void)setDefaultPosition:(id)position;
+
+/**
+ Returns the default toast position. Default is `CSToastPositionBottom`.
+
+ @return position The default center point. Will be one of the predefined
+ CSToastPosition constants or a `CGPoint` wrapped in an `NSValue` object.
+ */
++ (id)defaultPosition;
+
+@end
diff --git a/src/ios/UIView+Toast.m b/src/ios/UIView+Toast.m
new file mode 100644
index 0000000..4e5131a
--- /dev/null
+++ b/src/ios/UIView+Toast.m
@@ -0,0 +1,586 @@
+//
+// UIView+Toast.m
+// Toast
+//
+// Copyright (c) 2011-2017 Charles Scalesse.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#import "UIView+Toast.h"
+#import
+#import
+
+// Positions
+NSString * CSToastPositionTop = @"CSToastPositionTop";
+NSString * CSToastPositionCenter = @"CSToastPositionCenter";
+NSString * CSToastPositionBottom = @"CSToastPositionBottom";
+
+// Keys for values associated with toast views
+static const NSString * CSToastTimerKey = @"CSToastTimerKey";
+static const NSString * CSToastDurationKey = @"CSToastDurationKey";
+static const NSString * CSToastPositionKey = @"CSToastPositionKey";
+static const NSString * CSToastCompletionKey = @"CSToastCompletionKey";
+
+// Keys for values associated with self
+static const NSString * CSToastActiveKey = @"CSToastActiveKey";
+static const NSString * CSToastActivityViewKey = @"CSToastActivityViewKey";
+static const NSString * CSToastQueueKey = @"CSToastQueueKey";
+
+@interface UIView (ToastPrivate)
+
+/**
+ These private methods are being prefixed with "cs_" to reduce the likelihood of non-obvious
+ naming conflicts with other UIView methods.
+
+ @discussion Should the public API also use the cs_ prefix? Technically it should, but it
+ results in code that is less legible. The current public method names seem unlikely to cause
+ conflicts so I think we should favor the cleaner API for now.
+ */
+- (void)cs_showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)position;
+- (void)cs_hideToast:(UIView *)toast;
+- (void)cs_hideToast:(UIView *)toast fromTap:(BOOL)fromTap;
+- (void)cs_toastTimerDidFinish:(NSTimer *)timer;
+- (void)cs_handleToastTapped:(UITapGestureRecognizer *)recognizer;
+- (CGPoint)cs_centerPointForPosition:(id)position withToast:(UIView *)toast;
+- (NSMutableArray *)cs_toastQueue;
+
+@end
+
+@implementation UIView (Toast)
+
+#pragma mark - Make Toast Methods
+
+- (void)makeToast:(NSString *)message {
+ [self makeToast:message duration:[CSToastManager defaultDuration] position:[CSToastManager defaultPosition] style:nil];
+}
+
+- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position {
+ [self makeToast:message duration:duration position:position style:nil];
+}
+
+- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position style:(CSToastStyle *)style {
+ UIView *toast = [self toastViewForMessage:message title:nil image:nil style:style];
+ [self showToast:toast duration:duration position:position completion:nil];
+}
+
+- (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position title:(NSString *)title image:(UIImage *)image style:(CSToastStyle *)style completion:(void(^)(BOOL didTap))completion {
+ UIView *toast = [self toastViewForMessage:message title:title image:image style:style];
+ [self showToast:toast duration:duration position:position completion:completion];
+}
+
+#pragma mark - Show Toast Methods
+
+- (void)showToast:(UIView *)toast {
+ [self showToast:toast duration:[CSToastManager defaultDuration] position:[CSToastManager defaultPosition] completion:nil];
+}
+
+- (void)showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)position completion:(void(^)(BOOL didTap))completion {
+ // sanity
+ if (toast == nil) return;
+
+ // store the completion block on the toast view
+ objc_setAssociatedObject(toast, &CSToastCompletionKey, completion, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+
+ if ([CSToastManager isQueueEnabled] && [self.cs_activeToasts count] > 0) {
+ // we're about to queue this toast view so we need to store the duration and position as well
+ objc_setAssociatedObject(toast, &CSToastDurationKey, @(duration), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+ objc_setAssociatedObject(toast, &CSToastPositionKey, position, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+
+ // enqueue
+ [self.cs_toastQueue addObject:toast];
+ } else {
+ // present
+ [self cs_showToast:toast duration:duration position:position];
+ }
+}
+
+#pragma mark - Hide Toast Methods
+
+- (void)hideToast {
+ [self hideToast:[[self cs_activeToasts] firstObject]];
+}
+
+- (void)hideToast:(UIView *)toast {
+ // sanity
+ if (!toast || ![[self cs_activeToasts] containsObject:toast]) return;
+
+ [self cs_hideToast:toast];
+}
+
+- (void)hideAllToasts {
+ [self hideAllToasts:NO clearQueue:YES];
+}
+
+- (void)hideAllToasts:(BOOL)includeActivity clearQueue:(BOOL)clearQueue {
+ if (clearQueue) {
+ [self clearToastQueue];
+ }
+
+ for (UIView *toast in [self cs_activeToasts]) {
+ [self hideToast:toast];
+ }
+
+ if (includeActivity) {
+ [self hideToastActivity];
+ }
+}
+
+- (void)clearToastQueue {
+ [[self cs_toastQueue] removeAllObjects];
+}
+
+#pragma mark - Private Show/Hide Methods
+
+- (void)cs_showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)position {
+ toast.center = [self cs_centerPointForPosition:position withToast:toast];
+ toast.alpha = 0.0;
+
+ if ([CSToastManager isTapToDismissEnabled]) {
+ UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(cs_handleToastTapped:)];
+ [toast addGestureRecognizer:recognizer];
+ toast.userInteractionEnabled = YES;
+ toast.exclusiveTouch = YES;
+ }
+
+ [[self cs_activeToasts] addObject:toast];
+
+ [self addSubview:toast];
+
+ [UIView animateWithDuration:[[CSToastManager sharedStyle] fadeDuration]
+ delay:0.0
+ options:(UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction)
+ animations:^{
+ toast.alpha = 1.0;
+ } completion:^(BOOL finished) {
+ NSTimer *timer = [NSTimer timerWithTimeInterval:duration target:self selector:@selector(cs_toastTimerDidFinish:) userInfo:toast repeats:NO];
+ [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
+ objc_setAssociatedObject(toast, &CSToastTimerKey, timer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+ }];
+}
+
+- (void)cs_hideToast:(UIView *)toast {
+ [self cs_hideToast:toast fromTap:NO];
+}
+
+- (void)cs_hideToast:(UIView *)toast fromTap:(BOOL)fromTap {
+ NSTimer *timer = (NSTimer *)objc_getAssociatedObject(toast, &CSToastTimerKey);
+ [timer invalidate];
+
+ [UIView animateWithDuration:[[CSToastManager sharedStyle] fadeDuration]
+ delay:0.0
+ options:(UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionBeginFromCurrentState)
+ animations:^{
+ toast.alpha = 0.0;
+ } completion:^(BOOL finished) {
+ [toast removeFromSuperview];
+
+ // remove
+ [[self cs_activeToasts] removeObject:toast];
+
+ // execute the completion block, if necessary
+ void (^completion)(BOOL didTap) = objc_getAssociatedObject(toast, &CSToastCompletionKey);
+ if (completion) {
+ completion(fromTap);
+ }
+
+ if ([self.cs_toastQueue count] > 0) {
+ // dequeue
+ UIView *nextToast = [[self cs_toastQueue] firstObject];
+ [[self cs_toastQueue] removeObjectAtIndex:0];
+
+ // present the next toast
+ NSTimeInterval duration = [objc_getAssociatedObject(nextToast, &CSToastDurationKey) doubleValue];
+ id position = objc_getAssociatedObject(nextToast, &CSToastPositionKey);
+ [self cs_showToast:nextToast duration:duration position:position];
+ }
+ }];
+}
+
+#pragma mark - View Construction
+
+- (UIView *)toastViewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image style:(CSToastStyle *)style {
+ // sanity
+ if (message == nil && title == nil && image == nil) return nil;
+
+ // default to the shared style
+ if (style == nil) {
+ style = [CSToastManager sharedStyle];
+ }
+
+ // dynamically build a toast view with any combination of message, title, & image
+ UILabel *messageLabel = nil;
+ UILabel *titleLabel = nil;
+ UIImageView *imageView = nil;
+
+ UIView *wrapperView = [[UIView alloc] init];
+ wrapperView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
+ wrapperView.layer.cornerRadius = style.cornerRadius;
+
+ if (style.displayShadow) {
+ wrapperView.layer.shadowColor = style.shadowColor.CGColor;
+ wrapperView.layer.shadowOpacity = style.shadowOpacity;
+ wrapperView.layer.shadowRadius = style.shadowRadius;
+ wrapperView.layer.shadowOffset = style.shadowOffset;
+ }
+
+ wrapperView.backgroundColor = style.backgroundColor;
+
+ if(image != nil) {
+ imageView = [[UIImageView alloc] initWithImage:image];
+ imageView.contentMode = UIViewContentModeScaleAspectFit;
+ imageView.frame = CGRectMake(style.horizontalPadding, style.verticalPadding, style.imageSize.width, style.imageSize.height);
+ }
+
+ CGRect imageRect = CGRectZero;
+
+ if(imageView != nil) {
+ imageRect.origin.x = style.horizontalPadding;
+ imageRect.origin.y = style.verticalPadding;
+ imageRect.size.width = imageView.bounds.size.width;
+ imageRect.size.height = imageView.bounds.size.height;
+ }
+
+ if (title != nil) {
+ titleLabel = [[UILabel alloc] init];
+ titleLabel.numberOfLines = style.titleNumberOfLines;
+ titleLabel.font = style.titleFont;
+ titleLabel.textAlignment = style.titleAlignment;
+ titleLabel.lineBreakMode = NSLineBreakByTruncatingTail;
+ titleLabel.textColor = style.titleColor;
+ titleLabel.backgroundColor = [UIColor clearColor];
+ titleLabel.alpha = 1.0;
+ titleLabel.text = title;
+
+ // size the title label according to the length of the text
+ CGSize maxSizeTitle = CGSizeMake((self.bounds.size.width * style.maxWidthPercentage) - imageRect.size.width, self.bounds.size.height * style.maxHeightPercentage);
+ CGSize expectedSizeTitle = [titleLabel sizeThatFits:maxSizeTitle];
+ // UILabel can return a size larger than the max size when the number of lines is 1
+ expectedSizeTitle = CGSizeMake(MIN(maxSizeTitle.width, expectedSizeTitle.width), MIN(maxSizeTitle.height, expectedSizeTitle.height));
+ titleLabel.frame = CGRectMake(0.0, 0.0, expectedSizeTitle.width, expectedSizeTitle.height);
+ }
+
+ if (message != nil) {
+ messageLabel = [[UILabel alloc] init];
+ messageLabel.numberOfLines = style.messageNumberOfLines;
+ messageLabel.font = style.messageFont;
+ messageLabel.textAlignment = style.messageAlignment;
+ messageLabel.lineBreakMode = NSLineBreakByTruncatingTail;
+ messageLabel.textColor = style.messageColor;
+ messageLabel.backgroundColor = [UIColor clearColor];
+ messageLabel.alpha = 1.0;
+ messageLabel.text = message;
+
+ CGSize maxSizeMessage = CGSizeMake((self.bounds.size.width * style.maxWidthPercentage) - imageRect.size.width, self.bounds.size.height * style.maxHeightPercentage);
+ CGSize expectedSizeMessage = [messageLabel sizeThatFits:maxSizeMessage];
+ // UILabel can return a size larger than the max size when the number of lines is 1
+ expectedSizeMessage = CGSizeMake(MIN(maxSizeMessage.width, expectedSizeMessage.width), MIN(maxSizeMessage.height, expectedSizeMessage.height));
+ messageLabel.frame = CGRectMake(0.0, 0.0, expectedSizeMessage.width, expectedSizeMessage.height);
+ }
+
+ CGRect titleRect = CGRectZero;
+
+ if(titleLabel != nil) {
+ titleRect.origin.x = imageRect.origin.x + imageRect.size.width + style.horizontalPadding;
+ titleRect.origin.y = style.verticalPadding;
+ titleRect.size.width = titleLabel.bounds.size.width;
+ titleRect.size.height = titleLabel.bounds.size.height;
+ }
+
+ CGRect messageRect = CGRectZero;
+
+ if(messageLabel != nil) {
+ messageRect.origin.x = imageRect.origin.x + imageRect.size.width + style.horizontalPadding;
+ messageRect.origin.y = titleRect.origin.y + titleRect.size.height + style.verticalPadding;
+ messageRect.size.width = messageLabel.bounds.size.width;
+ messageRect.size.height = messageLabel.bounds.size.height;
+ }
+
+ CGFloat longerWidth = MAX(titleRect.size.width, messageRect.size.width);
+ CGFloat longerX = MAX(titleRect.origin.x, messageRect.origin.x);
+
+ // Wrapper width uses the longerWidth or the image width, whatever is larger. Same logic applies to the wrapper height.
+ CGFloat wrapperWidth = MAX((imageRect.size.width + (style.horizontalPadding * 2.0)), (longerX + longerWidth + style.horizontalPadding));
+ CGFloat wrapperHeight = MAX((messageRect.origin.y + messageRect.size.height + style.verticalPadding), (imageRect.size.height + (style.verticalPadding * 2.0)));
+
+ wrapperView.frame = CGRectMake(0.0, 0.0, wrapperWidth, wrapperHeight);
+
+ if(titleLabel != nil) {
+ titleLabel.frame = titleRect;
+ [wrapperView addSubview:titleLabel];
+ }
+
+ if(messageLabel != nil) {
+ messageLabel.frame = messageRect;
+ [wrapperView addSubview:messageLabel];
+ }
+
+ if(imageView != nil) {
+ [wrapperView addSubview:imageView];
+ }
+
+ return wrapperView;
+}
+
+#pragma mark - Storage
+
+- (NSMutableArray *)cs_activeToasts {
+ NSMutableArray *cs_activeToasts = objc_getAssociatedObject(self, &CSToastActiveKey);
+ if (cs_activeToasts == nil) {
+ cs_activeToasts = [[NSMutableArray alloc] init];
+ objc_setAssociatedObject(self, &CSToastActiveKey, cs_activeToasts, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+ }
+ return cs_activeToasts;
+}
+
+- (NSMutableArray *)cs_toastQueue {
+ NSMutableArray *cs_toastQueue = objc_getAssociatedObject(self, &CSToastQueueKey);
+ if (cs_toastQueue == nil) {
+ cs_toastQueue = [[NSMutableArray alloc] init];
+ objc_setAssociatedObject(self, &CSToastQueueKey, cs_toastQueue, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+ }
+ return cs_toastQueue;
+}
+
+#pragma mark - Events
+
+- (void)cs_toastTimerDidFinish:(NSTimer *)timer {
+ [self cs_hideToast:(UIView *)timer.userInfo];
+}
+
+- (void)cs_handleToastTapped:(UITapGestureRecognizer *)recognizer {
+ UIView *toast = recognizer.view;
+ NSTimer *timer = (NSTimer *)objc_getAssociatedObject(toast, &CSToastTimerKey);
+ [timer invalidate];
+
+ [self cs_hideToast:toast fromTap:YES];
+}
+
+#pragma mark - Activity Methods
+
+- (void)makeToastActivity:(id)position {
+ // sanity
+ UIView *existingActivityView = (UIView *)objc_getAssociatedObject(self, &CSToastActivityViewKey);
+ if (existingActivityView != nil) return;
+
+ CSToastStyle *style = [CSToastManager sharedStyle];
+
+ UIView *activityView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, style.activitySize.width, style.activitySize.height)];
+ activityView.center = [self cs_centerPointForPosition:position withToast:activityView];
+ activityView.backgroundColor = style.backgroundColor;
+ activityView.alpha = 0.0;
+ activityView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
+ activityView.layer.cornerRadius = style.cornerRadius;
+
+ if (style.displayShadow) {
+ activityView.layer.shadowColor = style.shadowColor.CGColor;
+ activityView.layer.shadowOpacity = style.shadowOpacity;
+ activityView.layer.shadowRadius = style.shadowRadius;
+ activityView.layer.shadowOffset = style.shadowOffset;
+ }
+
+ UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
+ activityIndicatorView.center = CGPointMake(activityView.bounds.size.width / 2, activityView.bounds.size.height / 2);
+ [activityView addSubview:activityIndicatorView];
+ [activityIndicatorView startAnimating];
+
+ // associate the activity view with self
+ objc_setAssociatedObject (self, &CSToastActivityViewKey, activityView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+
+ [self addSubview:activityView];
+
+ [UIView animateWithDuration:style.fadeDuration
+ delay:0.0
+ options:UIViewAnimationOptionCurveEaseOut
+ animations:^{
+ activityView.alpha = 1.0;
+ } completion:nil];
+}
+
+- (void)hideToastActivity {
+ UIView *existingActivityView = (UIView *)objc_getAssociatedObject(self, &CSToastActivityViewKey);
+ if (existingActivityView != nil) {
+ [UIView animateWithDuration:[[CSToastManager sharedStyle] fadeDuration]
+ delay:0.0
+ options:(UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionBeginFromCurrentState)
+ animations:^{
+ existingActivityView.alpha = 0.0;
+ } completion:^(BOOL finished) {
+ [existingActivityView removeFromSuperview];
+ objc_setAssociatedObject (self, &CSToastActivityViewKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+ }];
+ }
+}
+
+#pragma mark - Helpers
+
+- (CGPoint)cs_centerPointForPosition:(id)point withToast:(UIView *)toast {
+ CSToastStyle *style = [CSToastManager sharedStyle];
+
+ UIEdgeInsets safeInsets = UIEdgeInsetsZero;
+ if (@available(iOS 11.0, *)) {
+ safeInsets = self.safeAreaInsets;
+ }
+
+ CGFloat topPadding = style.verticalPadding + safeInsets.top;
+ CGFloat bottomPadding = style.verticalPadding + safeInsets.bottom;
+
+ if([point isKindOfClass:[NSString class]]) {
+ if([point caseInsensitiveCompare:CSToastPositionTop] == NSOrderedSame) {
+ return CGPointMake(self.bounds.size.width / 2.0, (toast.frame.size.height / 2.0) + topPadding);
+ } else if([point caseInsensitiveCompare:CSToastPositionCenter] == NSOrderedSame) {
+ return CGPointMake(self.bounds.size.width / 2.0, self.bounds.size.height / 2.0);
+ }
+ } else if ([point isKindOfClass:[NSValue class]]) {
+ return [point CGPointValue];
+ }
+
+ // default to bottom
+ return CGPointMake(self.bounds.size.width / 2.0, (self.bounds.size.height - (toast.frame.size.height / 2.0)) - bottomPadding);
+}
+
+@end
+
+@implementation CSToastStyle
+
+#pragma mark - Constructors
+
+- (instancetype)initWithDefaultStyle {
+ self = [super init];
+ if (self) {
+ self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.8];
+ self.titleColor = [UIColor whiteColor];
+ self.messageColor = [UIColor whiteColor];
+ self.maxWidthPercentage = 0.8;
+ self.maxHeightPercentage = 0.8;
+ self.horizontalPadding = 10.0;
+ self.verticalPadding = 10.0;
+ self.cornerRadius = 10.0;
+ self.titleFont = [UIFont boldSystemFontOfSize:16.0];
+ self.messageFont = [UIFont systemFontOfSize:16.0];
+ self.titleAlignment = NSTextAlignmentLeft;
+ self.messageAlignment = NSTextAlignmentLeft;
+ self.titleNumberOfLines = 0;
+ self.messageNumberOfLines = 0;
+ self.displayShadow = NO;
+ self.shadowOpacity = 0.8;
+ self.shadowRadius = 6.0;
+ self.shadowOffset = CGSizeMake(4.0, 4.0);
+ self.imageSize = CGSizeMake(80.0, 80.0);
+ self.activitySize = CGSizeMake(100.0, 100.0);
+ self.fadeDuration = 0.2;
+ }
+ return self;
+}
+
+- (void)setMaxWidthPercentage:(CGFloat)maxWidthPercentage {
+ _maxWidthPercentage = MAX(MIN(maxWidthPercentage, 1.0), 0.0);
+}
+
+- (void)setMaxHeightPercentage:(CGFloat)maxHeightPercentage {
+ _maxHeightPercentage = MAX(MIN(maxHeightPercentage, 1.0), 0.0);
+}
+
+- (instancetype)init NS_UNAVAILABLE {
+ return nil;
+}
+
+@end
+
+@interface CSToastManager ()
+
+@property (strong, nonatomic) CSToastStyle *sharedStyle;
+@property (assign, nonatomic, getter=isTapToDismissEnabled) BOOL tapToDismissEnabled;
+@property (assign, nonatomic, getter=isQueueEnabled) BOOL queueEnabled;
+@property (assign, nonatomic) NSTimeInterval defaultDuration;
+@property (strong, nonatomic) id defaultPosition;
+
+@end
+
+@implementation CSToastManager
+
+#pragma mark - Constructors
+
++ (instancetype)sharedManager {
+ static CSToastManager *_sharedManager = nil;
+ static dispatch_once_t oncePredicate;
+ dispatch_once(&oncePredicate, ^{
+ _sharedManager = [[self alloc] init];
+ });
+
+ return _sharedManager;
+}
+
+- (instancetype)init {
+ self = [super init];
+ if (self) {
+ self.sharedStyle = [[CSToastStyle alloc] initWithDefaultStyle];
+ self.tapToDismissEnabled = YES;
+ self.queueEnabled = NO;
+ self.defaultDuration = 3.0;
+ self.defaultPosition = CSToastPositionBottom;
+ }
+ return self;
+}
+
+#pragma mark - Singleton Methods
+
++ (void)setSharedStyle:(CSToastStyle *)sharedStyle {
+ [[self sharedManager] setSharedStyle:sharedStyle];
+}
+
++ (CSToastStyle *)sharedStyle {
+ return [[self sharedManager] sharedStyle];
+}
+
++ (void)setTapToDismissEnabled:(BOOL)tapToDismissEnabled {
+ [[self sharedManager] setTapToDismissEnabled:tapToDismissEnabled];
+}
+
++ (BOOL)isTapToDismissEnabled {
+ return [[self sharedManager] isTapToDismissEnabled];
+}
+
++ (void)setQueueEnabled:(BOOL)queueEnabled {
+ [[self sharedManager] setQueueEnabled:queueEnabled];
+}
+
++ (BOOL)isQueueEnabled {
+ return [[self sharedManager] isQueueEnabled];
+}
+
++ (void)setDefaultDuration:(NSTimeInterval)duration {
+ [[self sharedManager] setDefaultDuration:duration];
+}
+
++ (NSTimeInterval)defaultDuration {
+ return [[self sharedManager] defaultDuration];
+}
+
++ (void)setDefaultPosition:(id)position {
+ if ([position isKindOfClass:[NSString class]] || [position isKindOfClass:[NSValue class]]) {
+ [[self sharedManager] setDefaultPosition:position];
+ }
+}
+
++ (id)defaultPosition {
+ return [[self sharedManager] defaultPosition];
+}
+
+@end
diff --git a/src/ios/UserUpdateListener.h b/src/ios/UserUpdateListener.h
new file mode 100644
index 0000000..29e08cb
--- /dev/null
+++ b/src/ios/UserUpdateListener.h
@@ -0,0 +1,18 @@
+//
+// UserUpdateListener.h
+// shuto-cne
+//
+// Created by 范大德 on 2022/3/30.
+//
+
+#ifndef UserUpdateListener_h
+#define UserUpdateListener_h
+
+
+#endif /* UserUpdateListener_h */
+
+#import "Listener.h"
+
+@interface UserUpdateListener:Listener
+{}
+@end
diff --git a/src/ios/UserUpdateListener.m b/src/ios/UserUpdateListener.m
new file mode 100644
index 0000000..ca1afd7
--- /dev/null
+++ b/src/ios/UserUpdateListener.m
@@ -0,0 +1,24 @@
+//
+// Listener.m
+// shuto-cne
+//
+// Created by 范大德 on 2022/3/29.
+//
+
+#import "UserUpdateListener.h"
+#import "VideoCallingViewController.h"
+@interface UserUpdateListener()
+{}
+@end
+@implementation UserUpdateListener
+
+- (instancetype)init {
+ return self;
+}
+
+
+-(void)on: (NSDictionary*)extra{
+ [[VideoCallingViewController viewController]updateUser:extra];
+}
+
+@end
diff --git a/src/ios/VideoCallingViewController.h b/src/ios/VideoCallingViewController.h
new file mode 100755
index 0000000..be85877
--- /dev/null
+++ b/src/ios/VideoCallingViewController.h
@@ -0,0 +1,23 @@
+//
+// VideoCallingViewController.h
+// TRTC-API-Example-OC
+//
+// Created by bluedang on 2021/4/12.
+//
+
+#import
+
+#import
+
+NS_ASSUME_NONNULL_BEGIN
+
+//MARK: 视频通话示例 - 通话界面
+@interface VideoCallingViewController : UIViewController
+- (instancetype)initWithRoomId:(UInt32)roomId userId:(NSString *)userId appId:(UInt32 *)appId userSig:(NSString *) userSig;
+- (NSMutableOrderedSet *)remoteUidSet;
++(VideoCallingViewController*)viewController;
+- (void)refreshRemoteVideoViews;
+- (void) updateUser:(NSDictionary*)extra;
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/src/ios/VideoCallingViewController.m b/src/ios/VideoCallingViewController.m
new file mode 100755
index 0000000..d4541af
--- /dev/null
+++ b/src/ios/VideoCallingViewController.m
@@ -0,0 +1,402 @@
+//
+// VideoCallingViewController.m
+// TRTC-API-Example-OC
+//
+// Created by bluedang on 2021/4/12.
+//
+
+/*
+实时视频通话功能
+ TRTC APP 实时视频通话功能
+ 本文件展示如何集成实时视频通话功能
+ 1、切换摄像头 API:[[_trtcCloud getDeviceManager] switchCamera:_isFrontCamera];
+ 2、打开关闭摄像头 API: [self.trtcCloud startLocalPreview:_isFrontCamera view:_localVideoView];
+ [self.trtcCloud stopLocalPreview];
+ 3、切换听筒与扬声器 API:[[_trtcCloud getDeviceManager] setAudioRoute:TXAudioRouteEarpiece];
+ [[_trtcCloud getDeviceManager] setAudioRoute:TXAudioRouteSpeakerphone];
+ 4、静音当前设备,其他人将无法听到该设备的声音 API: [_trtcCloud muteLocalAudio:YES];
+ 参考文档:https://cloud.tencent.com/document/product/647/42044
+ */
+
+/*
+Real-Time Audio Call
+ TRTC Audio Call
+ This document shows how to integrate the real-time audio call feature.
+ 1. Switch between the speaker and receiver: [[_trtcCloud getDeviceManager] setAudioRoute:TXAudioRouteSpeakerphone]
+ 2. Mute the device so that others won’t hear the audio of the device: [_trtcCloud muteLocalAudio:YES]
+ 3. Display other network and volume information: delegate -> onNetworkQuality, onUserVoiceVolume
+ Documentation: https://cloud.tencent.com/document/product/647/42046
+*/
+
+#import "VideoCallingViewController.h"
+
+#import "TrtcUserInfo.h"
+#import "CordovaEventKit.h"
+#import "UIView+Toast.h"
+#import "Events.h"
+#import "UserUpdateListener.h"
+
+
+static const NSInteger maxRemoteUserNum = 7;
+
+@interface VideoCallingViewController ()
+
+@property (weak, nonatomic) IBOutlet UIButton *backButton;
+@property (weak, nonatomic) IBOutlet UIButton *subVisibleButton;
+@property (weak, nonatomic) IBOutlet UIButton *viewRotateButton;
+@property (strong, nonatomic) IBOutletCollection(UIView) NSArray *remoteViewArr;
+@property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *subViewBtnArr;
+@property (strong, nonatomic) IBOutletCollection(UILabel) NSArray *displayLabelArr;
+@property (weak, nonatomic) IBOutlet UILabel *displayLabel;
+
+@property (assign, nonatomic) UInt32 roomId;
+@property (strong, nonatomic) NSString* userId;
+@property(nonatomic, assign) UInt32 sdkAppId;
+@property (strong, nonatomic) NSString* userSig;
+@property (strong, nonatomic) TRTCCloud *trtcCloud;
+@property (strong, nonatomic) NSMutableOrderedSet *remoteUidSet;
+@property (strong, nonatomic) NSMutableArray *viewUsers;
+
+@property (assign, nonatomic) BOOL isFrontCamera;
+@property (assign, nonatomic) BOOL *hasShareUser;
+@property (assign, nonatomic) BOOL *hiddenAllSubView;
+
+@property (assign, nonatomic) NSInteger rotation;
+@end
+
+@implementation VideoCallingViewController
+
+ static VideoCallingViewController* _self;
+
++(VideoCallingViewController*)viewController{
+ return _self;
+}
+- (TRTCCloud*)trtcCloud {
+ if (!_trtcCloud) {
+ _trtcCloud = [TRTCCloud sharedInstance];
+ }
+ return _trtcCloud;
+}
+
+- (NSMutableOrderedSet *)remoteUidSet {
+ if (!_remoteUidSet) {
+ _remoteUidSet = [[NSMutableOrderedSet alloc] initWithCapacity:maxRemoteUserNum];
+ }
+ return _remoteUidSet;
+}
+
+- (NSMutableArray *)viewUsers {
+ if (!_viewUsers) {
+ _viewUsers = [[NSMutableArray alloc] initWithCapacity:maxRemoteUserNum];
+ }
+ return _viewUsers;
+}
+
+- (instancetype)initWithRoomId:(UInt32)roomId userId:(NSString *)userId appId:(UInt32)appId userSig:(NSString *)userSig{
+ NSLog(@"TRTC - initWithRoomId:::::");
+ self = [super initWithNibName:NSStringFromClass([self class]) bundle:nil];
+ if (self) {
+ _roomId = roomId;
+ _userId = userId;
+ _sdkAppId = appId;
+ _userSig = userSig;
+ }
+ NSLog(@"TRTC - roomid:%d,userID:%@,sdkAppid:%d,userSig:%@",_roomId,_userId,_sdkAppId,_userSig);
+ _self = self;
+ return self;
+}
+
+- (void) updateUser:(NSDictionary*)extra{
+ NSLog(@"TRTC - userinfo.update -- userID:%@,displayname:%@",extra[@"userId"],extra[@"displayName"]);
+ TrtcUserInfo *user = [[TrtcUserInfo alloc]initWithPersonid:extra[@"userId"]];
+ NSInteger index = [[self remoteUidSet] indexOfObject: user];
+ NSLog(@"TRTC - userinfo.update -- userId:%@,index:%ld",extra[@"userId"],index);
+ if (index == NSNotFound) { return; }
+ TrtcUserInfo *obj = [self remoteUidSet][index];
+ [obj setDisplayName: extra[@"displayName"]];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self refreshRemoteVideoViews];
+ });
+}
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ self.isFrontCamera = NO;
+ self.trtcCloud.delegate = self;
+
+ [self setupDefaultUIConfig];
+ [self setupTRTCCloud];
+
+ [self.view sendSubviewToBack:self.view];
+}
+
+- (void)setupDefaultUIConfig {
+ NSLog(@"TRTC - setupDefaultUIConfig:::::");
+ _displayLabel.text = @"我";
+ _displayLabel.hidden = NO;
+ _rotation = 0;
+ [Events addListener:@"userinfo.update" listener: [[UserUpdateListener alloc] init] ];
+}
+
+
+- (void)setupTRTCCloud {
+ [[self remoteUidSet] removeAllObjects];
+
+ [self.trtcCloud startLocalPreview:_isFrontCamera view:self.view];
+ TRTCParams *params = [TRTCParams new];
+ params.sdkAppId = _sdkAppId;
+ params.roomId = _roomId;
+ params.userId = _userId;
+ params.role = TRTCRoleAnchor;
+ params.userSig = _userSig;
+
+ [self.trtcCloud enterRoom:params appScene:TRTCAppSceneVideoCall];
+
+ TRTCVideoEncParam *encParams = [TRTCVideoEncParam new];
+ encParams.videoResolution = TRTCVideoResolution_640_360;
+ encParams.videoBitrate = 550;
+ encParams.videoFps = 15;
+
+ [self.trtcCloud setVideoEncoderParam:encParams];
+ [self.trtcCloud startLocalAudio:TRTCAudioQualityMusic];
+
+}
+
+- (void)dealloc {
+ [self.trtcCloud exitRoom];
+ [TRTCCloud destroySharedIntance];
+}
+
+- (void)changeUser:(NSInteger) a and:(NSInteger) b{
+ if(a == b || a < 0 || b < 0){return;}
+ NSInteger x = a > b ? b : a;
+ NSInteger y = a > b ? a : b;
+ if([self remoteUidSet].count > y && x>-1){
+ // 交换
+ NSLog(@"TRTC - onSubViewClcik:::::Before change:%@,%@",[[self remoteUidSet][x] personid],[[self remoteUidSet][y] personid]);
+ TrtcUserInfo* info = [self remoteUidSet][x];
+ TrtcUserInfo* info2 = [self remoteUidSet][y];
+ [_remoteUidSet removeObjectAtIndex:x];
+ [_remoteUidSet setObject:info atIndex: y-1];
+ [_remoteUidSet insertObject:info2 atIndex:x];
+ NSLog(@"TRTC - onSubViewClcik:::::after change:%@,%@",[[self remoteUidSet][x] personid],[[self remoteUidSet][y] personid]);
+ [self refreshRemoteVideoViews];
+ NSDictionary *event = [[NSDictionary alloc]initWithObjectsAndKeys:
+ [[NSString alloc] initWithFormat:@"%d",_roomId],@"room",info2.personid,@"userId", nil];
+ [CordovaEventKit fireEvent:@"onLayoutChangeMessage" obj:event];
+ }
+}
+
+#pragma mark - IBActions
+
+- (IBAction)onSubVisibleChange:(UIButton*)sender {
+ NSLog(@"TRTC - onSubVisibleChange:::::,before:%@",[NSNumber numberWithBool:sender.selected]);
+ sender.selected = !sender.selected;
+ NSLog(@"TRTC - onSubVisibleChange:::::,after:%@",[NSNumber numberWithBool:sender.selected]);
+ [self refreshRemoteVideoViews];
+}
+
+- (IBAction)onVideoRotate:(UIButton*)sender {
+ NSLog(@"TRTC - onRouteChange:::::,%@,local index: %ld",[[self remoteUidSet][0] personid],[_viewUsers indexOfObject:_userId]);
+ TRTCRenderParams *params = [[TRTCRenderParams alloc] init];
+
+ params.fillMode = TRTCVideoFillMode_Fit;
+ _rotation += 1;
+ _rotation = _rotation > 3 ? 0 : _rotation;
+ params.rotation = _rotation;
+// [_trtcCloud stopRemoteView:[[self viewUsers][0] personid] streamType:TRTCVideoStreamTypeBig];
+ [_trtcCloud setRemoteRenderParams:[[self remoteUidSet][0] personid] streamType:TRTCVideoStreamTypeBig params:params];
+// [_trtcCloud updateRemoteView:self.view streamType:TRTCVideoStreamTypeBig forUser:[[self remoteUidSet][0] personid]];
+// [_trtcCloud startRemoteView:[[self viewUsers][0] personid] streamType: TRTCVideoStreamTypeBig view:self.view];
+
+}
+
+- (IBAction)onBackClick:(UIButton*)sender {
+ NSLog(@"TRTC - onBackClick:::::");
+ [self.trtcCloud exitRoom];
+ [TRTCCloud destroySharedIntance];
+ [self dismissViewControllerAnimated:YES completion:nil];
+}
+
+- (IBAction)onSwitchCameraClick:(UIButton*)sender {
+ NSLog(@"TRTC - onSwitchCameraClick:::::");
+ _isFrontCamera = !_isFrontCamera;
+ [[_trtcCloud getDeviceManager] switchCamera:_isFrontCamera];
+}
+
+
+- (IBAction)onMicCaptureClick:(UIButton*)sender {
+ NSLog(@"TRTC - onMicCaptureClick:::::");
+ sender.selected = !sender.selected;
+ if ([sender isSelected]) {
+ [_trtcCloud muteLocalAudio:YES];
+ } else {
+ [_trtcCloud muteLocalAudio:NO];
+ }
+}
+
+- (IBAction)onSwitchSpeakerClick:(UIButton*)sender {
+ NSLog(@"TRTC - onSwitchSpeakerClick:::::");
+ sender.selected = !sender.selected;
+ if ([sender isSelected]) {
+ [[_trtcCloud getDeviceManager] setAudioRoute:TXAudioRouteEarpiece];
+ } else {
+ [[_trtcCloud getDeviceManager] setAudioRoute:TXAudioRouteSpeakerphone];
+ }
+}
+
+- (IBAction)onSubViewClcik:(UIButton*)sender {
+ NSLog(@"TRTC - onSubViewClcik:::::button");
+ NSInteger index = [_subViewBtnArr indexOfObject:sender];
+ if (index == NSNotFound) {return;}
+ index = index + 1;
+ [self changeUser:0 and:index];
+}
+
+
+#pragma mark - TRTCCloud Delegate
+
+- (void)onEnterRoom:(NSInteger) result{
+ NSLog(@"TRTC - onEnterRoom, %ld",result);
+ [_trtcCloud startLocalPreview:_isFrontCamera view:self.view];
+ // 添加本地用户到用户列表
+ TrtcUserInfo *info = [[TrtcUserInfo alloc] initWithPersonid:_userId];
+ [info setLocal:YES];
+ NSInteger index = [[self remoteUidSet] indexOfObject:info];
+ if (index != NSNotFound) {
+ return;
+ } else {
+ [[self remoteUidSet] addObject:info];
+ }
+
+ NSDictionary *event = [[NSDictionary alloc]initWithObjectsAndKeys:
+ [[NSString alloc] initWithFormat:@"%d",_roomId],@"room",_userId,@"userId", nil];
+
+ [CordovaEventKit fireEvent:@"onLayoutChangeMessage" obj:event];
+}
+
+- (void)onUserVideoAvailable:(NSString *)userId available:(BOOL)available {
+ NSLog(@"TRTC - onUserVideoAvailable, user:%@,available%@",userId, available ? @"YES":@"NO");
+ // 添加远端用户到用户列表
+ TrtcUserInfo *info = [[TrtcUserInfo alloc] initWithPersonid:userId];
+ NSInteger index = [[self remoteUidSet] indexOfObject:info];
+ if (available) {
+ if (index != NSNotFound) { return; }
+ if([info isShareUser]){
+ _hasShareUser = YES;
+ }
+ [[self remoteUidSet] addObject:info];
+ } else {
+ if (index == NSNotFound) { return; }
+ if([info isShareUser]){
+ _hasShareUser = NO;
+ _hiddenAllSubView = NO;
+ }
+ [_trtcCloud stopRemoteView:userId streamType:TRTCVideoStreamTypeSmall];
+ [[self remoteUidSet] removeObject:userId];
+ }
+ [self refreshRemoteVideoViews];
+ if(_hasShareUser){
+ // 切换分享屏幕到主窗口
+ [self changeUser:0 and:[[self remoteUidSet] indexOfObject:info]];
+ // 隐藏所有子窗口
+ _hiddenAllSubView = YES;
+ [self refreshRemoteVideoViews];
+// [_trtcCloud stopLocalPreview];
+ }
+ NSDictionary *event = @{@"room": [[NSString alloc] initWithFormat:@"%d", _roomId], @"userId": userId, @"available": [NSNumber numberWithBool:available]};
+ [CordovaEventKit fireEvent:@"onUserVideoAvailable" obj:event];
+}
+
+- (void)refreshRemoteVideoViews {
+ NSLog(@"TRTC - refreshRemoteVideoViews:%ld",_remoteViewArr.count);
+
+ _subVisibleButton.hidden = _hasShareUser != nil;
+ _viewRotateButton.hidden = _hasShareUser == nil;
+ _viewRotateButton.enabled = !_viewRotateButton.hidden;
+ for (int i = 0; i <= _remoteViewArr.count; i++) {
+ TrtcUserInfo* nUser = [self remoteUidSet].count > i ? [self remoteUidSet][i] : nil;
+ TrtcUserInfo* oUser = [self viewUsers].count > i ? [self viewUsers][i] : nil;
+ UIView* view = i == 0 ? self.view : _remoteViewArr[i-1];
+ UILabel* label = i ==0 ? _displayLabel : _displayLabelArr[i-1];
+ UIButton* btn = i ==0 ? nil : _subViewBtnArr[i-1];
+ NSLog(@"TRTC - refreshRemoteVideoViews - new : %@, o: %@",nUser == nil ? nil : [nUser personid],oUser == nil ? nil : [oUser personid]);
+ if((_hiddenAllSubView || ![_subVisibleButton isSelected]) && i!=0){
+ [view setHidden:YES];
+ [label setHidden:YES];
+ }else{
+ if(nUser != nil){
+ if([nUser isEqual:oUser] && ![view isHidden]){
+ if([nUser isLocalUser]){
+ [label setText:@"我"];
+ } else if([nUser displayName] == nil || [nUser displayName].length == 0) {
+ [label setText:[NSString stringWithFormat:@"%@%@",[nUser personid], [nUser isShareUser] ? @"的屏幕分享" : @""]];
+ } else {
+ [label setText:[NSString stringWithFormat:@"%@%@",[nUser displayName], [nUser isShareUser] ? @"的屏幕分享" : @""]];
+ }
+ [label sizeToFit];
+ continue;
+ }
+ TRTCRenderParams *params = [[TRTCRenderParams alloc] init];
+ params.rotation = 0;
+ params.fillMode = [nUser isShareUser] ? TRTCVideoFillMode_Fit : TRTCVideoFillMode_Fill;
+ if([nUser isLocalUser]){
+ [_trtcCloud startLocalPreview:_isFrontCamera view:view];
+ [_trtcCloud setLocalRenderParams:params];
+ [label setText:@"我"];
+ [label sizeToFit];
+ } else {
+ [_trtcCloud setRemoteRenderParams:[nUser personid] streamType:i == 0 ? TRTCVideoStreamTypeBig : TRTCVideoStreamTypeSmall params:params];
+ [_trtcCloud startRemoteView:[nUser personid] streamType:i == 0 ? TRTCVideoStreamTypeBig : TRTCVideoStreamTypeSmall view:view];
+
+ if([nUser displayName] == nil || [nUser displayName].length == 0) {
+ [label setText:[NSString stringWithFormat:@"%@%@",[nUser personid], [nUser isShareUser] ? @"的屏幕分享" : @""]];
+ } else {
+ [label setText:[NSString stringWithFormat:@"%@%@",[nUser displayName], [nUser isShareUser] ? @"的屏幕分享" : @""]];
+ }
+ [label sizeToFit];
+ }
+ [label setHidden:NO];
+ [view setHidden:NO];
+ if(btn != nil){
+ [btn setHidden:NO];
+ }
+ } else {
+ [view setHidden:YES];
+ [label setHidden:YES];
+ if(btn != nil){
+ [btn setHidden:YES];
+ }
+ }
+ }
+ if(nUser != nil){
+ [self viewUsers].count > i ? [self viewUsers][i] = nUser : [[self viewUsers] addObject:nUser];
+ }else {
+ while([self viewUsers].count > i){
+ [[self viewUsers] removeObjectAtIndex:i];
+ }
+ }
+ }
+}
+
+- (void) onError:(TXLiteAVError)errCode errMsg:(NSString *)errMsg extInfo:(NSDictionary *)extInfo{
+ NSLog(@"TRTC - onError::sdk callback onError code: %d,msg: %@,extInfo: %@",errCode,errMsg,extInfo);
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self.view makeToast: [[NSString alloc] initWithFormat:@"%@[%d]",errMsg,errCode]];
+ });
+// [self.trtcCloud exitRoom];
+// [TRTCCloud destroySharedIntance];
+// [self dismissViewControllerAnimated:YES completion:nil];
+}
+
+- (void) onExitRoom:(NSInteger)reason{
+ if (reason == 2) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self.view makeToast: @"远程协助已结束"];
+ });
+ }
+ [self dismissViewControllerAnimated:YES completion:nil];
+}
+
+@end
diff --git a/src/ios/VideoCallingViewController.xib b/src/ios/VideoCallingViewController.xib
new file mode 100755
index 0000000..60fbb93
--- /dev/null
+++ b/src/ios/VideoCallingViewController.xib
@@ -0,0 +1,342 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ios/libs/.gitkeep b/src/ios/libs/.gitkeep
deleted file mode 100644
index f2b04b1..0000000
--- a/src/ios/libs/.gitkeep
+++ /dev/null
@@ -1,4 +0,0 @@
-# AVSDK
-# BeautySDK
-# ILiveSDK
-# IMSDK
diff --git a/src/ios/res/beauty-dis.png b/src/ios/res/beauty-dis.png
deleted file mode 100644
index 3f709c7..0000000
Binary files a/src/ios/res/beauty-dis.png and /dev/null differ
diff --git a/src/ios/res/beauty.png b/src/ios/res/beauty.png
deleted file mode 100644
index b38bff1..0000000
Binary files a/src/ios/res/beauty.png and /dev/null differ
diff --git a/src/ios/res/bg.png b/src/ios/res/bg.png
deleted file mode 100644
index 26fc385..0000000
Binary files a/src/ios/res/bg.png and /dev/null differ
diff --git a/src/ios/res/camera-gray.png b/src/ios/res/camera-gray.png
deleted file mode 100644
index 5a0086b..0000000
Binary files a/src/ios/res/camera-gray.png and /dev/null differ
diff --git a/src/ios/res/camera.png b/src/ios/res/camera.png
deleted file mode 100644
index 424a2ee..0000000
Binary files a/src/ios/res/camera.png and /dev/null differ
diff --git a/src/ios/res/chat.png b/src/ios/res/chat.png
deleted file mode 100644
index 426ce06..0000000
Binary files a/src/ios/res/chat.png and /dev/null differ
diff --git a/src/ios/res/doubleroom.png b/src/ios/res/doubleroom.png
deleted file mode 100644
index 3ab3329..0000000
Binary files a/src/ios/res/doubleroom.png and /dev/null differ
diff --git a/src/ios/res/feedback.png b/src/ios/res/feedback.png
deleted file mode 100644
index 8c52b22..0000000
Binary files a/src/ios/res/feedback.png and /dev/null differ
diff --git a/src/ios/res/ic_toast_success@2x.png b/src/ios/res/ic_toast_success@2x.png
deleted file mode 100644
index e46d177..0000000
Binary files a/src/ios/res/ic_toast_success@2x.png and /dev/null differ
diff --git a/src/ios/res/icon_sign@2x.png b/src/ios/res/icon_sign@2x.png
deleted file mode 100644
index 0f8f7ef..0000000
Binary files a/src/ios/res/icon_sign@2x.png and /dev/null differ
diff --git a/src/ios/res/log.png b/src/ios/res/log.png
deleted file mode 100644
index 9435fa3..0000000
Binary files a/src/ios/res/log.png and /dev/null differ
diff --git a/src/ios/res/log2.png b/src/ios/res/log2.png
deleted file mode 100644
index 012a5c7..0000000
Binary files a/src/ios/res/log2.png and /dev/null differ
diff --git a/src/ios/res/mic-dis.png b/src/ios/res/mic-dis.png
deleted file mode 100644
index d948549..0000000
Binary files a/src/ios/res/mic-dis.png and /dev/null differ
diff --git a/src/ios/res/mic.png b/src/ios/res/mic.png
deleted file mode 100644
index 7390460..0000000
Binary files a/src/ios/res/mic.png and /dev/null differ
diff --git a/src/ios/res/muti_room_bg.png b/src/ios/res/muti_room_bg.png
deleted file mode 100644
index 90b77b9..0000000
Binary files a/src/ios/res/muti_room_bg.png and /dev/null differ
diff --git a/src/ios/res/role.png b/src/ios/res/role.png
deleted file mode 100644
index f25c11b..0000000
Binary files a/src/ios/res/role.png and /dev/null differ
diff --git a/src/ios/res/ui_title_arrow_left.png b/src/ios/res/ui_title_arrow_left.png
deleted file mode 100644
index 065336e..0000000
Binary files a/src/ios/res/ui_title_arrow_left.png and /dev/null differ