BasicModeViewController.m 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. //
  2. // BasicModeViewController.m
  3. // RA Image
  4. //
  5. // Created by Jack on 2017/5/3.
  6. // Copyright © 2017年 USAI. All rights reserved.
  7. //
  8. #import "BasicModeViewController.h"
  9. #import "ScannerViewController.h"
  10. #import "PhotoListViewController.h"
  11. #import "UploadViewController.h"
  12. #import <AVFoundation/AVFoundation.h>
  13. #import <AssetsLibrary/AssetsLibrary.h>
  14. #import "TakePhotoPreviewController.h"
  15. #pragma clang diagnostic push
  16. #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  17. @interface BasicModeViewController ()<UITextFieldDelegate>
  18. @property (nonatomic,strong) UIImagePickerController *imgPicker;
  19. @end
  20. @implementation BasicModeViewController
  21. - (void)viewDidLoad {
  22. [super viewDidLoad];
  23. // Do any additional setup after loading the view.
  24. self.photoCount = 0;
  25. UIBarButtonItem *uploadListItem = [[UIBarButtonItem alloc] initWithTitle:@"Upload List" style:UIBarButtonItemStylePlain target:self action:@selector(showUploadList)];
  26. self.navigationItem.rightBarButtonItem = uploadListItem;
  27. AppDelegate* appdelegate=(AppDelegate*)[UIApplication sharedApplication].delegate;
  28. [appdelegate.uploadManager addObserver:self
  29. forKeyPath:@"queue_status"
  30. options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld)
  31. context:@"queue_status changed"];
  32. }
  33. -(void) dealloc
  34. {
  35. AppDelegate* appdelegate=(AppDelegate*)[UIApplication sharedApplication].delegate;
  36. [appdelegate.uploadManager removeObserver:self forKeyPath:@"queue_status"];
  37. }
  38. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
  39. {
  40. if([keyPath isEqualToString:@"queue_status"])
  41. {
  42. NSString* msg=@"";
  43. switch ([[change objectForKey:NSKeyValueChangeNewKey] intValue]) {
  44. case QueueStatusFinish:
  45. msg=@"Upload is complete.";
  46. [[UIApplication sharedApplication] setIdleTimerDisabled:NO];
  47. break;
  48. case QueueStatusAdd:
  49. msg=@"New tasks added.";
  50. [[UIApplication sharedApplication] setIdleTimerDisabled:YES];
  51. break;
  52. case QueueStatusFinishWithError:
  53. {
  54. NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
  55. NSDictionary* dict=[userDefaults objectForKey:@"UploadSettingKey"];
  56. if([dict[@"auto_rm_error"] boolValue])
  57. msg=@"Upload is complete.";
  58. else
  59. msg=@"Some of the tasks have not been successfully uploaded.\n Check upload list for detail.";
  60. [[UIApplication sharedApplication] setIdleTimerDisabled:NO];
  61. break;
  62. }
  63. default:
  64. break;
  65. }
  66. dispatch_async(dispatch_get_main_queue(), ^{
  67. if(msg.length>0)
  68. [self.view makeToast:msg duration:3.0 position:CSToastPositionCenter];
  69. });
  70. }
  71. }
  72. - (void)didReceiveMemoryWarning {
  73. [super didReceiveMemoryWarning];
  74. // Dispose of any resources that can be recreated.
  75. }
  76. - (void)viewWillAppear:(BOOL)animated {
  77. [super viewWillAppear:animated];
  78. }
  79. - (NSMutableArray *)photos {
  80. if (!_photos) {
  81. _photos = [NSMutableArray array];
  82. }
  83. return _photos;
  84. }
  85. - (void)showUploadList {
  86. UploadViewController *upVC = (UploadViewController *)[self viewControllerInStoryboard:@"Upload" withId:@"UploadViewController"];
  87. [self.navigationController pushViewController:upVC animated:YES];
  88. }
  89. - (void)showPhotoList {
  90. if (!self.photos.count) {
  91. // [RAUtils message_alert:@"There is no photo" title:@"Note" controller:self];
  92. [self showCamera];
  93. return;
  94. }
  95. PhotoListViewController *photoListVC = (PhotoListViewController *)[self viewControllerInStoryboard:@"PhotoList" withId:@"PhotoListViewController"];
  96. // photoListVC.photos = self.photos;
  97. photoListVC.modeVC = self;
  98. [self.navigationController pushViewController:photoListVC animated:YES];
  99. }
  100. - (void)showScanner {
  101. __weak typeof(self) weakself = self;
  102. ScannerViewController *scannerVC = [[UIStoryboard storyboardWithName:@"cam_scan" bundle:nil] instantiateViewControllerWithIdentifier:@"NewScannerViewController"];
  103. scannerVC.returnCode = ^(NSString *code) {
  104. // 扫描成功保存扫描值
  105. if (code.length) {
  106. if (weakself) {
  107. __strong typeof(weakself) strongself = weakself;
  108. strongself.barcode = code;
  109. }
  110. }
  111. };
  112. [self presentViewController:scannerVC animated:YES completion:nil];
  113. }
  114. - (void)showCamera {
  115. if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
  116. [RAUtils message_alert:@"Camera is not available" title:@"Warning" controller:self];
  117. return;
  118. }
  119. //相机权限
  120. AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
  121. if (authStatus ==AVAuthorizationStatusRestricted ||//此应用程序没有被授权访问的照片数据。可能是家长控制权限
  122. authStatus ==AVAuthorizationStatusDenied) //用户已经明确否认了这一照片数据的应用程序访问
  123. {
  124. // 无权限 引导去开启
  125. NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
  126. if ([[UIApplication sharedApplication]canOpenURL:url]) {
  127. [[UIApplication sharedApplication]openURL:url];// 打开权限后返回应用会重启
  128. } else {
  129. NSDictionary* infoDict =[[NSBundle mainBundle] infoDictionary];
  130. NSString *appName = [infoDict objectForKey:@"CFBundleName"];
  131. [RAUtils message_alert:[NSString stringWithFormat:@"%@ need Authorization to use Camera",appName] title:@"Warning" controller:self];
  132. }
  133. return;
  134. }
  135. // UIImagePickerController *imgPicker = [[UIImagePickerController alloc] init];
  136. // imgPicker.delegate = self;
  137. //
  138. // imgPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
  139. // imgPicker.allowsEditing = YES;
  140. // [self presentViewController:imgPicker animated:YES completion:nil];
  141. CGFloat w = CGRectGetWidth(self.view.frame);
  142. CGFloat h = CGRectGetHeight(self.view.frame);
  143. if (self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft || self.interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
  144. // 修复横屏时打开相机Control位置不正确
  145. CGFloat tmp = w;
  146. w = h;
  147. h = tmp;
  148. }
  149. // 自定义相机控制视图
  150. UIImagePickerController *imgPicker = [[UIImagePickerController alloc] init];
  151. imgPicker.delegate = self;
  152. imgPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
  153. imgPicker.allowsEditing = NO;
  154. imgPicker.showsCameraControls = NO;
  155. UIView* overlay = [[UIView alloc]initWithFrame:CGRectMake(0, h - 150 , w, 150)];
  156. // Cancel
  157. UIButton *cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  158. cancelBtn.frame = CGRectMake(20, (150 - 40) * 0.5, 60, 40);
  159. [cancelBtn setTitle:@"cancel" forState:UIControlStateNormal];
  160. [cancelBtn addTarget:self action:@selector(cancelCameraClick:) forControlEvents:UIControlEventTouchUpInside];
  161. [overlay addSubview:cancelBtn];
  162. // Take
  163. UIButton *takeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  164. takeBtn.frame = CGRectMake((w - 60) * 0.5, (150 - 40) * 0.5, 60, 40);
  165. [takeBtn setTitle:@"take" forState:UIControlStateNormal];
  166. [takeBtn addTarget:self action:@selector(takePhotoClick:) forControlEvents:UIControlEventTouchUpInside];
  167. [overlay addSubview:takeBtn];
  168. // flash
  169. UIButton *flashBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  170. flashBtn.frame = CGRectMake(w - 80, (150 - 40) * 0.5, 60, 40);
  171. [flashBtn setTitle:@"Auto" forState:UIControlStateNormal];
  172. [flashBtn addTarget:self action:@selector(flashBtnClick:) forControlEvents:UIControlEventTouchUpInside];
  173. [overlay addSubview:flashBtn];
  174. // // camera
  175. // UIButton *cameraChangeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  176. // cameraChangeBtn.frame = CGRectMake(220, 10, 60, 40);
  177. // [cameraChangeBtn setTitle:@"change" forState:UIControlStateNormal];
  178. // [cameraChangeBtn addTarget:self action:@selector(cameraChangeClick:) forControlEvents:UIControlEventTouchUpInside];
  179. // [overlay addSubview:cameraChangeBtn];
  180. // 相机属性设置得在设置SourceType后设置
  181. imgPicker.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
  182. //把自定义的view设置到imagepickercontroller的overlay属性中
  183. imgPicker.cameraOverlayView = overlay;
  184. self.imgPicker = imgPicker;
  185. [self presentViewController:imgPicker animated:YES completion:nil];
  186. }
  187. - (void)showPhotoLibrary {
  188. if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
  189. [RAUtils message_alert:@"Photo Library is not available" title:@"Warning" controller:self];
  190. return;
  191. }
  192. //相册权限
  193. ALAuthorizationStatus author = [ALAssetsLibrary authorizationStatus];
  194. if (author ==ALAuthorizationStatusRestricted || author ==ALAuthorizationStatusDenied){
  195. //无权限 引导去开启
  196. NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
  197. if ([[UIApplication sharedApplication] canOpenURL:url]) {
  198. [[UIApplication sharedApplication] openURL:url];
  199. } else {
  200. NSDictionary* infoDict =[[NSBundle mainBundle] infoDictionary];
  201. NSString *appName = [infoDict objectForKey:@"CFBundleName"];
  202. [RAUtils message_alert:[NSString stringWithFormat:@"%@ need Authorization to use photo library",appName] title:@"Warning" controller:self];
  203. }
  204. return;
  205. }
  206. UIImagePickerController *imgPicker = [[UIImagePickerController alloc] init];
  207. imgPicker.delegate = self;
  208. imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
  209. imgPicker.allowsEditing = NO;
  210. [self presentViewController:imgPicker animated:YES completion:nil];
  211. }
  212. - (void)showBarcodeInput:(UIKeyboardType)keyboardType {
  213. [self tapResignFirstResponder:nil];
  214. __weak typeof(self) weakself = self;
  215. UIAlertController *alert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Please enter %@ Code",self.barcodeTitle] message:nil preferredStyle:UIAlertControllerStyleAlert];
  216. [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
  217. textField.text = weakself.barcode;
  218. textField.delegate = weakself;
  219. textField.clearButtonMode = UITextFieldViewModeWhileEditing;
  220. textField.keyboardType = keyboardType;
  221. }];
  222. UIAlertAction *OK = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  223. }];
  224. [alert addAction:OK];
  225. [self presentViewController:alert animated:YES completion:nil];
  226. }
  227. - (void)showTopImage {
  228. NSDictionary *item = [self.photos firstObject];
  229. UIImage *img = [item objectForKey:@"photo"];
  230. [self receiveImage:img];
  231. }
  232. - (NSString *)saveImage:(UIImage *)img {
  233. NSString *dir = [NSString stringWithFormat:@"%@/%@",NSTemporaryDirectory(),self.name];
  234. NSDate * date = [NSDate date];
  235. NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
  236. [dateFormatter setDateFormat:@"YYYYMMddHHmmss"];
  237. NSString * name = [[dateFormatter stringFromDate:date] stringByAppendingPathExtension:@"png"];
  238. name=[self.barcodeTitle stringByAppendingString:name];
  239. // NSString *name = [[NSUUID UUID] UUIDString];
  240. // name = [name stringByAppendingPathExtension:@"png"];
  241. NSString *path = [dir stringByAppendingPathComponent:name];
  242. if ([RAUtils saveData:UIImagePNGRepresentation(img) toPath:path]) {
  243. return path;
  244. }
  245. return nil;
  246. }
  247. //- (void)loadSavedPhotoCount {
  248. // NSString *dir = [NSString stringWithFormat:@"%@/%@",[RAUtils appCacheDirectory],self.name];
  249. // NSFileManager *manager = [NSFileManager defaultManager];
  250. // NSArray *files = [manager contentsOfDirectoryAtPath:dir error:nil];
  251. // if (files.count) {
  252. // NSMutableArray *photos = [NSMutableArray array];
  253. // for (NSString *name in files) {
  254. // if ([name hasSuffix:@".png"]) {
  255. // NSString *path = [dir stringByAppendingPathComponent:name];
  256. // UIImage *img = [UIImage imageWithContentsOfFile:path];
  257. // NSString *md5 = [RAUtils md5WithFile:path];
  258. // NSDictionary *photoDic = @{
  259. // @"photo" : img,
  260. // @"check" : @(NO),
  261. // @"path" : path,
  262. // @"md5" : md5
  263. // };
  264. // [photos addObject:photoDic];
  265. // }
  266. // }
  267. // self.photoCount = photos.count;
  268. // self.photos = photos;
  269. // } else {
  270. // self.photoCount = 0;
  271. // self.photos = nil;
  272. // }
  273. //}
  274. - (void)clearPhotos {
  275. [self.photos removeAllObjects];
  276. self.photoCount = 0;
  277. }
  278. #pragma mark - Public Method
  279. - (void)clickCameraButton {
  280. // __weak typeof(self) weakself = self;
  281. //
  282. //
  283. // UIAlertController *aler = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
  284. // UIAlertAction *library = [UIAlertAction actionWithTitle:@"Camera" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  285. // [weakself showCamera];
  286. // }];
  287. //
  288. // UIAlertAction *camera = [UIAlertAction actionWithTitle:@"Photo Library" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  289. // [weakself showPhotoLibrary];
  290. // }];
  291. //
  292. // UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
  293. //
  294. // }];
  295. //
  296. // [aler addAction:library];
  297. // [aler addAction:camera];
  298. // [aler addAction:cancel];
  299. //
  300. // [self presentViewController:aler animated:YES completion:nil];
  301. [self showCamera];
  302. }
  303. - (void)moveTmpImageToCache:(NSString *)img {
  304. NSString *dir = [NSString stringWithFormat:@"%@/%@",NSTemporaryDirectory(),self.name];
  305. NSString *tmpPath = [dir stringByAppendingPathComponent:img];
  306. NSString *cachePath = [NSString stringWithFormat:@"%@/%@/%@",[RAUtils appCacheDirectory],self.name,img];
  307. NSFileManager *fileManager = [NSFileManager defaultManager];
  308. // 保证移动目标文件夹存在
  309. [fileManager createDirectoryAtPath:[cachePath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:nil];
  310. NSError *err;
  311. BOOL res = [fileManager moveItemAtPath:tmpPath toPath:cachePath error:&err];
  312. if (res) {
  313. DebugLog(@"move tmp to cache");
  314. } else {
  315. DebugLog(@"move tmp to cache failed %@",err);
  316. }
  317. }
  318. #pragma mark - Image Picker Button Action
  319. - (void)cancelCameraClick:(UIButton *)sender {
  320. [self.imgPicker dismissViewControllerAnimated:YES completion:nil];
  321. }
  322. - (void)takePhotoClick:(UIButton *)sender {
  323. [self.imgPicker takePicture];
  324. }
  325. - (void)flashBtnClick:(UIButton *)sender {
  326. UIImagePickerControllerCameraDevice device = self.imgPicker.cameraDevice;
  327. UIImagePickerControllerCameraFlashMode flashMode = self.imgPicker.cameraFlashMode;
  328. NSString *flashMordeString = @"Auto";
  329. switch (flashMode) {
  330. case UIImagePickerControllerCameraFlashModeAuto: {
  331. flashMode = UIImagePickerControllerCameraFlashModeOn;
  332. flashMordeString = @"On";
  333. }
  334. break;
  335. case UIImagePickerControllerCameraFlashModeOn: {
  336. flashMode = UIImagePickerControllerCameraFlashModeOff;
  337. flashMordeString = @"Off";
  338. }
  339. break;
  340. case UIImagePickerControllerCameraFlashModeOff: {
  341. flashMode = UIImagePickerControllerCameraFlashModeAuto;
  342. flashMordeString = @"Auto";
  343. }
  344. break;
  345. default:
  346. break;
  347. }
  348. if ([UIImagePickerController isFlashAvailableForCameraDevice:device]) {
  349. self.imgPicker.cameraFlashMode = flashMode;
  350. [sender setTitle:flashMordeString forState:UIControlStateNormal];
  351. }
  352. }
  353. - (void)cameraChangeClick:(UIButton *)sender {
  354. UIImagePickerControllerCameraDevice device = self.imgPicker.cameraDevice;
  355. if (device == UIImagePickerControllerCameraDeviceRear) {
  356. device = UIImagePickerControllerCameraDeviceFront;
  357. } else {
  358. device = UIImagePickerControllerCameraDeviceRear;
  359. }
  360. if ([UIImagePickerController isCameraDeviceAvailable:device]) {
  361. self.imgPicker.cameraDevice = device;
  362. }
  363. }
  364. #pragma mark - Image Picker Delegate
  365. - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
  366. {
  367. UIImage *image = nil;
  368. if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
  369. if (self.imgPicker.viewControllers.count > 1) return;// 避免连续多次拍照,后多次present
  370. image = [info objectForKey:UIImagePickerControllerOriginalImage];
  371. // [picker dismissViewControllerAnimated:YES completion:nil];
  372. __weak typeof(self) weakself = self;
  373. TakePhotoPreviewController *preVC = (TakePhotoPreviewController *)[self viewControllerInStoryboard:@"Mode" withId:@"TakePhotoPreviewController"];
  374. __weak typeof(preVC) weakPreVC = preVC;
  375. preVC.photoHandler = ^(UIImage *img){
  376. if (img) {
  377. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  378. NSString *path = [weakself saveImage:img];
  379. dispatch_async(dispatch_get_main_queue(), ^{
  380. if (path) {// 保存成功
  381. [weakself receiveImage:img];
  382. NSString *md5 = [RAUtils md5WithFile:path];
  383. NSMutableDictionary *photoDic = @{
  384. @"photo" : img,
  385. @"check" : @(NO),
  386. @"file" : [path lastPathComponent],
  387. @"md5" : md5,
  388. @"path" : path
  389. }.mutableCopy;
  390. [weakself.photos insertObject:photoDic atIndex:0];
  391. weakself.photoCount++;
  392. } else {
  393. [RAUtils message_alert:@"Save photo failed, storage full?" title:@"Warning" controller:weakPreVC];
  394. }
  395. });
  396. });
  397. }
  398. };
  399. preVC.preImage = image;
  400. [self.imgPicker pushViewController:preVC animated:YES];
  401. } else if (picker .sourceType == UIImagePickerControllerSourceTypePhotoLibrary) {
  402. image = [info objectForKey:UIImagePickerControllerOriginalImage];
  403. [picker dismissViewControllerAnimated:YES completion:nil];
  404. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  405. NSString *path = [self saveImage:image];
  406. dispatch_async(dispatch_get_main_queue(), ^{
  407. if (path) {// 保存成功
  408. [self receiveImage:image];
  409. NSString *md5 = [RAUtils md5WithFile:path];
  410. NSMutableDictionary *photoDic = @{
  411. @"photo" : image,
  412. @"check" : @(NO),
  413. @"file" : [path lastPathComponent],
  414. @"md5" : md5,
  415. @"path" : path
  416. }.mutableCopy;
  417. [self.photos insertObject:photoDic atIndex:0];
  418. self.photoCount++;
  419. } else {
  420. [RAUtils message_alert:@"Save photo failed, storage full?" title:@"Warning" controller:self];
  421. }
  422. });
  423. });
  424. }
  425. }
  426. - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
  427. [picker dismissViewControllerAnimated:YES completion:nil];
  428. }
  429. #pragma mark - TextField Delegate
  430. - (void)textFieldDidEndEditing:(UITextField *)textField {
  431. self.barcode = textField.text;
  432. }
  433. #pragma mark - SubClass Override
  434. - (void)receiveImage:(UIImage *)img {
  435. }
  436. @end
  437. #pragma clang diagnostic pop