From f5716b15701ce07c079e7d6029206b351fa79df3 Mon Sep 17 00:00:00 2001 From: Danmei Chen Date: Mon, 8 Oct 2018 14:15:42 +0200 Subject: [PATCH 1/9] update linphone --- submodules/linphone | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/linphone b/submodules/linphone index f319f5cf1..4c7c3de24 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit f319f5cf17eb0f54596fdd02a0c1bd6f1ebca552 +Subproject commit 4c7c3de24bf6fc2d1d95c3c6d025b788275f9554 From f3aa7b45550e47ff3c372b6cfdca24bc7860f645 Mon Sep 17 00:00:00 2001 From: Danmei Chen Date: Tue, 21 Aug 2018 16:37:37 +0200 Subject: [PATCH 2/9] optimization of file sharing --- Classes/ChatConversationView.m | 2 +- .../Base.lproj/UIChatBubblePhotoCell.xib | 42 ++++++++++++------- Classes/LinphoneUI/UIChatBubblePhotoCell.h | 6 +-- Classes/LinphoneUI/UIChatBubblePhotoCell.m | 20 ++++----- 4 files changed, 39 insertions(+), 31 deletions(-) diff --git a/Classes/ChatConversationView.m b/Classes/ChatConversationView.m index cd0d3edd4..30a91a3b7 100644 --- a/Classes/ChatConversationView.m +++ b/Classes/ChatConversationView.m @@ -913,7 +913,7 @@ void on_chat_room_conference_left(LinphoneChatRoom *cr, const LinphoneEventLog * inMode:UIDocumentPickerModeImport]; _documentPicker.delegate = self; - _documentPicker.modalPresentationStyle = UIModalPresentationFormSheet; + _documentPicker.modalPresentationStyle = UIModalPresentationOverCurrentContext ; [self presentViewController:_documentPicker animated:YES completion:nil]; } diff --git a/Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.xib b/Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.xib index 50403d66f..c453ff689 100644 --- a/Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.xib +++ b/Classes/LinphoneUI/Base.lproj/UIChatBubblePhotoCell.xib @@ -19,8 +19,10 @@ - + + + @@ -29,7 +31,6 @@ - @@ -74,14 +75,6 @@ - @@ -144,7 +137,6 @@ - @@ -179,6 +171,29 @@ + + + + + + + + @@ -200,11 +215,6 @@ - - - - - diff --git a/Classes/LinphoneUI/UIChatBubblePhotoCell.h b/Classes/LinphoneUI/UIChatBubblePhotoCell.h index 1aa697eec..c39967456 100644 --- a/Classes/LinphoneUI/UIChatBubblePhotoCell.h +++ b/Classes/LinphoneUI/UIChatBubblePhotoCell.h @@ -34,11 +34,12 @@ @property(weak, nonatomic) IBOutlet UIProgressView *fileTransferProgress; @property(weak, nonatomic) IBOutlet UIButton *cancelButton; @property(weak, nonatomic) IBOutlet UIView *imageSubView; -@property (strong, nonatomic) IBOutlet UITapGestureRecognizer *openRecognizer; @property(weak, nonatomic) IBOutlet UIView *totalView; @property (weak, nonatomic) IBOutlet UIView *finalAssetView; @property (weak, nonatomic) IBOutlet UIImageView *finalImage; @property(strong, nonatomic) IBOutlet UITapGestureRecognizer *imageGestureRecognizer; +@property (weak, nonatomic) IBOutlet UIButton *fileButton; +@property (weak, nonatomic) IBOutlet UIView *fileView; - (void)setEvent:(LinphoneEventLog *)event; - (void)setChatMessage:(LinphoneChatMessage *)message; @@ -48,8 +49,7 @@ - (IBAction)onCancelClick:(id)sender; - (IBAction)onResendClick:(id)event; - (IBAction)onPlayClick:(id)sender; -- (IBAction)onOpenClick:(id)event; - +- (IBAction)onFileClick:(id)sender; @end diff --git a/Classes/LinphoneUI/UIChatBubblePhotoCell.m b/Classes/LinphoneUI/UIChatBubblePhotoCell.m index ca81111a7..18fe351d4 100644 --- a/Classes/LinphoneUI/UIChatBubblePhotoCell.m +++ b/Classes/LinphoneUI/UIChatBubblePhotoCell.m @@ -72,7 +72,6 @@ - (void)setChatMessage:(LinphoneChatMessage *)amessage { _imageGestureRecognizer.enabled = NO; - _openRecognizer.enabled = NO; _messageImageView.image = nil; _finalImage.image = nil; _finalImage.hidden = TRUE; @@ -131,9 +130,8 @@ - (void) loadFileAsset { dispatch_async(dispatch_get_main_queue(), ^{ - _fileName.hidden = NO; + _fileName.hidden = _fileView.hidden = _fileButton.hidden = NO; _imageGestureRecognizer.enabled = NO; - _openRecognizer.enabled = YES; }); } @@ -167,14 +165,14 @@ if (!(localImage || localVideo || localFile)) { _playButton.hidden = YES; - _fileName.hidden = YES; + _fileName.hidden = _fileView.hidden = _fileButton.hidden = YES; _messageImageView.hidden = _cancelButton.hidden = (_ftd.message == nil); _downloadButton.hidden = !_cancelButton.hidden; _fileTransferProgress.hidden = NO; } else { // file is being saved on device - just wait for it if ([localImage isEqualToString:@"saving..."] || [localVideo isEqualToString:@"saving..."] || [localFile isEqualToString:@"saving..."]) { - _cancelButton.hidden = _fileTransferProgress.hidden = _downloadButton.hidden = _playButton.hidden = _fileName.hidden = YES; + _cancelButton.hidden = _fileTransferProgress.hidden = _downloadButton.hidden = _playButton.hidden = _fileName.hidden = _fileView.hidden = _fileButton.hidden = YES; fullScreenImage = YES; } else if(!assetIsLoaded) { assetIsLoaded = TRUE; @@ -191,7 +189,7 @@ } } else if (localFile) { - NSString *text = [NSString stringWithFormat:@"📎 %@",localFile]; + NSString *text = [NSString stringWithFormat:@"📎 %@",localFile]; _fileName.text = text; [self loadFileAsset]; } @@ -202,12 +200,12 @@ _fileTransferProgress.hidden = NO; _downloadButton.hidden = YES; _playButton.hidden = YES; - _fileName.hidden = YES; + _fileName.hidden = _fileView.hidden = _fileButton.hidden =YES; } else { _cancelButton.hidden = _fileTransferProgress.hidden = _downloadButton.hidden = YES; fullScreenImage = YES; _playButton.hidden = localVideo ? NO : YES; - _fileName.hidden = localFile ? NO : YES; + _fileName.hidden = _fileView.hidden = _fileButton.hidden = localFile ? NO : YES; // Should fix cell not resizing after doanloading image. [self layoutSubviews]; } @@ -250,7 +248,7 @@ _cancelButton.hidden = NO; _downloadButton.hidden = YES; _playButton.hidden = YES; - _fileName.hidden = YES; + _fileName.hidden = _fileView.hidden = _fileButton.hidden = YES; } - (IBAction)onPlayClick:(id)sender { @@ -271,7 +269,7 @@ }]; } -- (IBAction)onOpenClick:(id)event { +- (IBAction)onFileClick:(id)sender { ChatConversationView *view = VIEW(ChatConversationView); NSString *cachedFile = [LinphoneManager getMessageAppDataForKey:@"cachedfile" inMessage:self.message]; if (cachedFile) { @@ -401,7 +399,7 @@ } bubbleFrame.origin.x = origin_x; - + super.bubbleView.frame = bubbleFrame; // Resizing Image view From dae0d9a093a18d3da2efb1c749eadaec4b7ffceb Mon Sep 17 00:00:00 2001 From: Danmei Chen Date: Wed, 22 Aug 2018 11:59:22 +0200 Subject: [PATCH 3/9] complete resend function --- Classes/ChatConversationTableView.h | 2 + Classes/ChatConversationView.h | 4 +- Classes/ChatConversationView.m | 27 +------- Classes/LinphoneUI/UIChatBubblePhotoCell.m | 6 +- Classes/LinphoneUI/UIChatBubbleTextCell.h | 5 +- Classes/LinphoneUI/UIChatBubbleTextCell.m | 75 +++++++++++++++++++--- 6 files changed, 78 insertions(+), 41 deletions(-) diff --git a/Classes/ChatConversationTableView.h b/Classes/ChatConversationTableView.h index 551a22a4d..a29288367 100644 --- a/Classes/ChatConversationTableView.h +++ b/Classes/ChatConversationTableView.h @@ -28,6 +28,8 @@ @protocol ChatConversationDelegate - (BOOL)startImageUpload:(UIImage *)image assetId:(NSString *)phAssetId withQuality:(float)quality; +- (BOOL)startFileUpload:(NSData *)data assetId:(NSString *)phAssetId; +- (BOOL)startFileUpload:(NSData *)data withName:(NSString *)name; - (void)resendChat:(NSString *)message withExternalUrl:(NSString *)url; - (void)tableViewIsScrolling; diff --git a/Classes/ChatConversationView.h b/Classes/ChatConversationView.h index 422cad12a..3fa69519f 100644 --- a/Classes/ChatConversationView.h +++ b/Classes/ChatConversationView.h @@ -32,7 +32,7 @@ #include "linphone/linphonecore.h" @interface ChatConversationView - : TPMultiLayoutViewController { OrderedDictionary *imageQualities; BOOL scrollOnGrowingEnabled; @@ -61,7 +61,6 @@ @property (weak, nonatomic) IBOutlet UIIconButton *infoButton; @property (weak, nonatomic) IBOutlet UILabel *particpantsLabel; @property (nonatomic, strong) UIDocumentInteractionController *documentInteractionController; -@property (nonatomic, strong) UIDocumentPickerViewController *documentPicker; @property NSMutableArray *imagesArray; @property NSMutableArray *assetIdsArray; @property NSMutableArray *qualitySettingsArray; @@ -81,7 +80,6 @@ - (IBAction)onDeleteClick:(id)sender; - (IBAction)onEditionChangeClick:(id)sender; - (void)update; -- (void)getIcloudFiles; - (void)openFile:(NSString *) filePath; - (void)clearMessageView; diff --git a/Classes/ChatConversationView.m b/Classes/ChatConversationView.m index 30a91a3b7..840cc3d7f 100644 --- a/Classes/ChatConversationView.m +++ b/Classes/ChatConversationView.m @@ -626,7 +626,7 @@ static UICompositeViewDescription *compositeDescription = nil; return TRUE; } -- (BOOL)startFileUpload:(NSData *)data assetId:phAssetId { +- (BOOL)startFileUpload:(NSData *)data assetId:(NSString *)phAssetId { FileTransferDelegate *fileTransfer = [[FileTransferDelegate alloc] init]; [fileTransfer uploadVideo:data withassetId:phAssetId forChatRoom:_chatRoom]; [_tableController scrollToBottom:true]; @@ -907,16 +907,6 @@ void on_chat_room_conference_left(LinphoneChatRoom *cr, const LinphoneEventLog * [view.tableController scrollToBottom:true]; } -- (void)getIcloudFiles -{ - _documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[@"public.data"] - inMode:UIDocumentPickerModeImport]; - _documentPicker.delegate = self; - - _documentPicker.modalPresentationStyle = UIModalPresentationOverCurrentContext ; - [self presentViewController:_documentPicker animated:YES completion:nil]; -} - - (void)openFile:(NSString *) filePath { // Open the controller. @@ -931,21 +921,6 @@ void on_chat_room_conference_left(LinphoneChatRoom *cr, const LinphoneEventLog * } } -- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url { - - NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil]; - [fileCoordinator coordinateReadingItemAtURL:url options:NSFileCoordinatorReadingWithoutChanges error:nil byAccessor:^(NSURL * _Nonnull newURL) { - - NSString *fileName = [newURL lastPathComponent]; - NSData *data = [NSData dataWithContentsOfURL:newURL]; - - NSString *filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:fileName]; - - [[NSFileManager defaultManager] createFileAtPath:filePath contents:data attributes:nil]; - [self openFile:filePath]; - }]; -} - - (void)deleteImageWithAssetId:(NSString *)assetId { NSUInteger key = [_assetIdsArray indexOfObject:assetId]; [_imagesArray removeObjectAtIndex:key]; diff --git a/Classes/LinphoneUI/UIChatBubblePhotoCell.m b/Classes/LinphoneUI/UIChatBubblePhotoCell.m index 18fe351d4..c9e4ed27c 100644 --- a/Classes/LinphoneUI/UIChatBubblePhotoCell.m +++ b/Classes/LinphoneUI/UIChatBubblePhotoCell.m @@ -279,8 +279,10 @@ } else { [self fileErrorBlock]; } - } else - [view getIcloudFiles]; + } else { + [LinphoneManager setValueInMessageAppData:@"onFileClick" forKey:@"icloudFileOption" inMessage:self.message]; + [super getIcloudFiles]; + } } diff --git a/Classes/LinphoneUI/UIChatBubbleTextCell.h b/Classes/LinphoneUI/UIChatBubbleTextCell.h index 18f5d879c..1d66bc5b8 100644 --- a/Classes/LinphoneUI/UIChatBubbleTextCell.h +++ b/Classes/LinphoneUI/UIChatBubbleTextCell.h @@ -23,7 +23,7 @@ #import "ChatConversationTableView.h" #import "UIRoundedImageView.h" -@interface UIChatBubbleTextCell : UITableViewCell +@interface UIChatBubbleTextCell : UITableViewCell @property(readonly, nonatomic) LinphoneEventLog *event; @property(readonly, nonatomic) LinphoneChatMessage *message; @@ -40,11 +40,14 @@ @property(weak, nonatomic) IBOutlet UIImageView *imdmIcon; @property(weak, nonatomic) IBOutlet UILabel *imdmLabel; +@property (nonatomic, strong) UIDocumentPickerViewController *documentPicker; + + (CGSize)ViewSizeForMessage:(LinphoneChatMessage *)chat withWidth:(int)width; + (CGSize)getMediaMessageSizefromOriginalSize:(CGSize)originalSize withWidth:(int)width; - (void)setEvent:(LinphoneEventLog *)event; - (void)setChatMessage:(LinphoneChatMessage *)message; +- (void)getIcloudFiles; - (void)onDelete; - (void)onResend; diff --git a/Classes/LinphoneUI/UIChatBubbleTextCell.m b/Classes/LinphoneUI/UIChatBubbleTextCell.m index 85b20dce9..8e207f682 100644 --- a/Classes/LinphoneUI/UIChatBubbleTextCell.m +++ b/Classes/LinphoneUI/UIChatBubbleTextCell.m @@ -128,7 +128,7 @@ _statusInProgressSpinner.accessibilityLabel = @"Delivery in progress"; - if (_messageText) { + if (_messageText && ![LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:_message]) { LOGD(_messageText.text); [_messageText setHidden:FALSE]; /* We need to use an attributed string here so that data detector don't mess @@ -207,6 +207,36 @@ [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; } +- (void)getIcloudFiles { + _documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[@"public.data"] + inMode:UIDocumentPickerModeImport]; + _documentPicker.delegate = self; + + _documentPicker.modalPresentationStyle = UIModalPresentationOverCurrentContext ; + ChatConversationView *view = VIEW(ChatConversationView); + [view presentViewController:_documentPicker animated:YES completion:nil]; + } + + - (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url { + NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil]; + [fileCoordinator coordinateReadingItemAtURL:url options:NSFileCoordinatorReadingWithoutChanges error:nil byAccessor:^(NSURL * _Nonnull newURL) { + + NSString *fileName = [newURL lastPathComponent]; + NSData *data = [NSData dataWithContentsOfURL:newURL]; + NSString *option = [LinphoneManager getMessageAppDataForKey:@"icloudFileOption" inMessage:self.message]; + + if ([option isEqualToString:@"onResend"]) + [_chatRoomDelegate startFileUpload:data withName:fileName]; + else if ([option isEqualToString:@"onFileClick"]) { + ChatConversationView *view = VIEW(ChatConversationView); + NSString *filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:fileName]; + [[NSFileManager defaultManager] createFileAtPath:filePath contents:data attributes:nil]; + [view openFile:filePath]; + } + }]; +} + + #pragma mark - Action Functions - (void)onDelete { @@ -235,10 +265,8 @@ if (linphone_chat_message_get_file_transfer_information(_message) != NULL) { NSString *localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:_message]; NSNumber *uploadQuality =[LinphoneManager getMessageAppDataForKey:@"uploadQuality" inMessage:_message]; - - // TODO: do resend for video and files - /*NSString *localVideo = [LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:_message]; - NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:_message];*/ + NSString *localVideo = [LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:_message]; + NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:_message]; [self onDelete]; if(localImage){ @@ -254,6 +282,9 @@ if (![assets firstObject]) return; PHAsset *asset = [assets firstObject]; + if (asset.mediaType != PHAssetMediaTypeImage) + return; + PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; options.synchronous = TRUE; [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeDefault options:options @@ -268,10 +299,36 @@ } }]; } - } /*else if(fileName) { - NSString *filePath = [LinphoneManager documentFile:fileName]; - [_chatRoomDelegate startFileUpload:[NSData dataWithContentsOfFile:filePath] withUrl:[NSURL URLWithString:filePath]]; - }*/ + } else if (localVideo) { + PHFetchResult *assets = [PHAsset fetchAssetsWithLocalIdentifiers:[NSArray arrayWithObject:localVideo] options:nil]; + if (![assets firstObject]) + return; + PHAsset *asset = [assets firstObject]; + if (asset.mediaType != PHAssetMediaTypeVideo) + return; + + PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init]; + options.version = PHImageRequestOptionsVersionCurrent; + options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic; + + [[PHImageManager defaultManager] requestAVAssetForVideo:asset options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) { + AVURLAsset *urlAsset = (AVURLAsset *)asset; + + NSURL *url = urlAsset.URL; + NSData *data = [NSData dataWithContentsOfURL:url]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), + ^(void) { + [_chatRoomDelegate startFileUpload:data assetId:localVideo]; + }); + }]; + + } else if (localFile) { + [LinphoneManager setValueInMessageAppData:@"onResend" forKey:@"icloudFileOption" inMessage:_message]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), + ^(void) { + [self getIcloudFiles]; + }); + } } else { [self onDelete]; double delayInSeconds = 0.4; From a76cbad1fe2287a40dc5aa1d22a32d11512b43bb Mon Sep 17 00:00:00 2001 From: Danmei Chen Date: Thu, 30 Aug 2018 10:23:17 +0200 Subject: [PATCH 4/9] send images with text content --- Classes/Utils/FileTransferDelegate.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/Utils/FileTransferDelegate.m b/Classes/Utils/FileTransferDelegate.m index 4b2fd6915..08d1b4d20 100644 --- a/Classes/Utils/FileTransferDelegate.m +++ b/Classes/Utils/FileTransferDelegate.m @@ -263,7 +263,7 @@ static LinphoneBuffer *linphone_iphone_file_transfer_send(LinphoneChatMessage *m linphone_content_set_name(content, [name UTF8String]); linphone_content_set_size(content, _data.length); _message = linphone_chat_room_create_file_transfer_message(chatRoom, content); - //linphone_chat_message_add_text_content(_message, [_text UTF8String]); + linphone_chat_message_add_text_content(_message, [_text UTF8String]); linphone_content_unref(content); linphone_chat_message_cbs_set_file_transfer_send(linphone_chat_message_get_callbacks(_message), From 859c4fea29f46b9cb3f3787db8221ae675f4b7c4 Mon Sep 17 00:00:00 2001 From: Danmei Chen Date: Thu, 4 Oct 2018 11:57:17 +0200 Subject: [PATCH 5/9] fix: save photo in the photo library the first time --- Classes/Utils/FileTransferDelegate.m | 264 ++++++++++++++------------- 1 file changed, 141 insertions(+), 123 deletions(-) diff --git a/Classes/Utils/FileTransferDelegate.m b/Classes/Utils/FileTransferDelegate.m index 08d1b4d20..58b716950 100644 --- a/Classes/Utils/FileTransferDelegate.m +++ b/Classes/Utils/FileTransferDelegate.m @@ -45,130 +45,148 @@ static void linphone_iphone_file_transfer_recv(LinphoneChatMessage *message, con LOGI(@"Transfer of %s (%d bytes): download finished", linphone_content_get_name(content), size); assert([thiz.data length] == linphone_content_get_file_size(content)); NSString *fileType = [NSString stringWithUTF8String:linphone_content_get_type(content)]; - if ([fileType isEqualToString:@"image"]) { - // we're finished, save the image and update the message - UIImage *image = [UIImage imageWithData:thiz.data]; - if (!image) { - UIAlertController *errView = [UIAlertController - alertControllerWithTitle:NSLocalizedString(@"File download error", nil) - message:NSLocalizedString(@"Error while downloading the file.\n" - @"The file is probably encrypted.\n" - @"Please retry to download this file after activating LIME.", - nil) - preferredStyle:UIAlertControllerStyleAlert]; - - UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK" - style:UIAlertActionStyleDefault - handler:^(UIAlertAction *action){ - }]; - - [errView addAction:defaultAction]; - [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; - [thiz stopAndDestroy]; - return; + + void (^block)(void)= ^ { + if ([fileType isEqualToString:@"image"]) { + // we're finished, save the image and update the message + UIImage *image = [UIImage imageWithData:thiz.data]; + if (!image) { + UIAlertController *errView = [UIAlertController + alertControllerWithTitle:NSLocalizedString(@"File download error", nil) + message:NSLocalizedString(@"Error while downloading the file.\n" + @"The file is probably encrypted.\n" + @"Please retry to download this file after activating LIME.", + nil) + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action){ + }]; + + [errView addAction:defaultAction]; + [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; + [thiz stopAndDestroy]; + return; + } + + CFBridgingRetain(thiz); + [[LinphoneManager.instance fileTransferDelegates] removeObject:thiz]; + + // until image is properly saved, keep a reminder on it so that the + // chat bubble is aware of the fact that image is being saved to device + [LinphoneManager setValueInMessageAppData:@"saving..." forKey:@"localimage" inMessage:message]; + __block PHObjectPlaceholder *placeHolder; + [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ + PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromImage:image]; + placeHolder = [request placeholderForCreatedAsset]; + } completionHandler:^(BOOL success, NSError *error) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (error) { + LOGE(@"Cannot save image data downloaded [%@]", [error localizedDescription]); + [LinphoneManager setValueInMessageAppData:nil forKey:@"localimage" inMessage:message]; + UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Transfer error", nil) + message:NSLocalizedString(@"Cannot write image to photo library", + nil) + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) {}]; + + [errView addAction:defaultAction]; + [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; + } else { + LOGI(@"Image saved to [%@]", [placeHolder localIdentifier]); + [LinphoneManager setValueInMessageAppData:[placeHolder localIdentifier] + forKey:@"localimage" + inMessage:message]; + } + [NSNotificationCenter.defaultCenter + postNotificationName:kLinphoneFileTransferRecvUpdate + object:thiz + userInfo:@{ + @"state" : @(LinphoneChatMessageStateDelivered), // we dont want to + // trigger + // FileTransferDone here + @"image" : image, + @"progress" : @(1.f), + }]; + + [thiz stopAndDestroy]; + CFRelease((__bridge CFTypeRef)thiz); + }); + }]; + } else if([fileType isEqualToString:@"video"]) { + CFBridgingRetain(thiz); + [[LinphoneManager.instance fileTransferDelegates] removeObject:thiz]; + NSString *name =[NSString stringWithUTF8String:linphone_content_get_name(content)]; + NSString *filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]; + [[NSFileManager defaultManager] createFileAtPath:filePath + contents:thiz.data + attributes:nil]; + // until image is properly saved, keep a reminder on it so that the + // chat bubble is aware of the fact that image is being saved to device + [LinphoneManager setValueInMessageAppData:@"saving..." forKey:@"localvideo" inMessage:message]; + + __block PHObjectPlaceholder *placeHolder; + [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ + PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromVideoAtFileURL:[NSURL fileURLWithPath:filePath]]; + placeHolder = [request placeholderForCreatedAsset]; + } completionHandler:^(BOOL success, NSError * _Nullable error) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (error) { + LOGE(@"Cannot save video data downloaded [%@]", [error localizedDescription]); + [LinphoneManager setValueInMessageAppData:nil forKey:@"localvideo" inMessage:message]; + UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Transfer error", nil) + message:NSLocalizedString(@"Cannot write video to photo library", + nil) + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) {}]; + + [errView addAction:defaultAction]; + [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; + } else { + LOGI(@"video saved to [%@]", [placeHolder localIdentifier]); + [LinphoneManager setValueInMessageAppData:[placeHolder localIdentifier] + forKey:@"localvideo" + inMessage:message]; + } + [NSNotificationCenter.defaultCenter + postNotificationName:kLinphoneFileTransferRecvUpdate + object:thiz + userInfo:@{ + @"state" : @(LinphoneChatMessageStateDelivered), // we dont want to + // trigger + // FileTransferDone here + @"progress" : @(1.f), + }]; + + [thiz stopAndDestroy]; + CFRelease((__bridge CFTypeRef)thiz); + }); + }]; + } + }; + // When you save an image or video to a photo library, make sure that it is allowed. Otherwise, there will be a backup error. + if ([fileType isEqualToString:@"image"] || [fileType isEqualToString:@"video"]) { + if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { + block(); + } else { + [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { + dispatch_async(dispatch_get_main_queue(), ^{ + if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { + block(); + } else { + [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Photo's permission", nil) message:NSLocalizedString(@"Photo not authorized", nil) delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Continue", nil] show]; + [thiz stopAndDestroy]; + } + }); + }]; } - - CFBridgingRetain(thiz); - [[LinphoneManager.instance fileTransferDelegates] removeObject:thiz]; - - // until image is properly saved, keep a reminder on it so that the - // chat bubble is aware of the fact that image is being saved to device - [LinphoneManager setValueInMessageAppData:@"saving..." forKey:@"localimage" inMessage:message]; - - __block PHObjectPlaceholder *placeHolder; - [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ - PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromImage:image]; - placeHolder = [request placeholderForCreatedAsset]; - } completionHandler:^(BOOL success, NSError *error) { - dispatch_async(dispatch_get_main_queue(), ^{ - if (error) { - LOGE(@"Cannot save image data downloaded [%@]", [error localizedDescription]); - [LinphoneManager setValueInMessageAppData:nil forKey:@"localimage" inMessage:message]; - UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Transfer error", nil) - message:NSLocalizedString(@"Cannot write image to photo library", - nil) - preferredStyle:UIAlertControllerStyleAlert]; - - UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) {}]; - - [errView addAction:defaultAction]; - [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; - } else { - LOGI(@"Image saved to [%@]", [placeHolder localIdentifier]); - [LinphoneManager setValueInMessageAppData:[placeHolder localIdentifier] - forKey:@"localimage" - inMessage:message]; - } - [NSNotificationCenter.defaultCenter - postNotificationName:kLinphoneFileTransferRecvUpdate - object:thiz - userInfo:@{ - @"state" : @(LinphoneChatMessageStateDelivered), // we dont want to - // trigger - // FileTransferDone here - @"image" : image, - @"progress" : @(1.f), - }]; - - [thiz stopAndDestroy]; - CFRelease((__bridge CFTypeRef)thiz); - }); - }]; - } else if([fileType isEqualToString:@"video"]) { - CFBridgingRetain(thiz); - [[LinphoneManager.instance fileTransferDelegates] removeObject:thiz]; - NSString *name =[NSString stringWithUTF8String:linphone_content_get_name(content)]; - NSString *filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]; - [[NSFileManager defaultManager] createFileAtPath:filePath - contents:thiz.data - attributes:nil]; - // until image is properly saved, keep a reminder on it so that the - // chat bubble is aware of the fact that image is being saved to device - [LinphoneManager setValueInMessageAppData:@"saving..." forKey:@"localvideo" inMessage:message]; - - __block PHObjectPlaceholder *placeHolder; - [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ - PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromVideoAtFileURL:[NSURL fileURLWithPath:filePath]]; - placeHolder = [request placeholderForCreatedAsset]; - } completionHandler:^(BOOL success, NSError * _Nullable error) { - dispatch_async(dispatch_get_main_queue(), ^{ - if (error) { - LOGE(@"Cannot save video data downloaded [%@]", [error localizedDescription]); - [LinphoneManager setValueInMessageAppData:nil forKey:@"localvideo" inMessage:message]; - UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Transfer error", nil) - message:NSLocalizedString(@"Cannot write video to photo library", - nil) - preferredStyle:UIAlertControllerStyleAlert]; - - UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) {}]; - - [errView addAction:defaultAction]; - [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; - } else { - LOGI(@"video saved to [%@]", [placeHolder localIdentifier]); - [LinphoneManager setValueInMessageAppData:[placeHolder localIdentifier] - forKey:@"localvideo" - inMessage:message]; - } - [NSNotificationCenter.defaultCenter - postNotificationName:kLinphoneFileTransferRecvUpdate - object:thiz - userInfo:@{ - @"state" : @(LinphoneChatMessageStateDelivered), // we dont want to - // trigger - // FileTransferDone here - @"progress" : @(1.f), - }]; - - [thiz stopAndDestroy]; - CFRelease((__bridge CFTypeRef)thiz); - }); - }]; - } else { [[LinphoneManager.instance fileTransferDelegates] removeObject:thiz]; NSString *key = @"localfile" ; From c8c40003d616faad8f2519028d77b77da9023d75 Mon Sep 17 00:00:00 2001 From: Danmei Chen Date: Fri, 5 Oct 2018 15:50:26 +0200 Subject: [PATCH 6/9] fix crash when chosse photo from camera --- Classes/ImagePickerView.m | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Classes/ImagePickerView.m b/Classes/ImagePickerView.m index fdf5f602c..f5a0cc62f 100644 --- a/Classes/ImagePickerView.m +++ b/Classes/ImagePickerView.m @@ -163,9 +163,13 @@ static UICompositeViewDescription *compositeDescription = nil; [self dismiss]; NSURL *alassetURL = [info objectForKey:UIImagePickerControllerReferenceURL]; - PHFetchResult *phFetchResult = [PHAsset fetchAssetsWithALAssetURLs:@[alassetURL] options:nil]; - PHAsset *phasset = [phFetchResult firstObject]; - //PHAsset *phasset = [info objectForKey:UIImagePickerControllerPHAsset]; + PHAsset *phasset = nil; + // when photo from camera, it hasn't be saved + if (alassetURL) { + PHFetchResult *phFetchResult = [PHAsset fetchAssetsWithALAssetURLs:@[alassetURL] options:nil]; + phasset = [phFetchResult firstObject]; + } + UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage] ? [info objectForKey:UIImagePickerControllerEditedImage] : [info objectForKey:UIImagePickerControllerOriginalImage]; if (!phasset) { __block PHObjectPlaceholder *placeHolder; From 3f7728797d2b9dcd6e4a65676f04a598c165e302 Mon Sep 17 00:00:00 2001 From: Danmei Chen Date: Fri, 5 Oct 2018 16:22:46 +0200 Subject: [PATCH 7/9] fix share file not from icloud --- linphoneExtension/ShareViewController.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linphoneExtension/ShareViewController.m b/linphoneExtension/ShareViewController.m index 1f656a9bc..788ac49af 100644 --- a/linphoneExtension/ShareViewController.m +++ b/linphoneExtension/ShareViewController.m @@ -77,12 +77,12 @@ static NSString* groupName = @"group.belledonne-communications.linphone"; NSDictionary *dict = @{@"nsData" : nsData, @"url" : filename}; [defaults setObject:dict forKey:@"photoData"]; - } else if ([imgPath containsString:@"var/mobile/Library/Mobile Documents/com~apple~CloudDocs"]) { + } else if ([imgPath containsString:@"var/mobile/Library/Mobile Documents/com~apple~CloudDocs"] || [[url scheme] isEqualToString:@"file"]) { // shared files from icloud drive NSDictionary *dict = @{@"nsData" : nsData, @"url" : filename}; [defaults setObject:dict forKey:@"icloudData"]; - }else { + } else { //Others NSDictionary *dict = @{@"url" : [url absoluteString]}; [defaults setObject:dict forKey:@"url"]; From 34abdb7e7ce1ad50e9c458f4079ec31e1e535eef Mon Sep 17 00:00:00 2001 From: Danmei Chen Date: Mon, 8 Oct 2018 14:56:41 +0200 Subject: [PATCH 8/9] Revert "send images with text content" This reverts commit a76cbad1fe2287a40dc5aa1d22a32d11512b43bb. --- Classes/Utils/FileTransferDelegate.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/Utils/FileTransferDelegate.m b/Classes/Utils/FileTransferDelegate.m index 58b716950..33bfcfa2c 100644 --- a/Classes/Utils/FileTransferDelegate.m +++ b/Classes/Utils/FileTransferDelegate.m @@ -281,7 +281,7 @@ static LinphoneBuffer *linphone_iphone_file_transfer_send(LinphoneChatMessage *m linphone_content_set_name(content, [name UTF8String]); linphone_content_set_size(content, _data.length); _message = linphone_chat_room_create_file_transfer_message(chatRoom, content); - linphone_chat_message_add_text_content(_message, [_text UTF8String]); + //linphone_chat_message_add_text_content(_message, [_text UTF8String]); linphone_content_unref(content); linphone_chat_message_cbs_set_file_transfer_send(linphone_chat_message_get_callbacks(_message), From 3bf495343bb9ccbd56f4a08403c7ef63a5c12683 Mon Sep 17 00:00:00 2001 From: Danmei Chen Date: Mon, 8 Oct 2018 15:03:25 +0200 Subject: [PATCH 9/9] Revert "fix: save photo in the photo library the first time" This reverts commit 859c4fea29f46b9cb3f3787db8221ae675f4b7c4. --- Classes/Utils/FileTransferDelegate.m | 258 +++++++++++++-------------- 1 file changed, 120 insertions(+), 138 deletions(-) diff --git a/Classes/Utils/FileTransferDelegate.m b/Classes/Utils/FileTransferDelegate.m index 33bfcfa2c..4b2fd6915 100644 --- a/Classes/Utils/FileTransferDelegate.m +++ b/Classes/Utils/FileTransferDelegate.m @@ -45,148 +45,130 @@ static void linphone_iphone_file_transfer_recv(LinphoneChatMessage *message, con LOGI(@"Transfer of %s (%d bytes): download finished", linphone_content_get_name(content), size); assert([thiz.data length] == linphone_content_get_file_size(content)); NSString *fileType = [NSString stringWithUTF8String:linphone_content_get_type(content)]; - - void (^block)(void)= ^ { - if ([fileType isEqualToString:@"image"]) { - // we're finished, save the image and update the message - UIImage *image = [UIImage imageWithData:thiz.data]; - if (!image) { - UIAlertController *errView = [UIAlertController - alertControllerWithTitle:NSLocalizedString(@"File download error", nil) - message:NSLocalizedString(@"Error while downloading the file.\n" - @"The file is probably encrypted.\n" - @"Please retry to download this file after activating LIME.", - nil) - preferredStyle:UIAlertControllerStyleAlert]; + if ([fileType isEqualToString:@"image"]) { + // we're finished, save the image and update the message + UIImage *image = [UIImage imageWithData:thiz.data]; + if (!image) { + UIAlertController *errView = [UIAlertController + alertControllerWithTitle:NSLocalizedString(@"File download error", nil) + message:NSLocalizedString(@"Error while downloading the file.\n" + @"The file is probably encrypted.\n" + @"Please retry to download this file after activating LIME.", + nil) + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction *action){ + }]; + + [errView addAction:defaultAction]; + [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; + [thiz stopAndDestroy]; + return; + } + + CFBridgingRetain(thiz); + [[LinphoneManager.instance fileTransferDelegates] removeObject:thiz]; + + // until image is properly saved, keep a reminder on it so that the + // chat bubble is aware of the fact that image is being saved to device + [LinphoneManager setValueInMessageAppData:@"saving..." forKey:@"localimage" inMessage:message]; + + __block PHObjectPlaceholder *placeHolder; + [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ + PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromImage:image]; + placeHolder = [request placeholderForCreatedAsset]; + } completionHandler:^(BOOL success, NSError *error) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (error) { + LOGE(@"Cannot save image data downloaded [%@]", [error localizedDescription]); + [LinphoneManager setValueInMessageAppData:nil forKey:@"localimage" inMessage:message]; + UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Transfer error", nil) + message:NSLocalizedString(@"Cannot write image to photo library", + nil) + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) {}]; + + [errView addAction:defaultAction]; + [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; + } else { + LOGI(@"Image saved to [%@]", [placeHolder localIdentifier]); + [LinphoneManager setValueInMessageAppData:[placeHolder localIdentifier] + forKey:@"localimage" + inMessage:message]; + } + [NSNotificationCenter.defaultCenter + postNotificationName:kLinphoneFileTransferRecvUpdate + object:thiz + userInfo:@{ + @"state" : @(LinphoneChatMessageStateDelivered), // we dont want to + // trigger + // FileTransferDone here + @"image" : image, + @"progress" : @(1.f), + }]; - UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK" - style:UIAlertActionStyleDefault - handler:^(UIAlertAction *action){ - }]; - - [errView addAction:defaultAction]; - [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; [thiz stopAndDestroy]; - return; - } - - CFBridgingRetain(thiz); - [[LinphoneManager.instance fileTransferDelegates] removeObject:thiz]; - - // until image is properly saved, keep a reminder on it so that the - // chat bubble is aware of the fact that image is being saved to device - [LinphoneManager setValueInMessageAppData:@"saving..." forKey:@"localimage" inMessage:message]; - __block PHObjectPlaceholder *placeHolder; - [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ - PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromImage:image]; - placeHolder = [request placeholderForCreatedAsset]; - } completionHandler:^(BOOL success, NSError *error) { - dispatch_async(dispatch_get_main_queue(), ^{ - if (error) { - LOGE(@"Cannot save image data downloaded [%@]", [error localizedDescription]); - [LinphoneManager setValueInMessageAppData:nil forKey:@"localimage" inMessage:message]; - UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Transfer error", nil) - message:NSLocalizedString(@"Cannot write image to photo library", - nil) - preferredStyle:UIAlertControllerStyleAlert]; - - UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) {}]; - - [errView addAction:defaultAction]; - [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; - } else { - LOGI(@"Image saved to [%@]", [placeHolder localIdentifier]); - [LinphoneManager setValueInMessageAppData:[placeHolder localIdentifier] - forKey:@"localimage" - inMessage:message]; - } - [NSNotificationCenter.defaultCenter - postNotificationName:kLinphoneFileTransferRecvUpdate - object:thiz - userInfo:@{ - @"state" : @(LinphoneChatMessageStateDelivered), // we dont want to - // trigger - // FileTransferDone here - @"image" : image, - @"progress" : @(1.f), - }]; + CFRelease((__bridge CFTypeRef)thiz); + }); + }]; + } else if([fileType isEqualToString:@"video"]) { + CFBridgingRetain(thiz); + [[LinphoneManager.instance fileTransferDelegates] removeObject:thiz]; + NSString *name =[NSString stringWithUTF8String:linphone_content_get_name(content)]; + NSString *filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]; + [[NSFileManager defaultManager] createFileAtPath:filePath + contents:thiz.data + attributes:nil]; + // until image is properly saved, keep a reminder on it so that the + // chat bubble is aware of the fact that image is being saved to device + [LinphoneManager setValueInMessageAppData:@"saving..." forKey:@"localvideo" inMessage:message]; + + __block PHObjectPlaceholder *placeHolder; + [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ + PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromVideoAtFileURL:[NSURL fileURLWithPath:filePath]]; + placeHolder = [request placeholderForCreatedAsset]; + } completionHandler:^(BOOL success, NSError * _Nullable error) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (error) { + LOGE(@"Cannot save video data downloaded [%@]", [error localizedDescription]); + [LinphoneManager setValueInMessageAppData:nil forKey:@"localvideo" inMessage:message]; + UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Transfer error", nil) + message:NSLocalizedString(@"Cannot write video to photo library", + nil) + preferredStyle:UIAlertControllerStyleAlert]; - [thiz stopAndDestroy]; - CFRelease((__bridge CFTypeRef)thiz); - }); - }]; - } else if([fileType isEqualToString:@"video"]) { - CFBridgingRetain(thiz); - [[LinphoneManager.instance fileTransferDelegates] removeObject:thiz]; - NSString *name =[NSString stringWithUTF8String:linphone_content_get_name(content)]; - NSString *filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]; - [[NSFileManager defaultManager] createFileAtPath:filePath - contents:thiz.data - attributes:nil]; - // until image is properly saved, keep a reminder on it so that the - // chat bubble is aware of the fact that image is being saved to device - [LinphoneManager setValueInMessageAppData:@"saving..." forKey:@"localvideo" inMessage:message]; - - __block PHObjectPlaceholder *placeHolder; - [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ - PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromVideoAtFileURL:[NSURL fileURLWithPath:filePath]]; - placeHolder = [request placeholderForCreatedAsset]; - } completionHandler:^(BOOL success, NSError * _Nullable error) { - dispatch_async(dispatch_get_main_queue(), ^{ - if (error) { - LOGE(@"Cannot save video data downloaded [%@]", [error localizedDescription]); - [LinphoneManager setValueInMessageAppData:nil forKey:@"localvideo" inMessage:message]; - UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Transfer error", nil) - message:NSLocalizedString(@"Cannot write video to photo library", - nil) - preferredStyle:UIAlertControllerStyleAlert]; - - UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) {}]; - - [errView addAction:defaultAction]; - [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; - } else { - LOGI(@"video saved to [%@]", [placeHolder localIdentifier]); - [LinphoneManager setValueInMessageAppData:[placeHolder localIdentifier] - forKey:@"localvideo" - inMessage:message]; - } - [NSNotificationCenter.defaultCenter - postNotificationName:kLinphoneFileTransferRecvUpdate - object:thiz - userInfo:@{ - @"state" : @(LinphoneChatMessageStateDelivered), // we dont want to - // trigger - // FileTransferDone here - @"progress" : @(1.f), - }]; + UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) {}]; - [thiz stopAndDestroy]; - CFRelease((__bridge CFTypeRef)thiz); - }); - }]; - } - }; - // When you save an image or video to a photo library, make sure that it is allowed. Otherwise, there will be a backup error. - if ([fileType isEqualToString:@"image"] || [fileType isEqualToString:@"video"]) { - if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { - block(); - } else { - [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { - dispatch_async(dispatch_get_main_queue(), ^{ - if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) { - block(); - } else { - [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Photo's permission", nil) message:NSLocalizedString(@"Photo not authorized", nil) delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Continue", nil] show]; - [thiz stopAndDestroy]; - } - }); - }]; - } + [errView addAction:defaultAction]; + [PhoneMainView.instance presentViewController:errView animated:YES completion:nil]; + } else { + LOGI(@"video saved to [%@]", [placeHolder localIdentifier]); + [LinphoneManager setValueInMessageAppData:[placeHolder localIdentifier] + forKey:@"localvideo" + inMessage:message]; + } + [NSNotificationCenter.defaultCenter + postNotificationName:kLinphoneFileTransferRecvUpdate + object:thiz + userInfo:@{ + @"state" : @(LinphoneChatMessageStateDelivered), // we dont want to + // trigger + // FileTransferDone here + @"progress" : @(1.f), + }]; + + [thiz stopAndDestroy]; + CFRelease((__bridge CFTypeRef)thiz); + }); + }]; + } else { [[LinphoneManager.instance fileTransferDelegates] removeObject:thiz]; NSString *key = @"localfile" ;