From 70a85bcaa743b8e1e99d7a19b7ec6803b2e190c0 Mon Sep 17 00:00:00 2001 From: Christophe Deschamps Date: Fri, 21 Oct 2022 09:44:52 +0200 Subject: [PATCH] Set unique file name per message to avoid local display conflicts --- Classes/ChatConversationView.m | 2 +- Classes/LinphoneUI/UIChatBubblePhotoCell.m | 6 +- Classes/Swift/FileUtil.swift | 128 +++++++++++++++++++++ linphone.xcodeproj/project.pbxproj | 4 + 4 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 Classes/Swift/FileUtil.swift diff --git a/Classes/ChatConversationView.m b/Classes/ChatConversationView.m index 74b193ef9..776caff95 100644 --- a/Classes/ChatConversationView.m +++ b/Classes/ChatConversationView.m @@ -468,7 +468,7 @@ static UICompositeViewDescription *compositeDescription = nil; //file shared from photo lib NSString *fileName = dict[@"url"]; [_messageField setText:dict[@"message"]]; - [self confirmShare:[self nsDataRead] url:nil fileName:fileName]; + [self confirmShare:[self nsDataRead] url:nil fileName:fileName]; [defaults removeObjectForKey:@"photoData"]; } else if (dictFile) { NSString *fileName = dictFile[@"url"]; diff --git a/Classes/LinphoneUI/UIChatBubblePhotoCell.m b/Classes/LinphoneUI/UIChatBubblePhotoCell.m index 2371ad7b2..29e7554f5 100644 --- a/Classes/LinphoneUI/UIChatBubblePhotoCell.m +++ b/Classes/LinphoneUI/UIChatBubblePhotoCell.m @@ -234,7 +234,8 @@ if (strcmp(cPath, "") != 0) { NSString *tempPath = [NSString stringWithUTF8String:cPath]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); - filePath = [paths objectAtIndex:0]; + filePath = [NSString stringWithFormat:@"%@/%s", [paths objectAtIndex:0],linphone_chat_message_get_message_id(super.message)]; + [FileUtil ensureDirectoryExistsWithPath:filePath]; filePath = [filePath stringByAppendingPathComponent:name]; [[NSFileManager defaultManager] moveItemAtPath:tempPath toPath:filePath error:nil]; } @@ -300,7 +301,8 @@ if (strcmp(cPath, "") != 0) { NSString *tempPath = [NSString stringWithUTF8String:cPath]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); - filePath = [paths objectAtIndex:0]; + filePath = [NSString stringWithFormat:@"%@/%s", [paths objectAtIndex:0],linphone_chat_message_get_message_id(super.message)]; + [FileUtil ensureDirectoryExistsWithPath:filePath]; filePath = [filePath stringByAppendingPathComponent:fileName]; [[NSFileManager defaultManager] moveItemAtPath:tempPath toPath:filePath error:nil]; } diff --git a/Classes/Swift/FileUtil.swift b/Classes/Swift/FileUtil.swift new file mode 100644 index 000000000..5f0d18d46 --- /dev/null +++ b/Classes/Swift/FileUtil.swift @@ -0,0 +1,128 @@ +// +// FileUtils.swift +// Linhome +// +// Created by Christophe Deschamps on 24/02/2020. +// Copyright © 2020 Belledonne communications. All rights reserved. +// + +import UIKit +import linphonesw + +@objc class FileUtil: NSObject { + public class func bundleFilePath(_ file: NSString) -> String? { + return Bundle.main.path(forResource: file.deletingPathExtension, ofType: file.pathExtension) + } + + public class func bundleFilePathAsUrl(_ file: NSString) -> URL? { + if let bPath = bundleFilePath(file) { + return URL.init(fileURLWithPath: bPath) + } + return nil + } + + public class func documentsDirectory() -> URL { + let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) + let documentsDirectory = paths[0] + return documentsDirectory + } + + public class func libraryDirectory() -> URL { + let paths = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask) + let documentsDirectory = paths[0] + return documentsDirectory + } + + public class func sharedContainerUrl(appGroupName:String) -> URL { + return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupName)! + } + + + @objc public class func ensureDirectoryExists(path:String) { + if !FileManager.default.fileExists(atPath: path) { + do { + try FileManager.default.createDirectory(atPath: path, withIntermediateDirectories: true, attributes: nil) + } catch { + print(error) + } + } + } + + public class func ensureFileExists(path:String) { + if !FileManager.default.fileExists(atPath: path) { + FileManager.default.createFile(atPath: path, contents: nil, attributes: nil) + } + } + + public class func fileExists(path:String) -> Bool { + return FileManager.default.fileExists(atPath: path) + } + + public class func fileExistsAndIsNotEmpty(path:String) -> Bool { + guard FileManager.default.fileExists(atPath: path) else {return false} + do { + let attribute = try FileManager.default.attributesOfItem(atPath: path) + if let size = attribute[FileAttributeKey.size] as? NSNumber { + return size.doubleValue > 0 + } else { + return false + } + } catch { + print(error) + return false + } + } + + public class func write(string:String, toPath:String) { + do { + try string.write(to: URL(fileURLWithPath:toPath), atomically: true, encoding: String.Encoding.utf8) + } catch { + print(error) + } + } + + public class func delete(path:String) { + do { + try FileManager.default.removeItem(atPath: path) + print("FIle \(path) was removed") + } catch { + print("Error deleting file at path \(path) error is \(error)") + } + } + + public class func mkdir(path:String) { + do { + try FileManager.default.createDirectory(atPath: path, withIntermediateDirectories: true, attributes: nil) + print("Dir \(path) was created") + } catch { + print("Error creating dir at path \(path) error is \(error)") + } + } + + + + public class func copy(_ fromPath:String, _ toPath: String, overWrite:Bool) { + do { + if (overWrite && fileExists(path: toPath)) { + delete(path: toPath) + } + try FileManager.default.copyItem(at: URL(fileURLWithPath:fromPath), to: URL(fileURLWithPath:toPath)) + } catch { + print(error) + } + } + + + // For debugging + + public class func showListOfFilesInSharedDir(appGroupName:String) { + let fileManager = FileManager.default + do { + let fileURLs = try fileManager.contentsOfDirectory(at: FileUtil.sharedContainerUrl(appGroupName: appGroupName), includingPropertiesForKeys: nil) + fileURLs.forEach{print($0)} + } catch { + print("Error while enumerating files \(error.localizedDescription)") + } + } + +} diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index 3897a10fa..03b081795 100644 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -674,6 +674,7 @@ C622E3F226A81290004F5434 /* vr_off.png in Resources */ = {isa = PBXBuildFile; fileRef = C622E3EC26A8128F004F5434 /* vr_off.png */; }; C622E3F326A81290004F5434 /* vr_pause.png in Resources */ = {isa = PBXBuildFile; fileRef = C622E3ED26A8128F004F5434 /* vr_pause.png */; }; C622E3F426A81290004F5434 /* vr_play.png in Resources */ = {isa = PBXBuildFile; fileRef = C622E3EE26A81290004F5434 /* vr_play.png */; }; + C63D2F1529029536008F0F66 /* FileUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = C63D2F1429029536008F0F66 /* FileUtil.swift */; }; C63F720D285A24B10066163B /* ConfigManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C63F7197285A24B10066163B /* ConfigManager.swift */; }; C63F720E285A24B10066163B /* CallManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C63F7198285A24B10066163B /* CallManager.swift */; }; C63F720F285A24B10066163B /* ConferenceWaitingRoomViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C63F719B285A24B10066163B /* ConferenceWaitingRoomViewModel.swift */; }; @@ -1879,6 +1880,7 @@ C622E3EC26A8128F004F5434 /* vr_off.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vr_off.png; sourceTree = ""; }; C622E3ED26A8128F004F5434 /* vr_pause.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vr_pause.png; sourceTree = ""; }; C622E3EE26A81290004F5434 /* vr_play.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = vr_play.png; sourceTree = ""; }; + C63D2F1429029536008F0F66 /* FileUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileUtil.swift; sourceTree = ""; }; C63F7197285A24B10066163B /* ConfigManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigManager.swift; sourceTree = ""; }; C63F7198285A24B10066163B /* CallManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallManager.swift; sourceTree = ""; }; C63F719B285A24B10066163B /* ConferenceWaitingRoomViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConferenceWaitingRoomViewModel.swift; sourceTree = ""; }; @@ -3451,6 +3453,7 @@ C63F7196285A24B10066163B /* Swift */ = { isa = PBXGroup; children = ( + C63D2F1429029536008F0F66 /* FileUtil.swift */, C6B4444726AADA530076C517 /* SwiftUtil.swift */, C63F7197285A24B10066163B /* ConfigManager.swift */, C63F7198285A24B10066163B /* CallManager.swift */, @@ -5355,6 +5358,7 @@ C63F7229285A24B10066163B /* UIButtonExtensions.swift in Sources */, C63F722B285A24B10066163B /* UIDeviceExtensions.swift in Sources */, C63F724B285A24B10066163B /* VoipConferenceDisplayModeSelectionView.swift in Sources */, + C63D2F1529029536008F0F66 /* FileUtil.swift in Sources */, CF7602E221086EB200749F76 /* RecordingsListTableView.m in Sources */, C63F721E285A24B10066163B /* Pair.swift in Sources */, D3807FC515C28940005BE9BC /* DCRoundSwitchToggleLayer.m in Sources */,