JXScanQRViewController.m 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945
  1. //
  2. // JXScanQRViewController.m
  3. // shiku_im
  4. //
  5. // Created by 1 on 17/9/15.
  6. // Copyright © 2017年 Reese. All rights reserved.
  7. //
  8. #import "JXScanQRViewController.h"
  9. #import <AVFoundation/AVFoundation.h>
  10. #import "JXUserInfoVC.h"
  11. #import "JXRoomObject.h"
  12. #import "JXRoomPool.h"
  13. #import "JXChatViewController.h"
  14. #import "webpageVC.h"
  15. #import "JXRoomRemind.h"
  16. #import "JXInputVC.h"
  17. #import "RITLPhotosViewController.h"
  18. #import "JXInputMoneyVC.h"
  19. #import "GCDAsyncSocket.h"
  20. #import "JXChatLogMoveActionVC.h"
  21. #import "JXWebLoginVC.h"
  22. #define TOP (JX_SCREEN_HEIGHT-300)/2
  23. #define LEFT (JX_SCREEN_WIDTH-300)/2
  24. #define kScanRect CGRectMake(LEFT, TOP, 300, 300)
  25. @interface JXScanQRViewController ()<AVCaptureMetadataOutputObjectsDelegate,RITLPhotosViewControllerDelegate,GCDAsyncSocketDelegate,JXWebLoginVCDelegate,JXRoomObjectDelegate>
  26. {
  27. int num;
  28. BOOL upOrdown;
  29. NSTimer * timer;
  30. CAShapeLayer *cropLayer;
  31. JXRoomObject *_chatRoom;
  32. NSDictionary * _dataDict;
  33. }
  34. //捕获设备,通常是前置摄像头,后置摄像头,麦克风(音频输入)
  35. @property(nonatomic)AVCaptureDevice *device;
  36. //AVCaptureDeviceInput 代表输入设备,他使用AVCaptureDevice 来初始化
  37. @property(nonatomic)AVCaptureDeviceInput *input;
  38. //设置输出类型为Metadata,因为这种输出类型中可以设置扫描的类型,譬如二维码
  39. //当启动摄像头开始捕获输入时,如果输入中包含二维码,就会产生输出
  40. @property(nonatomic)AVCaptureMetadataOutput *output;
  41. //session:由他把输入输出结合在一起,并开始启动捕获设备(摄像头)
  42. @property(nonatomic)AVCaptureSession *session;
  43. //图像预览层,实时显示捕获的图像
  44. @property(nonatomic)AVCaptureVideoPreviewLayer *previewLayer;
  45. @property (nonatomic, strong) UIImageView * line;
  46. // 扫描到群组参数
  47. @property (nonatomic, copy) NSString *roomJid;
  48. @property (nonatomic, copy) NSString *roomUserId;
  49. @property (nonatomic, copy) NSString *roomUserName;
  50. @property(nonatomic,strong)GCDAsyncSocket *tcpScoket;
  51. @property (nonatomic, strong) NSMutableArray *connectHostMuArr;
  52. @property (nonatomic, strong) NSData *lastData;
  53. @property (nonatomic, assign) BOOL isMyLog; //是否是自己的聊天记录
  54. @property (nonatomic, copy) NSString *logUserId; // 聊天记录的用户Id;
  55. @property (nonatomic, strong) JXChatLogMoveActionVC *moveActionVC;
  56. @property (nonatomic,copy) NSString *qrCodeKey; // web端扫描二维码登录key
  57. @property (nonatomic, assign) BOOL isQRLoginAction;
  58. @end
  59. @implementation JXScanQRViewController
  60. -(instancetype)init{
  61. if (self = [super init]) {
  62. self.heightHeader = JX_SCREEN_TOP;
  63. self.heightFooter = 0;
  64. self.isGotoBack = YES;
  65. self.title = Localized(@"JXQR_Scan");
  66. self.connectHostMuArr = [NSMutableArray array];
  67. }
  68. return self;
  69. }
  70. -(void)dealloc{
  71. [timer invalidate];
  72. timer = nil;
  73. }
  74. - (void)viewDidLoad {
  75. [super viewDidLoad];
  76. self.view.backgroundColor = [UIColor whiteColor];
  77. [self createHeadAndFoot];
  78. self.tableBody.hidden = YES;
  79. [self configView];
  80. [self setCropRect:kScanRect];
  81. [self setupCamera];
  82. [self setupPhotoAlbum];
  83. [_session startRunning];
  84. }
  85. - (void)setupPhotoAlbum {
  86. UIButton *moreBtn = [UIFactory createButtonWithImage:@""
  87. highlight:nil
  88. target:self
  89. selector:@selector(onPhotoAlbum:)];
  90. [moreBtn setTitle:Localized(@"ALBUM") forState:UIControlStateNormal];
  91. [moreBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
  92. [moreBtn.titleLabel setFont:SYSFONT(15)];
  93. moreBtn.custom_acceptEventInterval = 1.0f;
  94. moreBtn.frame = CGRectMake(JX_SCREEN_WIDTH - 32-15, JX_SCREEN_TOP - 30, 32, 15);
  95. [self.tableHeader addSubview:moreBtn];
  96. }
  97. - (void)onPhotoAlbum:(UIButton *)button {
  98. RITLPhotosViewController *photoController = RITLPhotosViewController.photosViewController;
  99. photoController.configuration.maxCount = 1;//最大的选择数目
  100. photoController.configuration.containVideo = NO;//选择类型,目前只选择图片不选择视频
  101. photoController.configuration.containImage = YES;//选择类型,目前只选择图片不选择视频
  102. photoController.configuration.isRichScan = YES;//选择类型,目前只选择图片不选择视频
  103. photoController.photo_delegate = self;
  104. photoController.thumbnailSize = CGSizeMake(320, 320);//缩略图的尺寸
  105. // photoController.defaultIdentifers = self.saveAssetIds;//记录已经选择过的资源
  106. [self presentViewController:photoController animated:true completion:^{}];
  107. }
  108. #pragma mark - 图库选择二维码后的回调
  109. - (void)photosViewController:(UIViewController *)viewController thumbnailImages:(NSArray *)thumbnailImages infos:(NSArray<NSDictionary *> *)infos {
  110. UIImage *image = [thumbnailImages firstObject];
  111. if(image){
  112. //1. 初始化扫描仪,设置设别类型和识别质量
  113. CIDetector*detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{ CIDetectorAccuracy : CIDetectorAccuracyHigh }];
  114. //2. 扫描获取的特征组
  115. NSArray *features = [detector featuresInImage:[CIImage imageWithCGImage:image.CGImage]];
  116. //3. 获取扫描结果
  117. if (features.count <= 0) {
  118. [g_App showAlert:Localized(@"JX_NoQrCode")];
  119. return;
  120. }
  121. CIQRCodeFeature *feature = [features objectAtIndex:0];
  122. NSString *stringValue = feature.messageString;
  123. NSRange range = [stringValue rangeOfString:@"shikuId"];
  124. if (range.location != NSNotFound) {
  125. NSString * idStr = [stringValue substringFromIndex:range.location + range.length + 1];
  126. if ([stringValue rangeOfString:@"=user"].location != NSNotFound) {
  127. [g_server userGetByAccountWithAccount:idStr toView:self];
  128. }else if ([stringValue rangeOfString:@"=group"].location != NSNotFound) {
  129. [g_server getRoom:idStr toView:self];
  130. }else if ([stringValue rangeOfString:@"=open"].location != NSNotFound) {
  131. if ([idStr rangeOfString:@"http://"].location != NSNotFound && [idStr rangeOfString:@"https://"].location != NSNotFound) {
  132. webpageVC * webVC = [webpageVC alloc];
  133. webVC.url= idStr;
  134. webVC.isSend = YES;
  135. webVC = [webVC init];
  136. [self actionQuit];
  137. [g_navigation.navigationView addSubview:webVC.view];
  138. // [g_navigation pushViewController:webVC animated:YES];
  139. }else{
  140. [g_App showAlert:Localized(@"JX_TheUrlNotOpen")];
  141. }
  142. }
  143. }else {
  144. NSRange idRange = [stringValue rangeOfString:@"userId"];
  145. NSRange nameRange = [stringValue rangeOfString:@"userName"];
  146. if ([stringValue hasPrefix:@"http://"] || [stringValue hasPrefix:@"https://"]) {
  147. webpageVC * webVC = [webpageVC alloc];
  148. webVC.url= stringValue;
  149. webVC.isSend = YES;
  150. webVC = [webVC init];
  151. [self actionQuit];
  152. [g_navigation.navigationView addSubview:webVC.view];
  153. // [g_navigation pushViewController:webVC animated:YES];
  154. }else if (stringValue.length == 20 && [self isNumber:stringValue]){
  155. // 对面付款, 己方收款
  156. [self getMoney:stringValue];
  157. }else if (idRange.location != NSNotFound && nameRange.location != NSNotFound) {
  158. // 己方付款, 对面收款
  159. [self PaySide:stringValue];
  160. }
  161. }
  162. }else {
  163. UIAlertView * alertView = [[UIAlertView alloc]initWithTitle:Localized(@"JX_ScanResults") message:Localized(@"JX_Haven'tQrCode") delegate:nil cancelButtonTitle:Localized(@"JX_Confirm") otherButtonTitles:nil, nil];
  164. [alertView show];
  165. }
  166. }
  167. - (void)getMoney:(NSString *)stringValue {
  168. JXInputMoneyVC *inputVC = [[JXInputMoneyVC alloc] init];
  169. inputVC.type = JXInputMoneyTypeCollection;
  170. inputVC.paymentCode = stringValue;
  171. [g_navigation pushViewController:inputVC animated:YES];
  172. [self actionQuit];
  173. }
  174. - (void)PaySide:(NSString *)stringValue {
  175. SBJsonParser * resultParser = [[SBJsonParser alloc] init] ;
  176. NSDictionary *dict = [resultParser objectWithString:stringValue];
  177. JXInputMoneyVC *inputVC = [[JXInputMoneyVC alloc] init];
  178. inputVC.type = JXInputMoneyTypePayment;
  179. inputVC.userId = [dict objectForKey:@"userId"];
  180. inputVC.userName = [dict objectForKey:@"userName"];
  181. if ([dict objectForKey:@"money"]) {
  182. inputVC.money = [dict objectForKey:@"money"];
  183. }
  184. if ([dict objectForKey:@"description"]) {
  185. inputVC.desStr = [dict objectForKey:@"description"];
  186. }
  187. [g_navigation pushViewController:inputVC animated:YES];
  188. [self actionQuit];
  189. }
  190. -(void)configView{
  191. UIImageView * imageView = [[UIImageView alloc]initWithFrame:kScanRect];
  192. [self.view addSubview:imageView];
  193. upOrdown = NO;
  194. num =0;
  195. _line = [[UIImageView alloc] initWithFrame:CGRectMake(LEFT, TOP+10, 300, 2)];
  196. _line.backgroundColor = [UIColor greenColor];
  197. [self.view addSubview:_line];
  198. timer = [NSTimer scheduledTimerWithTimeInterval:.02 target:self selector:@selector(animation1) userInfo:nil repeats:YES];
  199. }
  200. -(void)animation1
  201. {
  202. if (upOrdown == NO) {
  203. num ++;
  204. _line.frame = CGRectMake(LEFT, TOP+10+2*num, 300, 2);
  205. if (2*num == 200) {
  206. upOrdown = YES;
  207. }
  208. }
  209. else {
  210. num --;
  211. _line.frame = CGRectMake(LEFT, TOP+10+2*num, 300, 2);
  212. if (num == 0) {
  213. upOrdown = NO;
  214. }
  215. }
  216. }
  217. - (void)setCropRect:(CGRect)cropRect{
  218. cropLayer = [[CAShapeLayer alloc] init];
  219. CGMutablePathRef path = CGPathCreateMutable();
  220. CGPathAddRect(path, nil, cropRect);
  221. // CGPathAddRect(path, nil, self.view.bounds);
  222. CGRect viewRect = self.view.bounds;
  223. viewRect.origin.y += JX_SCREEN_TOP;
  224. viewRect.size.height -= JX_SCREEN_TOP;
  225. CGPathAddRect(path, nil, viewRect);
  226. [cropLayer setFillRule:kCAFillRuleEvenOdd];
  227. [cropLayer setPath:path];
  228. [cropLayer setFillColor:[UIColor blackColor].CGColor];
  229. [cropLayer setOpacity:0.6];
  230. [cropLayer setNeedsDisplay];
  231. [self.view.layer addSublayer:cropLayer];
  232. }
  233. - (void)setupCamera
  234. {
  235. AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
  236. if (device==nil) {
  237. UIAlertController *alert = [UIAlertController alertControllerWithTitle:Localized(@"JX_Tip") message:Localized(@"JX_DeviceNoCamera") preferredStyle:UIAlertControllerStyleAlert];
  238. [alert addAction:[UIAlertAction actionWithTitle:Localized(@"JX_Confirm") style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  239. }]];
  240. [self presentViewController:alert animated:YES completion:nil];
  241. return;
  242. }
  243. // Device
  244. _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
  245. // Input
  246. _input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
  247. // Output
  248. _output = [[AVCaptureMetadataOutput alloc]init];
  249. [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
  250. //设置扫描区域
  251. CGFloat top = TOP/JX_SCREEN_HEIGHT;
  252. CGFloat left = LEFT/JX_SCREEN_WIDTH;
  253. CGFloat width = 300/JX_SCREEN_WIDTH;
  254. CGFloat height = 300/JX_SCREEN_HEIGHT;
  255. ///top 与 left 互换 width 与 height 互换
  256. [_output setRectOfInterest:CGRectMake(top,left, height, width)];
  257. // Session
  258. _session = [[AVCaptureSession alloc]init];
  259. [_session setSessionPreset:AVCaptureSessionPresetHigh];
  260. if ([_session canAddInput:self.input])
  261. {
  262. [_session addInput:self.input];
  263. }
  264. if ([_session canAddOutput:self.output])
  265. {
  266. [_session addOutput:self.output];
  267. }
  268. // 条码类型 AVMetadataObjectTypeQRCode
  269. [_output setMetadataObjectTypes:[NSArray arrayWithObjects:AVMetadataObjectTypeQRCode, nil]];
  270. // Preview
  271. _previewLayer =[AVCaptureVideoPreviewLayer layerWithSession:_session];
  272. _previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
  273. _previewLayer.frame =self.view.layer.bounds;
  274. [self.view.layer insertSublayer:_previewLayer atIndex:0];
  275. // // Start
  276. // [_session startRunning];
  277. }
  278. #pragma mark AVCaptureMetadataOutputObjectsDelegate
  279. - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
  280. {
  281. NSString *stringValue;
  282. if ([metadataObjects count] >0)
  283. {
  284. //停止扫描
  285. [_session stopRunning];
  286. [timer setFireDate:[NSDate distantFuture]];
  287. AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
  288. stringValue = metadataObject.stringValue;
  289. NSLog(@"扫描结果:%@",stringValue);
  290. NSString *action = [self subString:stringValue withString:@"action"];
  291. if ([action isEqualToString:@"sendChatHistory"]) {
  292. NSString *userId = [self subString:stringValue withString:@"userId"];
  293. if (![userId isEqualToString:g_myself.userId]) {
  294. [JXMyTools showTipView:Localized(@"JX_PleaseLoginSameAccountScan")];
  295. return;
  296. }
  297. NSString *host = [self subString:stringValue withString:@"ip"];
  298. NSString *port = [self subString:stringValue withString:@"port"];
  299. self.tcpScoket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
  300. NSError *error;
  301. BOOL isConnect = [self.tcpScoket connectToHost:host onPort:[port intValue] withTimeout:-1 error:&error];
  302. [self.tcpScoket readDataWithTimeout:-1 tag:0];
  303. if (isConnect) {
  304. self.moveActionVC = [[JXChatLogMoveActionVC alloc] init];
  305. [g_navigation pushViewController:self.moveActionVC animated:YES];
  306. NSLog(@"连接成功");
  307. }else {
  308. [JXMyTools showTipView:Localized(@"JX_ConnectFailed")];
  309. NSLog(@"连接失败");
  310. }
  311. return;
  312. }
  313. if ([action isEqualToString:@"webLogin"]) {
  314. NSString *qrCodeKey = [self subString:stringValue withString:@"qrCodeKey"];
  315. self.qrCodeKey = qrCodeKey;
  316. self.isQRLoginAction = NO;
  317. [g_server userQrCodeLoginWithQRCodeKey:qrCodeKey type:@"1" toView:self];
  318. return;
  319. }
  320. NSRange range = [stringValue rangeOfString:@"shikuId"];
  321. if (range.location != NSNotFound) {
  322. NSString * idStr = [stringValue substringFromIndex:range.location + range.length + 1];
  323. if ([stringValue rangeOfString:@"=user"].location != NSNotFound) {
  324. // [g_server getUser:idStr toView:self];
  325. [g_server userGetByAccountWithAccount:idStr toView:self];
  326. }else if ([stringValue rangeOfString:@"=group"].location != NSNotFound) {
  327. [g_server getRoom:idStr toView:self];
  328. }else if ([stringValue rangeOfString:@"=open"].location != NSNotFound) {
  329. if ([idStr rangeOfString:@"http://"].location != NSNotFound && [idStr rangeOfString:@"https://"].location != NSNotFound) {
  330. webpageVC * webVC = [webpageVC alloc];
  331. webVC.url= idStr;
  332. webVC.isSend = YES;
  333. webVC = [webVC init];
  334. [self actionQuit];
  335. [g_navigation.navigationView addSubview:webVC.view];
  336. // [g_navigation pushViewController:webVC animated:YES];
  337. }else{
  338. [g_App showAlert:Localized(@"JX_TheUrlNotOpen")];
  339. }
  340. }
  341. }else {
  342. NSRange idRange = [stringValue rangeOfString:@"userId"];
  343. NSRange nameRange = [stringValue rangeOfString:@"userName"];
  344. if ([stringValue hasPrefix:@"http://"] || [stringValue hasPrefix:@"https://"]) {
  345. webpageVC * webVC = [webpageVC alloc];
  346. webVC.url= stringValue;
  347. webVC.isSend = YES;
  348. webVC = [webVC init];
  349. [self actionQuit];
  350. [g_navigation.navigationView addSubview:webVC.view];
  351. // [g_navigation pushViewController:webVC animated:YES];
  352. }else if (stringValue.length == 19 && [self isNumber:stringValue]){
  353. // 对面付款, 己方收款
  354. [self getMoney:stringValue];
  355. }else if (idRange.location != NSNotFound && nameRange.location != NSNotFound) {
  356. // 己方付款, 对面收款
  357. [self PaySide:stringValue];
  358. }
  359. }
  360. // NSDictionary * dict = [[[SBJsonParser alloc] init] objectWithString:stringValue];
  361. //
  362. // if (dict[@"shiku"] && dict[@"action"]) {
  363. // NSString * idStr = dict[@"shiku"];
  364. // NSString * actionStr = dict[@"action"];
  365. // if ([actionStr isEqualToString:@"user"]) {
  366. // [g_server getUser:idStr toView:self];
  367. // }else if ([actionStr isEqualToString:@"group"]) {
  368. // [g_server getRoom:idStr toView:self];
  369. // }else if ([actionStr isEqualToString:@"open"]){
  370. // if ([idStr rangeOfString:@"http://"].location != NSNotFound && [idStr rangeOfString:@"https://"].location != NSNotFound) {
  371. // webpageVC * webVC = [webpageVC alloc];
  372. // webVC.url= idStr;
  373. // webVC.isSend = YES;
  374. // webVC = [webVC init];
  375. // [g_window addSubview:webVC.view];
  376. // }else{
  377. // [g_App showAlert:@"URL不标准,无法打开"];
  378. // }
  379. //
  380. // }
  381. // }else{
  382. // if ([stringValue hasPrefix:@"http://"] || [stringValue hasPrefix:@"https://"]) {
  383. // webpageVC * webVC = [webpageVC alloc];
  384. // webVC.url= stringValue;
  385. // webVC.isSend = YES;
  386. // webVC = [webVC init];
  387. // [g_window addSubview:webVC.view];
  388. // [self actionQuit];
  389. //
  390. // }else {
  391. //
  392. // }
  393. // }
  394. // NSArray *arry = metadataObject.corners;
  395. // for (id temp in arry) {
  396. // NSLog(@"%@",temp);
  397. // }
  398. // UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"扫描结果" message:stringValue preferredStyle:UIAlertControllerStyleAlert];
  399. // [alert addAction:[UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  400. // if (_session != nil && timer != nil) {
  401. // [_session startRunning];
  402. // [timer setFireDate:[NSDate date]];
  403. // }
  404. //
  405. // }]];
  406. // [self presentViewController:alert animated:YES completion:nil];
  407. } else {
  408. NSLog(@"%@",Localized(@"JX_NoScanningInformation"));
  409. return;
  410. }
  411. }
  412. - (NSString *)subString:(NSString *)url withString:(NSString *)str {
  413. NSString *urlStr = [url copy];
  414. NSRange range = [urlStr rangeOfString:@"//"];
  415. if (range.location != NSNotFound) {
  416. urlStr = [urlStr substringFromIndex:range.location + range.length];
  417. }
  418. range = [urlStr rangeOfString:[NSString stringWithFormat:@"%@=",str]];
  419. if (range.location == NSNotFound) {
  420. return nil;
  421. }
  422. urlStr = [urlStr substringFromIndex:range.location + range.length];
  423. range = [urlStr rangeOfString:@","];
  424. if (range.location != NSNotFound) {
  425. urlStr = [urlStr substringToIndex:range.location];
  426. }else {
  427. range = [urlStr rangeOfString:@"&"];
  428. if (range.location != NSNotFound) {
  429. urlStr = [urlStr substringToIndex:range.location];
  430. }
  431. }
  432. return urlStr;
  433. }
  434. - (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err {
  435. if (err) {
  436. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  437. [g_notify postNotificationName:kXMPPAllMsgNotifaction object:nil userInfo:nil];
  438. [self actionQuit];
  439. [self.moveActionVC moveActionFinish];
  440. });
  441. NSLog(@"断开连接");
  442. }
  443. }
  444. //已经连接上
  445. -(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port{
  446. NSLog(@"连接上: host = %@, port = %d", host, port);
  447. [self.connectHostMuArr addObject:host];
  448. [self.tcpScoket readDataWithTimeout:-1 tag:0];
  449. }
  450. - (void)socketDidCloseReadStream:(GCDAsyncSocket *)sock {
  451. NSLog(@"断开连接");
  452. }
  453. -(void)socketDidDisconnect:(GCDAsyncSocket *)sock{
  454. NSLog(@"断开连接");
  455. // [self addMessage:[NSString stringWithFormat:@"%d断开连接:%@ ",a,sock]];
  456. }
  457. -(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
  458. if (self.lastData.length > 0) {
  459. NSMutableData *mData = [[NSMutableData alloc] init];
  460. [mData appendData:self.lastData];
  461. [mData appendData:data];
  462. data = [mData copy];
  463. }
  464. if (data.length < 4) {
  465. self.lastData = data;
  466. return;
  467. }
  468. // 取出消息长度
  469. NSData *da = [data subdataWithRange:NSMakeRange(0, 4)];
  470. int len;
  471. [da getBytes:&len length:sizeof(len)];
  472. NTOHL(len);
  473. if (len > (data.length - 4)) {
  474. self.lastData = data;
  475. return;
  476. }
  477. self.lastData = nil;
  478. // 取出消息体
  479. da = [data subdataWithRange:NSMakeRange(4, len)];
  480. NSString *jsonStr = [[NSString alloc] initWithData: da encoding:NSUTF8StringEncoding];
  481. SBJsonParser * resultParser = [[SBJsonParser alloc] init] ;
  482. NSDictionary *resultObject = [resultParser objectWithString:jsonStr];
  483. if (!resultObject && jsonStr.length > 0) {
  484. NSArray *ids = [jsonStr componentsSeparatedByString:@","];
  485. if (ids.count > 0) {
  486. self.isMyLog = [[ids firstObject] isEqualToString:g_myself.userId];
  487. self.logUserId = [ids lastObject];
  488. }
  489. }
  490. if (!self.isMyLog) {
  491. return;
  492. }
  493. JXMessageObject *msg = [[JXMessageObject alloc] init];
  494. [msg fromDictionary:resultObject];
  495. msg.timeSend = [NSDate dateWithTimeIntervalSince1970:[[resultObject objectForKey:kMESSAGE_TIMESEND] doubleValue] / 1000.0];
  496. if (msg.messageId.length > 0) {
  497. if ([msg doInsertMsg:MY_USER_ID tableName:self.logUserId]) {
  498. [msg updateLastSend:UpdateLastSendType_None];
  499. }
  500. }
  501. [self.tcpScoket readDataWithTimeout: -1 tag: 0];
  502. if (data.length - 4 > len) {
  503. [self socket:sock didReadData:[data subdataWithRange:NSMakeRange(4 + len, data.length - (4 + len))] withTag:tag];
  504. }
  505. }
  506. -(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
  507. NSLog(@"发送成功");
  508. }
  509. //- (void)creatCaptureDevice{
  510. // //使用AVMediaTypeVideo 指明self.device代表视频,默认使用后置摄像头进行初始化
  511. // self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
  512. //
  513. // //使用设备初始化输入
  514. // self.input = [[AVCaptureDeviceInput alloc]initWithDevice:self.device error:nil];
  515. //
  516. // //生成输出对象
  517. // self.output = [[AVCaptureMetadataOutput alloc]init];
  518. //
  519. // //设置代理,一旦扫描到指定类型的数据,就会通过代理输出
  520. // //在扫描的过程中,会分析扫描的内容,分析成功后就会调用代理方法在队列中输出
  521. // [self.output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
  522. //
  523. // //生成会话,用来结合输入输出
  524. // self.session = [[AVCaptureSession alloc]init];
  525. // if ([self.session canAddInput:self.input]) {
  526. // [self.session addInput:self.input];
  527. // }
  528. // if ([self.session canAddOutput:self.output]) {
  529. // [self.session addOutput:self.output];
  530. // }
  531. //
  532. // //指定当扫描到二维码的时候,产生输出
  533. // //AVMetadataObjectTypeQRCode 指定二维码
  534. // //指定识别类型一定要放到添加到session之后
  535. // [self.output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
  536. // //设置扫描信息的识别区域,左上角为(0,0),右下角为(1,1),不设的话全屏都可以识别。设置过之后可以缩小信息扫描面积加快识别速度。
  537. // //这个属性并不好设置,整了半天也没太搞明白,到底x,y,width,height,怎么是对应的,这是我一点一点试的扫描区域,看不到只能调一下,扫一扫试试
  538. //// [self.output setRectOfInterest:CGRectMake(95/JX_SCREEN_HEIGHT, 40/JX_SCREEN_WIDTH, 240/JX_SCREEN_HEIGHT, 240/JX_SCREEN_WIDTH)];
  539. // //使用self.session,初始化预览层,self.session负责驱动input进行信息的采集,layer负责把图像渲染显示
  540. // self.previewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.session];
  541. // self.previewLayer.frame = CGRectMake(0, 0, JX_SCREEN_WIDTH , JX_SCREEN_HEIGHT);
  542. // self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
  543. // [self.view.layer addSublayer:self.previewLayer];
  544. //
  545. // //开始启动
  546. // [self.session startRunning];
  547. //}
  548. //
  549. //#pragma mark 输出的代理
  550. ////metadataObjects :把识别到的内容放到该数组中
  551. //- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
  552. //{
  553. // //停止扫描
  554. // [self.session stopRunning];
  555. //// [self.timer invalidate];
  556. //// self.timer = nil;
  557. //// [self.lineView removeFromSuperview];
  558. // if ([metadataObjects count] >= 1) {
  559. // //数组中包含的都是AVMetadataMachineReadableCodeObject 类型的对象,该对象中包含解码后的数据
  560. // AVMetadataMachineReadableCodeObject *qrObject = [metadataObjects lastObject];
  561. // //拿到扫描内容在这里进行个性化处理
  562. // [g_App showAlert:qrObject.stringValue];
  563. // NSLog(@"识别成功%@",qrObject.stringValue);
  564. // }
  565. //}
  566. - (void)didReceiveMemoryWarning {
  567. [super didReceiveMemoryWarning];
  568. // Dispose of any resources that can be recreated.
  569. }
  570. -(void) didServerResultSucces:(JXConnection*)aDownload dict:(NSDictionary*)dict array:(NSArray*)array1{
  571. [_wait stop];
  572. if ([aDownload.action isEqualToString:act_roomJoin]) {
  573. [self showChatView];
  574. [self actionQuit];
  575. }
  576. if( [aDownload.action isEqualToString:act_UserGet] ){
  577. JXUserObject* user = [[JXUserObject alloc]init];
  578. [user getDataFromDict:dict];
  579. JXUserInfoVC* vc = [JXUserInfoVC alloc];
  580. vc.user = user;
  581. vc = [vc init];
  582. // [g_window addSubview:vc.view];
  583. [g_navigation pushViewController:vc animated:YES];
  584. [self actionQuit];
  585. }else if( [aDownload.action isEqualToString:act_roomGet] ){
  586. _dataDict = dict;
  587. if(g_xmpp.isLogined != 1){
  588. // 掉线后点击title重连
  589. // 判断XMPP是否在线 不在线重连
  590. [g_xmpp showXmppOfflineAlert];
  591. return;
  592. }
  593. // _chatRoom = [g_xmpp.roomPool joinRoom:[dict objectForKey:@"jid"] title:[dict objectForKey:@"name"] isNew:YES];
  594. JXUserObject *user = [[JXUserObject sharedInstance] getUserById:[dict objectForKey:@"jid"]];
  595. if(user && [user.groupStatus intValue] == 0){
  596. //老房间:
  597. _chatRoom = [[JXXMPP sharedInstance].roomPool joinRoom:[dict objectForKey:@"jid"] title:[dict objectForKey:@"name"] lastDate:nil isNew:YES];
  598. //老房间:
  599. [self showChatView];
  600. [self actionQuit];
  601. }else{
  602. BOOL isNeedVerify = [dict[@"isNeedVerify"] boolValue];
  603. long userId = [dict[@"userId"] longLongValue];
  604. if (isNeedVerify && userId != [g_myself.userId longLongValue]) {
  605. self.roomJid = [dict objectForKey:@"jid"];
  606. self.roomUserName = [dict objectForKey:@"nickname"];
  607. self.roomUserId = [dict objectForKey:@"userId"];
  608. JXInputVC* vc = [JXInputVC alloc];
  609. vc.delegate = self;
  610. vc.didTouch = @selector(onInputHello:);
  611. vc.inputTitle = Localized(@"JX_GroupOwnersHaveEnabled");
  612. vc.titleColor = [UIColor lightGrayColor];
  613. vc.titleFont = [UIFont systemFontOfSize:13.0];
  614. vc.inputHint = Localized(@"JX_PleaseEnterTheReason");
  615. vc = [vc init];
  616. [g_window addSubview:vc.view];
  617. }else {
  618. _chatRoom = [[JXXMPP sharedInstance].roomPool joinRoom:[dict objectForKey:@"jid"] title:[dict objectForKey:@"name"] lastDate:nil isNew:YES];
  619. [_wait start:Localized(@"JXAlert_AddRoomIng") delay:30];
  620. //新房间:
  621. _chatRoom.delegate = self;
  622. [_chatRoom joinRoom:YES];
  623. }
  624. }
  625. }
  626. if ([aDownload.action isEqualToString:act_UserQrCodeLogin]) {
  627. if (self.isQRLoginAction) {
  628. [JXMyTools showTipView:Localized(@"JX_SuccessfulLogin")];
  629. }else {
  630. JXWebLoginVC *vc = [[JXWebLoginVC alloc] init];
  631. vc.delegate = self;
  632. vc.isQRLogin = YES;
  633. [g_navigation pushViewController:vc animated:YES];
  634. [self actionQuit];
  635. }
  636. }
  637. if ([aDownload.action isEqualToString:act_UserGetByAccount]) {
  638. JXUserInfoVC* vc = [JXUserInfoVC alloc];
  639. vc.userId = dict[@"userId"];
  640. vc.fromAddType = 1;
  641. vc = [vc init];
  642. [g_navigation pushViewController:vc animated:YES];
  643. [self actionQuit];
  644. }
  645. }
  646. - (void)webLoginSuccess {
  647. self.isQRLoginAction = YES;
  648. [g_server userQrCodeLoginWithQRCodeKey:self.qrCodeKey type:@"2" toView:self];
  649. }
  650. -(void)onInputHello:(JXInputVC*)sender{
  651. JXMessageObject *msg = [[JXMessageObject alloc] init];
  652. msg.fromUserId = MY_USER_ID;
  653. msg.toUserId = [NSString stringWithFormat:@"%@", self.roomUserId];
  654. msg.fromUserName = MY_USER_NAME;
  655. msg.toUserName = self.roomUserName;
  656. msg.timeSend = [NSDate date];
  657. msg.type = [NSNumber numberWithInt:kRoomRemind_NeedVerify];
  658. NSString *userIds = g_myself.userId;
  659. NSString *userNames = g_myself.userNickname;
  660. NSDictionary *dict = @{
  661. @"userIds" : userIds,
  662. @"userNames" : userNames,
  663. @"roomJid" : self.roomJid,
  664. @"reason" : sender.inputText,
  665. @"isInvite" : [NSNumber numberWithBool:YES]
  666. };
  667. NSError *error = nil;
  668. NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&error];
  669. NSString *jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
  670. msg.objectId = jsonStr;
  671. [g_xmpp sendMessage:msg roomName:nil];
  672. [self actionQuit];
  673. // msg.fromUserId = self.roomJid;
  674. // msg.type = [NSNumber numberWithInt:kWCMessageTypeRemind];
  675. // msg.content = @"申请已发送给群主,请等待群主确认";
  676. // [msg insert:self.roomJid];
  677. // if ([self.delegate respondsToSelector:@selector(needVerify:)]) {
  678. // [self.delegate needVerify:msg];
  679. // }
  680. }
  681. -(int) didServerResultFailed:(JXConnection*)aDownload dict:(NSDictionary*)dict{
  682. [_wait stop];
  683. return show_error;
  684. }
  685. -(int) didServerConnectError:(JXConnection*)aDownload error:(NSError *)error{//error为空时,代表超时
  686. [_wait stop];
  687. return show_error;
  688. }
  689. -(void) didServerConnectStart:(JXConnection*)aDownload{
  690. [_wait start];
  691. }
  692. -(void)xmppRoomDidJoin{
  693. NSDictionary * dict = _dataDict;
  694. JXUserObject* user = [[JXUserObject alloc]init];
  695. user.userNickname = [dict objectForKey:@"name"];
  696. user.userId = [dict objectForKey:@"jid"];
  697. user.userDescription = [dict objectForKey:@"desc"];
  698. user.roomId = [dict objectForKey:@"id"];
  699. user.showRead = [dict objectForKey:@"showRead"];
  700. user.showMember = [dict objectForKey:@"showMember"];
  701. user.allowSendCard = [dict objectForKey:@"allowSendCard"];
  702. user.chatRecordTimeOut = [dict objectForKey:@"chatRecordTimeOut"];
  703. user.talkTime = [dict objectForKey:@"talkTime"];
  704. user.allowInviteFriend = [dict objectForKey:@"allowInviteFriend"];
  705. user.allowUploadFile = [dict objectForKey:@"allowUploadFile"];
  706. user.allowConference = [dict objectForKey:@"allowConference"];
  707. user.allowSpeakCourse = [dict objectForKey:@"allowSpeakCourse"];
  708. user.isNeedVerify = [dict objectForKey:@"isNeedVerify"];
  709. if (![user haveTheUser])
  710. [user insertRoom];
  711. // else
  712. // [user update];
  713. // [user release];
  714. // [g_server addRoomMember:[dict objectForKey:@"id"] userId:g_myself.userId nickName:g_myself.userNickname toView:self];
  715. [g_server roomJoin:[dict objectForKey:@"id"] userId:g_myself.userId nickName:g_myself.userNickname toView:self];
  716. dict = nil;
  717. _chatRoom.delegate = nil;
  718. }
  719. -(void)showChatView{
  720. [_wait stop];
  721. NSDictionary * dict = _dataDict;
  722. roomData * roomdata = [[roomData alloc] init];
  723. [roomdata getDataFromDict:dict];
  724. JXChatViewController *sendView=[JXChatViewController alloc];
  725. sendView.title = [dict objectForKey:@"name"];
  726. sendView.roomJid = [dict objectForKey:@"jid"];
  727. sendView.roomId = [dict objectForKey:@"id"];
  728. sendView.chatRoom = _chatRoom;
  729. sendView.room = roomdata;
  730. JXUserObject * userObj = [[JXUserObject alloc]init];
  731. userObj.userId = [dict objectForKey:@"jid"];
  732. userObj.showRead = [dict objectForKey:@"showRead"];
  733. userObj.userNickname = [dict objectForKey:@"name"];
  734. userObj.showMember = [dict objectForKey:@"showMember"];
  735. userObj.allowSendCard = [dict objectForKey:@"allowSendCard"];
  736. userObj.chatRecordTimeOut = roomdata.chatRecordTimeOut;
  737. userObj.talkTime = [dict objectForKey:@"talkTime"];
  738. userObj.allowInviteFriend = [dict objectForKey:@"allowInviteFriend"];
  739. userObj.allowUploadFile = [dict objectForKey:@"allowUploadFile"];
  740. userObj.allowConference = [dict objectForKey:@"allowConference"];
  741. userObj.allowSpeakCourse = [dict objectForKey:@"allowSpeakCourse"];
  742. userObj.isNeedVerify = [dict objectForKey:@"isNeedVerify"];
  743. sendView.chatPerson = userObj;
  744. sendView = [sendView init];
  745. // [g_App.window addSubview:sendView.view];
  746. [g_navigation pushViewController:sendView animated:YES];
  747. dict = nil;
  748. }
  749. - (BOOL)isNumber:(NSString *)strValue
  750. {
  751. if (strValue == nil || [strValue length] <= 0)
  752. {
  753. return NO;
  754. }
  755. NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet];
  756. NSString *filtered = [[strValue componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
  757. if (![strValue isEqualToString:filtered])
  758. {
  759. return NO;
  760. }
  761. return YES;
  762. }
  763. - (void)actionQuit {
  764. [super actionQuit];
  765. [self.tcpScoket disconnect];
  766. }
  767. @end