diff options
author | Joris Bodin <joris.bodin@infomaniak.com> | 2019-10-23 18:18:25 +0300 |
---|---|---|
committer | Joris Bodin <joris.bodin@infomaniak.com> | 2019-10-23 18:18:25 +0300 |
commit | 8c6eac13fec695452b67b69899f3f7b4431d50e0 (patch) | |
tree | 12e9d37094d2ae5b18047cd7a699e7f8bb04bb46 | |
parent | 9fdea2b9aa55714a480059e9f6c71c911836a5d3 (diff) | |
parent | d5de66f94cec84d06ecc0c6675044656e7945881 (diff) |
Merge branch 'develop' into infomaniak (2.25.0 build 3 Beta)2.25.0.3
# Conflicts:
# kDrive.xcodeproj/project.pbxproj
# kDrive.xcodeproj/xcshareddata/xcschemes/kDrive.xcscheme
27 files changed, 764 insertions, 367 deletions
@@ -17,8 +17,10 @@ github "rechsteiner/Parchment" "v1.7.0" github "WenchaoD/FSCalendar" "2.8.0" github "AssistoLab/DropDown" "v2.3.13" github "krzyzanowskim/OpenSSL" "1.0.218" + github "Alamofire/Alamofire" "5.0.0-rc.2" github "https://github.com/yahoojapan/SwiftyXMLParser" +github "SwiftyJSON/SwiftyJSON" ~> 4.0 github "https://github.com/marinofaggiana/FastScroll" "master" github "https://github.com/marinofaggiana/AFNetworking" "master" diff --git a/Cartfile.resolved b/Cartfile.resolved index e877af467..37b4496f4 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -4,6 +4,7 @@ github "ChangbaDevs/KTVHTTPCache" "2.0.1" github "CocoaLumberjack/CocoaLumberjack" "3.6.0" github "MortimerGoro/MGSwipeTableCell" "1.6.8" github "SVGKit/SVGKit" "39dd210fd47e3195f57f914354ffd2d0b4b8ff1c" +github "SwiftyJSON/SwiftyJSON" "4.3.0" github "WeTransfer/WeScan" "v1.1.0" github "WenchaoD/FSCalendar" "2.8.0" github "calimarkus/JDStatusBarNotification" "1.6.0" diff --git a/File Provider Extension/FileProviderData.swift b/File Provider Extension/FileProviderData.swift index 28be6224c..9c527966f 100644 --- a/File Provider Extension/FileProviderData.swift +++ b/File Provider Extension/FileProviderData.swift @@ -76,7 +76,9 @@ class fileProviderData: NSObject { accountPassword = CCUtility.getPassword(tableAccounts.account) accountUrl = tableAccounts.url homeServerUrl = CCUtility.getHomeServerUrlActiveUrl(tableAccounts.url) - + + NCCommunication.init(username: accountUserID, password: accountPassword, userAgent: CCUtility.getUserAgent(), delegate: nil) + return true } @@ -96,6 +98,8 @@ class fileProviderData: NSObject { accountUrl = tableAccount.url homeServerUrl = CCUtility.getHomeServerUrlActiveUrl(tableAccount.url) + NCCommunication.init(username: accountUserID, password: accountPassword, userAgent: CCUtility.getUserAgent(), delegate: nil) + foundAccount = true } } @@ -121,6 +125,8 @@ class fileProviderData: NSObject { accountUrl = tableAccount.url homeServerUrl = CCUtility.getHomeServerUrlActiveUrl(tableAccount.url) + NCCommunication.init(username: accountUserID, password: accountPassword, userAgent: CCUtility.getUserAgent(), delegate: nil) + foundAccount = true } } diff --git a/File Provider Extension/FileProviderEnumerator.swift b/File Provider Extension/FileProviderEnumerator.swift index 559c096ed..b355d453d 100644 --- a/File Provider Extension/FileProviderEnumerator.swift +++ b/File Provider Extension/FileProviderEnumerator.swift @@ -125,70 +125,42 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator { // Update the WorkingSet -> Favorite fileProviderData.sharedInstance.updateFavoriteForWorkingSet() - // Read - var fileName: String? - var serverUrlForFileName = fileProviderData.sharedInstance.homeServerUrl - - if serverUrl != fileProviderData.sharedInstance.homeServerUrl { - fileName = (serverUrl as NSString).lastPathComponent - serverUrlForFileName = (serverUrl as NSString).deletingLastPathComponent - } - - // +++ TEST +++ - /* - OCNetworking.sharedManager()?.search(withAccount: fileProviderData.sharedInstance.account, folder: serverUrl, fileName:"", dateLastModified: nil, numberOfItem: 2, completion: { (account, metadatas, message, errorCode) in - print(message ?? "NO MESSAGE") - }) - */ - // ++++++++++++ - - OCNetworking.sharedManager().readFile(withAccount: fileProviderData.sharedInstance.account, serverUrl: serverUrlForFileName, fileName: fileName, completion: { (account, metadata, message, errorCode) in + NCCommunication.sharedInstance.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", account: fileProviderData.sharedInstance.account, completionHandler: { (account, files, error) in + + if error == nil && files.count >= 1 { + + let file = files[0] - if errorCode == 0 && account == fileProviderData.sharedInstance.account { + // Update directory etag + NCManageDatabase.sharedInstance.setDirectory(serverUrl: serverUrl, serverUrlTo: nil, etag: file.etag, ocId: file.ocId, encrypted: file.e2eEncrypted, account: account) + // Save etag for this serverUrl + fileProviderData.sharedInstance.listServerUrlEtag[serverUrl] = file.etag - if fileProviderData.sharedInstance.listServerUrlEtag[serverUrl] == nil || fileProviderData.sharedInstance.listServerUrlEtag[serverUrl] != metadata!.etag || metadatasFromDB == nil { - - OCNetworking.sharedManager().readFolder(withAccount: fileProviderData.sharedInstance.account, serverUrl: serverUrl, depth: "1", completion: { (account, metadatas, metadataFolder, message, errorCode) in - - if errorCode == 0 && account == fileProviderData.sharedInstance.account { - - if metadataFolder != nil { - // Update directory etag - NCManageDatabase.sharedInstance.setDirectory(serverUrl: serverUrl, serverUrlTo: nil, etag: metadataFolder!.etag, ocId: metadataFolder!.ocId, encrypted: metadataFolder!.e2eEncrypted, account: fileProviderData.sharedInstance.account) - // Save etag for this serverUrl - fileProviderData.sharedInstance.listServerUrlEtag[serverUrl] = metadataFolder!.etag - } - - if metadatas != nil { - - NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d)", fileProviderData.sharedInstance.account, serverUrl, k_metadataStatusNormal, k_metadataStatusHide)) - - NCManageDatabase.sharedInstance.setDateReadDirectory(serverUrl: serverUrl, account: fileProviderData.sharedInstance.account) - - let metadatasInDownload = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d OR status == %d OR status == %d)", fileProviderData.sharedInstance.account, serverUrl, k_metadataStatusWaitDownload, k_metadataStatusInDownload, k_metadataStatusDownloading, k_metadataStatusDownloadError), sorted: nil, ascending: false) - - _ = NCManageDatabase.sharedInstance.addMetadatas(metadatas as! [tableMetadata]) - if metadatasInDownload != nil { - _ = NCManageDatabase.sharedInstance.addMetadatas(metadatasInDownload!) - } - } - - metadatasFromDB = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), sorted: "fileName", ascending: true) - - self.selectFirstPageItems(metadatasFromDB, observer: observer) - - } else if errorCode != 0 { - - self.selectFirstPageItems(metadatasFromDB, observer: observer) - } - }) + NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d)", account, serverUrl, k_metadataStatusNormal, k_metadataStatusHide)) - } else { + NCManageDatabase.sharedInstance.setDateReadDirectory(serverUrl: serverUrl, account: account) - self.selectFirstPageItems(metadatasFromDB, observer: observer) + let metadatasInDownload = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d OR status == %d OR status == %d)", account, serverUrl, k_metadataStatusWaitDownload, k_metadataStatusInDownload, k_metadataStatusDownloading, k_metadataStatusDownloadError), sorted: nil, ascending: false) + + /* + for (index, file) in files.enumerated() { + if index > 0 { + NCManageDatabase.sharedInstance.addMetadata(file: file, account: fileProviderData.sharedInstance.account, serverUrl: serverUrl) + } + } + */ + NCManageDatabase.sharedInstance.addMetadata(files: files, account: account, serverUrl: serverUrl, removeFirst: true) + + if metadatasInDownload != nil { + _ = NCManageDatabase.sharedInstance.addMetadatas(metadatasInDownload!) } + metadatasFromDB = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl), sorted: "fileName", ascending: true) + + self.selectFirstPageItems(metadatasFromDB, observer: observer) + } else { + self.selectFirstPageItems(metadatasFromDB, observer: observer) } }) diff --git a/File Provider Extension/FileProviderExtension+Actions.swift b/File Provider Extension/FileProviderExtension+Actions.swift index d5746cfa4..1eb7ebf8d 100644 --- a/File Provider Extension/FileProviderExtension+Actions.swift +++ b/File Provider Extension/FileProviderExtension+Actions.swift @@ -32,20 +32,20 @@ extension FileProviderExtension { return } - let serverUrl = tableDirectory.serverUrl + let serverUrlFileName = tableDirectory.serverUrl + "/" + directoryName - OCNetworking.sharedManager().createFolder(withAccount: fileProviderData.sharedInstance.account, serverUrl: serverUrl, fileName: directoryName, completion: { (account, ocId, date, message, errorCode) in + NCCommunication.sharedInstance.createFolder(serverUrlFileName, account: fileProviderData.sharedInstance.account) { (account, ocId, date, error) in - if errorCode == 0 && account == fileProviderData.sharedInstance.account { + if error == nil { let metadata = tableMetadata() - metadata.account = account! + metadata.account = account metadata.directory = true metadata.ocId = ocId! metadata.fileName = directoryName metadata.fileNameView = directoryName - metadata.serverUrl = serverUrl + metadata.serverUrl = tableDirectory.serverUrl metadata.typeFile = k_metadataTypeFile_directory guard let metadataUpdate = NCManageDatabase.sharedInstance.addMetadata(metadata) else { @@ -53,7 +53,7 @@ extension FileProviderExtension { return } - guard let _ = NCManageDatabase.sharedInstance.addDirectory(encrypted: false, favorite: false, ocId: ocId!, permissions: nil, serverUrl: serverUrl + "/" + directoryName, account: account!) else { + guard let _ = NCManageDatabase.sharedInstance.addDirectory(encrypted: false, favorite: false, ocId: ocId!, permissions: nil, serverUrl: tableDirectory.serverUrl + "/" + directoryName, account: account) else { completionHandler(nil, NSFileProviderError(.noSuchItem)) return } @@ -65,10 +65,11 @@ extension FileProviderExtension { let item = FileProviderItem(metadata: metadataUpdate, parentItemIdentifier: parentItemIdentifier) completionHandler(item, nil) + } else { completionHandler(nil, NSFileProviderError(.serverUnreachable)) } - }) + } } override func deleteItem(withIdentifier itemIdentifier: NSFileProviderItemIdentifier, completionHandler: @escaping (Error?) -> Void) { @@ -78,8 +79,12 @@ extension FileProviderExtension { return } - OCNetworking.sharedManager().deleteFileOrFolder(withAccount: fileProviderData.sharedInstance.account, path: metadata.serverUrl + "/" + metadata.fileName, completion: { (account, message, errorCode) in - if errorCode == 0 || errorCode == kOCErrorServerPathNotFound { + let serverUrlFileName = metadata.serverUrl + "/" + metadata.fileName + + NCCommunication.sharedInstance.deleteFileOrFolder(serverUrlFileName, account: fileProviderData.sharedInstance.account) { (account, error) in + + if error == nil { //|| error == kOCErrorServerPathNotFound { + let fileNamePath = CCUtility.getDirectoryProviderStorageOcId(itemIdentifier.rawValue)! do { try fileProviderUtility.sharedInstance.fileManager.removeItem(atPath: fileNamePath) @@ -89,7 +94,7 @@ extension FileProviderExtension { if metadata.directory { let dirForDelete = CCUtility.stringAppendServerUrl(metadata.serverUrl, addFileName: metadata.fileName) - NCManageDatabase.sharedInstance.deleteDirectoryAndSubDirectory(serverUrl: dirForDelete!, account: fileProviderData.sharedInstance.account) + NCManageDatabase.sharedInstance.deleteDirectoryAndSubDirectory(serverUrl: dirForDelete!, account: account) } NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) @@ -100,7 +105,7 @@ extension FileProviderExtension { } else { completionHandler( NSFileProviderError(.serverUnreachable)) } - }) + } } override func reparentItem(withIdentifier itemIdentifier: NSFileProviderItemIdentifier, toParentItemWithIdentifier parentItemIdentifier: NSFileProviderItemIdentifier, newName: String?, completionHandler: @escaping (NSFileProviderItem?, Error?) -> Void) { @@ -126,12 +131,12 @@ extension FileProviderExtension { let serverUrlTo = tableDirectoryTo.serverUrl let fileNameTo = serverUrlTo + "/" + itemFrom.filename - OCNetworking.sharedManager().moveFileOrFolder(withAccount: metadataFrom.account, fileName: fileNameFrom, fileNameTo: fileNameTo, completion: { (account, message, errorCode) in - - if errorCode == 0 && account == metadataFrom.account { + NCCommunication.sharedInstance.moveFileOrFolder(serverUrlFileNameSource: fileNameFrom, serverUrlFileNameDestination: fileNameTo, account: fileProviderData.sharedInstance.account) { (account, error) in + + if error == nil { if metadataFrom.directory { - NCManageDatabase.sharedInstance.deleteDirectoryAndSubDirectory(serverUrl: serverUrlFrom, account: account!) + NCManageDatabase.sharedInstance.deleteDirectoryAndSubDirectory(serverUrl: serverUrlFrom, account: account) NCManageDatabase.sharedInstance.renameDirectory(ocId: ocIdFrom, serverUrl: serverUrlTo) } @@ -148,7 +153,7 @@ extension FileProviderExtension { } else { completionHandler(nil, NSFileProviderError(.serverUnreachable)) } - }) + } } override func renameItem(withIdentifier itemIdentifier: NSFileProviderItemIdentifier, toName itemName: String, completionHandler: @escaping (NSFileProviderItem?, Error?) -> Void) { @@ -167,9 +172,9 @@ extension FileProviderExtension { let fileNamePathFrom = metadata.serverUrl + "/" + fileNameFrom let fileNamePathTo = metadata.serverUrl + "/" + itemName - OCNetworking.sharedManager().moveFileOrFolder(withAccount: metadata.account, fileName: fileNamePathFrom, fileNameTo: fileNamePathTo, completion: { (account, message, errorCode) in - - if errorCode == 0 && account == metadata.account { + NCCommunication.sharedInstance.moveFileOrFolder(serverUrlFileNameSource: fileNamePathFrom, serverUrlFileNameDestination: fileNamePathTo, account: fileProviderData.sharedInstance.account) { (account, error) in + + if error == nil { // Rename metadata guard let metadata = NCManageDatabase.sharedInstance.renameMetadata(fileNameTo: itemName, ocId: metadata.ocId) else { @@ -179,7 +184,7 @@ extension FileProviderExtension { if metadata.directory { - NCManageDatabase.sharedInstance.setDirectory(serverUrl: fileNamePathFrom, serverUrlTo: fileNamePathTo, etag: nil, ocId: nil, encrypted: directoryTable.e2eEncrypted, account: account!) + NCManageDatabase.sharedInstance.setDirectory(serverUrl: fileNamePathFrom, serverUrlTo: fileNamePathTo, etag: nil, ocId: nil, encrypted: directoryTable.e2eEncrypted, account: account) } else { @@ -203,7 +208,7 @@ extension FileProviderExtension { } else { completionHandler(nil, NSFileProviderError(.serverUnreachable)) } - }) + } } override func setFavoriteRank(_ favoriteRank: NSNumber?, forItemIdentifier itemIdentifier: NSFileProviderItemIdentifier, completionHandler: @escaping (NSFileProviderItem?, Error?) -> Void) { @@ -230,10 +235,10 @@ extension FileProviderExtension { } if (favorite == true && metadata.favorite == false) || (favorite == false && metadata.favorite == true) { - let fileNamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, activeUrl: fileProviderData.sharedInstance.accountUrl) + let fileNamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, activeUrl: fileProviderData.sharedInstance.accountUrl)! - OCNetworking.sharedManager().settingFavorite(withAccount: metadata.account, fileName: fileNamePath, favorite: favorite, completion: { (account, message, errorCode) in - if errorCode == 0 && account == metadata.account { + NCCommunication.sharedInstance.setFavorite(urlString: fileProviderData.sharedInstance.accountUrl, fileName: fileNamePath, favorite: favorite, account: fileProviderData.sharedInstance.account) { (account, error) in + if error == nil { // Change DB metadata.favorite = favorite guard let metadataUpdate = NCManageDatabase.sharedInstance.addMetadata(metadata) else { @@ -246,18 +251,17 @@ extension FileProviderExtension { fileProviderData.sharedInstance.signalEnumerator(for: [.workingSet]) completionHandler(item, nil) - } else { // Errore, remove from listFavoriteIdentifierRank fileProviderData.sharedInstance.listFavoriteIdentifierRank.removeValue(forKey: itemIdentifier.rawValue) let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier) - + fileProviderData.sharedInstance.fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item fileProviderData.sharedInstance.signalEnumerator(for: [.workingSet]) - + completionHandler(item, NSFileProviderError(.serverUnreachable)) } - }) + } } } @@ -345,16 +349,13 @@ extension FileProviderExtension { fileURL.stopAccessingSecurityScopedResource() - OCNetworking.sharedManager()?.upload(withAccount: fileProviderData.sharedInstance.account, fileNameServerUrl: fileNameServerUrl, fileNameLocalPath: fileTemporaryDirectory, encode: true, communication: OCNetworking.sharedManager()?.sharedOCCommunicationExtension(), progress: { (progress) in - - }, completion: { (account, ocId, etag, date, message, errorCode) in - - if account == fileProviderData.sharedInstance.account && errorCode == 0 { - + _ = NCCommunication.sharedInstance.upload(serverUrlFileName: fileNameServerUrl, fileNamePathSource: fileTemporaryDirectory, wwan: false, account: fileProviderData.sharedInstance.account, progressHandler: { (progress) in + }) { (account, ocId, etag, date, error) in + if error == nil { _ = fileProviderUtility.sharedInstance.moveFile(fileTemporaryDirectory, toPath: CCUtility.getDirectoryProviderStorageOcId(ocId, fileNameView: fileName)) - + let metadata = tableMetadata() - metadata.account = fileProviderData.sharedInstance.account + metadata.account = account metadata.date = date! as NSDate metadata.directory = false metadata.etag = etag! @@ -363,21 +364,19 @@ extension FileProviderExtension { metadata.fileNameView = fileName metadata.serverUrl = tableDirectory.serverUrl metadata.size = size - + guard let metadataDB = NCManageDatabase.sharedInstance.addMetadata(metadata) else { completionHandler(nil, NSFileProviderError(.noSuchItem)) return } NCManageDatabase.sharedInstance.addLocalFile(metadata: metadataDB) - + let item = FileProviderItem(metadata: metadataDB, parentItemIdentifier: parentItemIdentifier) completionHandler(item, nil) - } else { - completionHandler(nil, NSFileProviderError(.serverUnreachable)) - } - }) + } + } } } } diff --git a/File Provider Extension/FileProviderExtension+Thumbnail.swift b/File Provider Extension/FileProviderExtension+Thumbnail.swift index abe166893..4a8e47753 100644 --- a/File Provider Extension/FileProviderExtension+Thumbnail.swift +++ b/File Provider Extension/FileProviderExtension+Thumbnail.swift @@ -47,17 +47,13 @@ extension FileProviderExtension { let width = NCUtility.sharedInstance.getScreenWidthForPreview() let height = NCUtility.sharedInstance.getScreenHeightForPreview() - OCNetworking.sharedManager().downloadPreview(withAccount: metadata.account, metadata: metadata, withWidth: width, andHeight: height, completion: { (account, preview, message, errorCode) in - - if errorCode == 0 && account == metadata.account { - do { - let url = URL.init(fileURLWithPath: CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, fileNameView: metadata.fileNameView)) - let data = try Data.init(contentsOf: url) - perThumbnailCompletionHandler(itemIdentifier, data, nil) - } catch let error { - print("error: \(error)") - perThumbnailCompletionHandler(itemIdentifier, nil, NSFileProviderError(.noSuchItem)) - } + let fileNamePathSource = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, activeUrl: fileProviderData.sharedInstance.accountUrl)! + let fileNamePathLocalDestination = CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, fileNameView: metadata.fileNameView)! + let serverUrl = fileProviderData.sharedInstance.accountUrl + + NCCommunication.sharedInstance.downloadPreview(serverUrl: serverUrl, fileNamePath: fileNamePathSource, fileNamePathLocalDestination: fileNamePathLocalDestination ,width: width, height: height, account: fileProviderData.sharedInstance.account) { (account, data, error) in + if error == nil && data != nil { + perThumbnailCompletionHandler(itemIdentifier, data, nil) } else { perThumbnailCompletionHandler(itemIdentifier, nil, NSFileProviderError(.serverUnreachable)) } @@ -66,8 +62,8 @@ extension FileProviderExtension { if (counterProgress == progress.totalUnitCount) { completionHandler(nil) } - }) - + } + } else { counterProgress += 1 @@ -79,5 +75,5 @@ extension FileProviderExtension { return progress } - + } diff --git a/File Provider Extension/FileProviderExtension.swift b/File Provider Extension/FileProviderExtension.swift index eddd7c1e4..390f19c82 100644 --- a/File Provider Extension/FileProviderExtension.swift +++ b/File Provider Extension/FileProviderExtension.swift @@ -215,13 +215,15 @@ class FileProviderExtension: NSFileProviderExtension { return } - let task = OCNetworking.sharedManager().download(withAccount: metadata.account, fileNameServerUrl: metadata.serverUrl + "/" + metadata.fileName, fileNameLocalPath: url.path, encode: true, communication: OCNetworking.sharedManager()?.sharedOCCommunicationExtension(), completion: { (account, lenght, etag, date, message, errorCode) in + let task = NCCommunication.sharedInstance.download(serverUrlFileName: metadata.serverUrl + "/" + metadata.fileName, fileNamePathLocalDestination: url.path, wwan: false, account: fileProviderData.sharedInstance.account, progressHandler: { (progress) in + + }) { (account, etag, date, lenght, error) in // remove Task self.outstandingSessionTasks.removeValue(forKey: url) - if errorCode == 0 && account == metadata.account { - + if error == nil { + guard let metadata = fileProviderUtility.sharedInstance.getTableMetadataFromItemIdentifier(identifier) else { completionHandler(NSFileProviderError(.noSuchItem)) return @@ -238,16 +240,14 @@ class FileProviderExtension: NSFileProviderExtension { } else { - if errorCode == Int(CFNetworkErrors.cfurlErrorCancelled.rawValue) { - completionHandler(NSFileProviderError(.noSuchItem)) - } else { +// if errorCode == Int(CFNetworkErrors.cfurlErrorCancelled.rawValue) { +// completionHandler(NSFileProviderError(.noSuchItem)) +// } else { completionHandler(NSFileProviderError(.serverUnreachable)) - } - - return +// } } - }) - + } + // Add and register task if task != nil { outstandingSessionTasks[url] = task @@ -267,15 +267,14 @@ class FileProviderExtension: NSFileProviderExtension { let fileNameServerUrl = metadata.serverUrl + "/" + fileName let fileNameLocalPath = url.path - OCNetworking.sharedManager()?.upload(withAccount: fileProviderData.sharedInstance.account, fileNameServerUrl: fileNameServerUrl, fileNameLocalPath: fileNameLocalPath, encode: true, communication: OCNetworking.sharedManager()?.sharedOCCommunicationExtension(), progress: { (progress) in - }, completion: { (account, ocId, etag, date, message, errorCode) in - - if account == fileProviderData.sharedInstance.account && errorCode == 0 { + _ = NCCommunication.sharedInstance.upload(serverUrlFileName: fileNameServerUrl, fileNamePathSource: fileNameLocalPath, wwan: false, account: fileProviderData.sharedInstance.account, progressHandler: { (progress) in + }) { (account, ocId, etag, date, error) in + if error == nil { NCManageDatabase.sharedInstance.setLocalFile(ocId: itemIdentifier.rawValue, date: date! as NSDate, exifDate: nil, exifLatitude: nil, exifLongitude: nil, fileName: nil, etag: etag!) // remove preview ico CCUtility.removeFile(atPath: CCUtility.getDirectoryProviderStorageIconOcId(itemIdentifier.rawValue, fileNameView: fileName)) } - }) + } } /* diff --git a/File Provider Extension/FileProviderItem.swift b/File Provider Extension/FileProviderItem.swift index be925e61c..e908ad19e 100644 --- a/File Provider Extension/FileProviderItem.swift +++ b/File Provider Extension/FileProviderItem.swift @@ -86,9 +86,11 @@ class FileProviderItem: NSObject, NSFileProviderItem { let tableLocalFile = NCManageDatabase.sharedInstance.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) if tableLocalFile == nil { -// isMostRecentVersionDownloaded = false + isMostRecentVersionDownloaded = false + isDownloaded = false } else { -// isMostRecentVersionDownloaded = true + isMostRecentVersionDownloaded = true + isDownloaded = true } } else { diff --git a/Share/NCSelectDestination.h b/Share/NCSelectDestination.h index 67c3e1961..8e8766a9f 100644 --- a/Share/NCSelectDestination.h +++ b/Share/NCSelectDestination.h @@ -26,7 +26,6 @@ #import "CCBKPasscode.h" #import "CCUtility.h" -#import "OCNetworking.h" #import "CCHud.h" @class tableMetadata; diff --git a/Share/NCSelectDestination.m b/Share/NCSelectDestination.m index 2a5097938..47cab6fc0 100644 --- a/Share/NCSelectDestination.m +++ b/Share/NCSelectDestination.m @@ -27,11 +27,8 @@ @interface NCSelectDestination () { NSString *activeAccount; - NSString *activePassword; NSString *activeUrl; - NSString *activeUser; - NSString *activeUserID; - + BOOL _loadingFolder; // Automatic Upload Folder @@ -55,11 +52,10 @@ if (tableAccount) { activeAccount = tableAccount.account; - activePassword = [CCUtility getPassword:tableAccount.account]; activeUrl = tableAccount.url; - activeUser = tableAccount.user; - activeUserID = tableAccount.userID; + (void)[[NCCommunication sharedInstance] initWithUsername:tableAccount.userID password:[CCUtility getPassword:tableAccount.account] userAgent:[CCUtility getUserAgent] delegate:nil]; + } else { UIAlertController * alert= [UIAlertController alertControllerWithTitle:nil message:NSLocalizedString(@"_no_active_account_", nil) preferredStyle:UIAlertControllerStyleAlert]; @@ -103,7 +99,7 @@ _autoUploadDirectory = [[NCManageDatabase sharedInstance] getAccountAutoUploadDirectory:activeUrl]; // read file->folder - [self readFile]; + [self readFolder]; } // Apparirà @@ -268,62 +264,47 @@ [self dismissViewControllerAnimated:YES completion:nil]; } -// MARK: - Read File - -- (void)readFile -{ - [[OCNetworking sharedManager] readFileWithAccount:activeAccount serverUrl:_serverUrl fileName:nil completion:^(NSString *account, tableMetadata *metadata, NSString *message, NSInteger errorCode) { - if (errorCode == 0) { - tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", account, _serverUrl]]; - if ([metadata.etag isEqualToString:directory.etag] == NO) { - [self readFolder]; - } - } else { - [self readFolder]; - } - }]; -} - // MARK: - Read Folder - (void)readFolder { - [[OCNetworking sharedManager] readFolderWithAccount:activeAccount serverUrl:_serverUrl depth:@"1" completion:^(NSString *account, NSArray *metadatas, tableMetadata *metadataFolder, NSString *message, NSInteger errorCode) { + [[NCCommunication sharedInstance] readFileOrFolderWithServerUrlFileName:_serverUrl depth:@"1" account:activeAccount completionHandler:^(NSString *account, NSArray<NCFile *> *files, NSError *error) { + + if (error == nil && files.count >= 1) { + + NCFile *fileDirectory = files[0]; - if (errorCode == 0 && [account isEqualToString:activeAccount]) { - // Update directory etag - [[NCManageDatabase sharedInstance] setDirectoryWithServerUrl:_serverUrl serverUrlTo:nil etag:metadataFolder.etag ocId:metadataFolder.ocId encrypted:metadataFolder.e2eEncrypted account:activeAccount]; - [[NCManageDatabase sharedInstance] deleteMetadataWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND (status == %d OR status == %d)", activeAccount, _serverUrl, k_metadataStatusNormal, k_metadataStatusHide]]; - [[NCManageDatabase sharedInstance] setDateReadDirectoryWithServerUrl:_serverUrl account:activeAccount]; + [[NCManageDatabase sharedInstance] setDirectoryWithServerUrl:_serverUrl serverUrlTo:nil etag:fileDirectory.etag ocId:fileDirectory.ocId encrypted:fileDirectory.e2eEncrypted account:account]; + + // Delete metadata + [[NCManageDatabase sharedInstance] deleteMetadataWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND (status == %d OR status == %d)", account, _serverUrl, k_metadataStatusNormal, k_metadataStatusHide]]; + + // In download + NSArray *metadatasInDownload = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND (status == %d OR status == %d OR status == %d OR status == %d)", account, _serverUrl, k_metadataStatusWaitDownload, k_metadataStatusInDownload, k_metadataStatusDownloading, k_metadataStatusDownloadError] sorted:nil ascending:NO]; - NSArray *metadatasInDownload = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND (status == %d OR status == %d OR status == %d OR status == %d)", activeAccount, _serverUrl, k_metadataStatusWaitDownload, k_metadataStatusInDownload, k_metadataStatusDownloading, k_metadataStatusDownloadError] sorted:nil ascending:NO]; + // Insert in Database + [[NCManageDatabase sharedInstance] addMetadataWithFiles:files account:account serverUrl:_serverUrl removeFirst:true]; - // insert in Database - (void)[[NCManageDatabase sharedInstance] addMetadatas:metadatas]; // reinsert metadatas in Download if (metadatasInDownload) { (void)[[NCManageDatabase sharedInstance] addMetadatas:metadatasInDownload]; } - - } else if (errorCode != 0) { + + } else { self.move.enabled = NO; - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_error_",nil) message:message preferredStyle:UIAlertControllerStyleAlert]; + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_error_",nil) message:error.description preferredStyle:UIAlertControllerStyleAlert]; [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { }]]; [self presentViewController:alertController animated:YES completion:nil]; - } else { - NSLog(@"[LOG] It has been changed user during networking process, error."); } _loadingFolder = NO; - [self.tableView reloadData]; - }]; _loadingFolder = YES; @@ -334,16 +315,15 @@ - (void)createFolder:(NSString *)fileNameFolder { - [[OCNetworking sharedManager] createFolderWithAccount:activeAccount serverUrl:_serverUrl fileName:fileNameFolder completion:^(NSString *account, NSString *ocId, NSDate *date, NSString *message, NSInteger errorCode) { - - if (errorCode == 0 && [account isEqualToString:activeAccount]) { - [self readFolder]; - } else if (errorCode != 0) { - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_error_",nil) message:message preferredStyle:UIAlertControllerStyleAlert]; + NSString *serverUrlFileName = [NSString stringWithFormat:@"%@/%@", _serverUrl, fileNameFolder]; + + [[NCCommunication sharedInstance] createFolder:serverUrlFileName account:activeAccount completionHandler:^(NSString *account, NSString *ocID, NSDate *date, NSError *error) { + if (error == nil) { + [self readFolder]; + } else { + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_error_",nil) message:error.description preferredStyle:UIAlertControllerStyleAlert]; [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { }]]; [self presentViewController:alertController animated:YES completion:nil]; - } else { - NSLog(@"[LOG] It has been changed user during networking process, error."); } }]; } diff --git a/Share/ShareViewController.h b/Share/ShareViewController.h index 4f12893b5..228e75e9f 100644 --- a/Share/ShareViewController.h +++ b/Share/ShareViewController.h @@ -23,8 +23,6 @@ #import <MBProgressHUD/MBProgressHUD.h> -#import "OCCommunication.h" -#import "CCNetworking.h" #import "OCNetworking.h" #import "CCBKPasscode.h" #import "CCGlobal.h" @@ -37,13 +35,7 @@ @interface ShareViewController : UIViewController <UITableViewDelegate, MBProgressHUDDelegate, BKPasscodeViewControllerDelegate, NCSelectDestinationDelegate> @property (nonatomic, strong) NSString *activeAccount; -@property (nonatomic, strong) NSString *activeUrl; -@property (nonatomic, strong) NSString *activeUser; -@property (nonatomic, strong) NSString *activeUserID; -@property (nonatomic, strong) NSString *activePassword; -@property (nonatomic, strong) NSString *activeAccessToken; @property (nonatomic, strong) NSString *serverUrl; - @property (nonatomic, retain) NSMutableArray *filesName; @property (nonatomic, weak) IBOutlet UITableView *shareTable; diff --git a/Share/ShareViewController.m b/Share/ShareViewController.m index 2efdbfb23..c8fff7391 100644 --- a/Share/ShareViewController.m +++ b/Share/ShareViewController.m @@ -58,10 +58,8 @@ } else { _activeAccount = tableAccount.account; - _activePassword = [CCUtility getPassword:tableAccount.account]; - _activeUrl = tableAccount.url; - _activeUser = tableAccount.user; - _activeUserID = tableAccount.userID; + + (void)[[NCCommunication sharedInstance] initWithUsername:tableAccount.userID password:[CCUtility getPassword:tableAccount.account] userAgent:[CCUtility getUserAgent] delegate:nil]; if ([_activeAccount isEqualToString:[CCUtility getActiveAccountExt]]) { @@ -77,7 +75,7 @@ [CCUtility setActiveAccountExt:self.activeAccount]; - _serverUrl = [CCUtility getHomeServerUrlActiveUrl:self.activeUrl]; + _serverUrl = [CCUtility getHomeServerUrlActiveUrl:tableAccount.url]; [CCUtility setServerUrlExt:_serverUrl]; _destinyFolderButton.title = [NSString stringWithFormat:NSLocalizedString(@"_destiny_folder_", nil), NSLocalizedString(@"_home_", nil)]; @@ -212,24 +210,18 @@ NSString *fileNameServer = [NSString stringWithFormat:@"%@/%@", self.serverUrl, fileNameForUpload]; NSString *fileNameLocal = [NSTemporaryDirectory() stringByAppendingString:fileName]; - [[OCNetworking sharedManager] uploadWithAccount:self.activeAccount fileNameServerUrl:fileNameServer fileNameLocalPath:fileNameLocal encode:true communication:[[OCNetworking sharedManager] sharedOCCommunication] progress:^(NSProgress *progress) { - - dispatch_async(dispatch_get_main_queue(), ^{ - [self.hud progress:progress.fractionCompleted]; - }); - - } completion:^(NSString *account, NSString *ocId, NSString *etag, NSDate *date, NSString *message, NSInteger errorCode) { - + (void)[[NCCommunication sharedInstance] uploadWithServerUrlFileName:fileNameServer fileNamePathSource:fileNameLocal wwan:false account:self.activeAccount progressHandler:^(NSProgress * progress) { + [self.hud progress:progress.fractionCompleted]; + } completionHandler:^(NSString *account, NSString *ocId, NSString *etag, NSDate *date, NSError *error) { [self.hud hideHud]; - [self.filesName removeObject:fileName]; - - if (errorCode == 0) { - + + if (error == nil) { + [CCUtility copyFileAtPath:fileNameLocal toPath:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileNameForUpload]]; - + tableMetadata *metadata = [tableMetadata new]; - + metadata.account = self.activeAccount; metadata.date = date; metadata.etag = etag; @@ -238,21 +230,21 @@ metadata.fileNameView = fileNameForUpload; metadata.serverUrl = self.serverUrl; (void)[CCUtility insertTypeFileIconName:fileNameForUpload metadata:metadata]; - + metadata = [[NCManageDatabase sharedInstance] addMetadata:metadata]; [[NCManageDatabase sharedInstance] addLocalFileWithMetadata:metadata]; - + [self.shareTable performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO]; [self performSelector:@selector(selectPost) withObject:nil]; - + } else { - - UIAlertController * alert= [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_error_", nil) message:message preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertController * alert= [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_error_", nil) message:error.description preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction* ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { - [alert dismissViewControllerAnimated:YES completion:nil]; - [self closeShareViewController]; - }]; + handler:^(UIAlertAction * action) { + [alert dismissViewControllerAnimated:YES completion:nil]; + [self closeShareViewController]; + }]; [alert addAction:ok]; [self presentViewController:alert animated:YES completion:nil]; } diff --git a/iOSClient/AppDelegate.m b/iOSClient/AppDelegate.m index 963ff771a..54f5d4ba9 100755 --- a/iOSClient/AppDelegate.m +++ b/iOSClient/AppDelegate.m @@ -36,7 +36,7 @@ @class NCViewerRichdocument; -@interface AppDelegate () <UNUserNotificationCenterDelegate> +@interface AppDelegate () <UNUserNotificationCenterDelegate, NCCommunicationDelegate> { PKPushRegistry *pushRegistry; } @@ -383,6 +383,8 @@ PKPushRegistry *pushRegistry; // Setting Account to Networking [CCNetworking sharedNetworking].delegate = [NCNetworkingMain sharedInstance]; + + (void)[[NCCommunication sharedInstance] initWithUsername:activeUserID password:activePassword userAgent:[CCUtility getUserAgent] delegate:self]; } - (void)deleteAccount:(NSString *)account wipe:(BOOL)wipe @@ -1259,6 +1261,16 @@ PKPushRegistry *pushRegistry; }); } +- (void)urlSession:(NSURLSession * _Nonnull)session didReceive:(NSURLAuthenticationChallenge * _Nonnull)challenge completionHandler:(void (^ _Nonnull)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler { + + // The pinnning check + if ([[CCCertificate sharedManager] checkTrustedChallenge:challenge]) { + completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + } else { + completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); + } +} + #pragma -------------------------------------------------------------------------------------------- #pragma mark ===== Process Load Download/Upload < k_timerProcess seconds > ===== #pragma -------------------------------------------------------------------------------------------- diff --git a/iOSClient/AudioRecorder/NCAudioRecorderViewController.swift b/iOSClient/AudioRecorder/NCAudioRecorderViewController.swift index 93b22efe0..19bf9dd58 100644 --- a/iOSClient/AudioRecorder/NCAudioRecorderViewController.swift +++ b/iOSClient/AudioRecorder/NCAudioRecorderViewController.swift @@ -156,7 +156,7 @@ open class NCAudioRecorder : NSObject { fileprivate let session = AVAudioSession.sharedInstance() var recorder: AVAudioRecorder? - fileprivate var player: AVAudioPlayer? + fileprivate var player: AVAudioPlayer! fileprivate var link: CADisplayLink? var metering: Bool { diff --git a/iOSClient/Database/NCManageDatabase.swift b/iOSClient/Database/NCManageDatabase.swift index f490c07d5..9aaab4ca3 100644 --- a/iOSClient/Database/NCManageDatabase.swift +++ b/iOSClient/Database/NCManageDatabase.swift @@ -1837,24 +1837,24 @@ class NCManageDatabase: NSObject { metadata.resourceType = file.resourceType metadata.serverUrl = serverUrl metadata.size = file.size - + + CCUtility.insertTypeFileIconName(file.fileName, metadata: metadata) + realm.add(metadata, update: .all) // Directory if file.directory { - let result = realm.objects(tableDirectory.self).filter("ocId == %@", file.ocId).first - if result == nil { - - let directory = tableDirectory() - - directory.account = account - directory.e2eEncrypted = file.e2eEncrypted - directory.favorite = file.favorite - directory.permissions = file.permissions - directory.serverUrl = CCUtility.stringAppendServerUrl(serverUrl, addFileName: file.fileName) - realm.add(directory, update: .all) - } + let directory = tableDirectory() + + directory.account = account + directory.e2eEncrypted = file.e2eEncrypted + directory.favorite = file.favorite + directory.ocId = file.ocId + directory.permissions = file.permissions + directory.serverUrl = CCUtility.stringAppendServerUrl(serverUrl, addFileName: file.fileName) + + realm.add(directory, update: .all) } } } diff --git a/iOSClient/Login/CCLogin.m b/iOSClient/Login/CCLogin.m index efbdbcac4..f2be251e0 100644 --- a/iOSClient/Login/CCLogin.m +++ b/iOSClient/Login/CCLogin.m @@ -176,7 +176,59 @@ // Remove trailing slash if ([self.baseUrl.text hasSuffix:@"/"]) self.baseUrl.text = [self.baseUrl.text substringToIndex:[self.baseUrl.text length] - 1]; + + [NCCommunication sharedInstance].delegate = (id <NCCommunicationDelegate>)appDelegate; + [[NCCommunication sharedInstance] getServerStatusWithUrlString:self.baseUrl.text completionHandler:^(NSString *serverProductName, NSString *serverVersion, NSInteger versionMajor, NSInteger versionMinor, NSInteger versionMicro, BOOL extendedSupport, NSError *error) { + + if (error == nil) { + + [self.activity stopAnimating]; + self.login.enabled = YES; + + // Login Flow + if (_user.hidden && _password.hidden && versionMajor >= k_flow_version_available) { + + appDelegate.activeLoginWeb = [[UIStoryboard storyboardWithName:@"CCLogin" bundle:nil] instantiateViewControllerWithIdentifier:@"NCLoginWeb"]; + appDelegate.activeLoginWeb.urlBase = self.baseUrl.text; + + [self presentViewController:appDelegate.activeLoginWeb animated:YES completion:nil]; + } + + // NO Login Flow available + if (versionMajor < k_flow_version_available) { + + [self.loginTypeView setHidden:YES]; + + _imageUser.hidden = NO; + _user.hidden = NO; + _imagePassword.hidden = NO; + _password.hidden = NO; + + [_user becomeFirstResponder]; + } + + } else { + + [self.activity stopAnimating]; + self.login.enabled = YES; + + if ([error code] == NSURLErrorServerCertificateUntrusted) { + + [[CCCertificate sharedManager] presentViewControllerCertificateWithAccount:nil viewController:self delegate:self]; + + } else { + + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_connection_error_", nil) message:[error description] preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}]; + + [alertController addAction:okAction]; + [self presentViewController:alertController animated:YES completion:nil]; + } + } + + }]; + /* [[OCNetworking sharedManager] serverStatusUrl:self.baseUrl.text completion:^(NSString *serverProductName, NSInteger versionMajor, NSInteger versionMicro, NSInteger versionMinor, BOOL extendedSupport, NSString *message, NSInteger errorCode) { if (errorCode == 0) { @@ -225,6 +277,7 @@ } } }]; + */ } - (void)trustedCerticateAccepted diff --git a/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift b/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift index deb46600b..3de9b7188 100644 --- a/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift +++ b/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift @@ -37,7 +37,7 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud private var durationPlayer: TimeInterval = 0 private var counterSecondPlayer: TimeInterval = 0 - private var audioPlayer = AVAudioPlayer() + private var audioPlayer: AVAudioPlayer! private var timer = Timer() let appDelegate = UIApplication.shared.delegate as! AppDelegate diff --git a/iOSClient/Networking/NCCommunication.swift b/iOSClient/Networking/NCCommunication.swift index c9221d0fc..24a1a91c3 100755 --- a/iOSClient/Networking/NCCommunication.swift +++ b/iOSClient/Networking/NCCommunication.swift @@ -22,11 +22,17 @@ // import Foundation +import UIKit import Alamofire import SwiftyXMLParser +import SwiftyJSON -class NCCommunication: SessionDelegate { - @objc static let sharedInstance: NCCommunication = { +@objc public protocol NCCommunicationDelegate { + @objc func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) +} + +@objc public class NCCommunication: SessionDelegate { + @objc public static let sharedInstance: NCCommunication = { let instance = NCCommunication() return instance }() @@ -34,34 +40,72 @@ class NCCommunication: SessionDelegate { var username = "" var password = "" var userAgent: String? + var directoryCertificate: String? + @objc public var delegate: NCCommunicationDelegate? + + // Session Manager - //MARK: - Settings + private lazy var sessionManagerData: Alamofire.Session = { + let configuration = URLSessionConfiguration.af.default + return Alamofire.Session(configuration: configuration, delegate: self, rootQueue: DispatchQueue(label: "com.nextcloud.sessionManagerData.rootQueue"), startRequestsImmediately: true, requestQueue: nil, serializationQueue: nil, interceptor: nil, serverTrustManager: nil, redirectHandler: nil, cachedResponseHandler: nil, eventMonitors: self.makeEvents()) + }() + + private lazy var sessionManagerTransfer: Alamofire.Session = { + let configuration = URLSessionConfiguration.af.default + configuration.allowsCellularAccess = true + configuration.httpMaximumConnectionsPerHost = NCCommunicationCommon.sharedInstance.session_maximumConnectionsPerHost + return Alamofire.Session(configuration: configuration, delegate: self, rootQueue: DispatchQueue(label: "com.nextcloud.sessionManagerTransfer.rootQueue"), startRequestsImmediately: true, requestQueue: nil, serializationQueue: nil, interceptor: nil, serverTrustManager: nil, redirectHandler: nil, cachedResponseHandler: nil, eventMonitors: self.makeEvents()) + }() + + private lazy var sessionManagerTransferWWan: Alamofire.Session = { + let configuration = URLSessionConfiguration.af.default + configuration.allowsCellularAccess = false + configuration.httpMaximumConnectionsPerHost = NCCommunicationCommon.sharedInstance.session_maximumConnectionsPerHost + return Alamofire.Session(configuration: configuration, delegate: self, rootQueue: DispatchQueue(label: "com.nextcloud.sessionManagerTransferWWan.rootQueue"), startRequestsImmediately: true, requestQueue: nil, serializationQueue: nil, interceptor: nil, serverTrustManager: nil, redirectHandler: nil, cachedResponseHandler: nil, eventMonitors: self.makeEvents()) + }() + + //MARK: - Initializer - @objc func settingAccount(username: String, password: String) { + init() { } + + @objc public init(username: String, password: String, userAgent: String?, delegate: NCCommunicationDelegate?) { self.username = username self.password = password + self.userAgent = userAgent + self.delegate = delegate } - @objc func settingUserAgent(_ userAgent: String) { - self.userAgent = userAgent + @objc public func setting(directoryCertificate: String) { + self.directoryCertificate = directoryCertificate + } + + //MARK: - monitor + + private func makeEvents() -> [EventMonitor] { + let events = ClosureEventMonitor() + events.requestDidFinish = { request in + print("Request finished \(request)") + } + events.taskDidComplete = { session, task, error in + print("Request failed \(session) \(task) \(String(describing: error))") + /* + if let urlString = (error as NSError?)?.userInfo["NSErrorFailingURLStringKey"] as? String, + let resumedata = (error as NSError?)?.userInfo[NSURLSessionDownloadTaskResumeData] as? Data { + print("Found resume data for url \(urlString)") + //self.startDownload(urlString, resumeData: resumedata) + } + */ + } + return [events] } //MARK: - webDAV - @objc func createFolder(serverUrl: String, fileName: String, completionHandler: @escaping (_ ocId: String?, _ date: NSDate?, _ error: Error?) -> Void) { + @objc public func createFolder(_ serverUrlFileName: String, account: String, completionHandler: @escaping (_ account: String, _ ocId: String?, _ date: NSDate?, _ error: Error?) -> Void) { // url - var serverUrl = serverUrl - var url: URLConvertible - do { - if serverUrl.last == "/" { - serverUrl = serverUrl + fileName - } else { - serverUrl = serverUrl + "/" + fileName - } - try url = serverUrl.asURL() - } catch let error { - completionHandler(nil, nil, error) + guard let url = NCCommunicationCommon.sharedInstance.encodeUrlString(serverUrlFileName) else { + completionHandler(account, nil, nil, NCCommunicationCommon.sharedInstance.getError(code: NSURLErrorUnsupportedURL, description: "Invalid ServerUrl")) return } @@ -72,35 +116,26 @@ class NCCommunication: SessionDelegate { var headers: HTTPHeaders = [.authorization(username: self.username, password: self.password)] if let userAgent = self.userAgent { headers.update(.userAgent(userAgent)) } - AF.request(url, method: method, parameters:nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).response { (response) in + sessionManagerData.request(url, method: method, parameters:nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).response { (response) in switch response.result { case.failure(let error): - completionHandler(nil, nil, error) + completionHandler(account, nil, nil, error) case .success( _): let ocId = response.response?.allHeaderFields["OC-FileId"] as! String? if let dateString = response.response?.allHeaderFields["Date"] as! String? { if let date = NCCommunicationCommon.sharedInstance.convertDate(dateString, format: "EEE, dd MMM y HH:mm:ss zzz") { - completionHandler(ocId, date, nil) - } else { completionHandler(nil, nil, NSError(domain: NSCocoaErrorDomain, code: NSURLErrorBadServerResponse, userInfo: nil)) } - } else { completionHandler(nil, nil, NSError(domain: NSCocoaErrorDomain, code: NSURLErrorBadServerResponse, userInfo: nil)) } + completionHandler(account, ocId, date, nil) + } else { completionHandler(account, nil, nil, NCCommunicationCommon.sharedInstance.getError(code: NSURLErrorBadServerResponse, description: "Response error decode date format")) } + } else { completionHandler(account, nil, nil, NCCommunicationCommon.sharedInstance.getError(code: NSURLErrorBadServerResponse, description: "Response error decode date format")) } } } } - @objc func deleteFileOrFolder(serverUrl: String, fileName: String, completionHandler: @escaping (_ error: Error?) -> Void) { + @objc public func deleteFileOrFolder(_ serverUrlFileName: String, account: String, completionHandler: @escaping (_ account: String, _ error: Error?) -> Void) { // url - var serverUrl = serverUrl - var url: URLConvertible - do { - if serverUrl.last == "/" { - serverUrl = serverUrl + fileName - } else { - serverUrl = serverUrl + "/" + fileName - } - try url = serverUrl.asURL() - } catch let error { - completionHandler(error) + guard let url = NCCommunicationCommon.sharedInstance.encodeUrlString(serverUrlFileName) else { + completionHandler(account, NCCommunicationCommon.sharedInstance.getError(code: NSURLErrorUnsupportedURL, description: "Invalid ServerUrl")) return } @@ -111,24 +146,21 @@ class NCCommunication: SessionDelegate { var headers: HTTPHeaders = [.authorization(username: self.username, password: self.password)] if let userAgent = self.userAgent { headers.update(.userAgent(userAgent)) } - AF.request(url, method: method, parameters:nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).response { (response) in + sessionManagerData.request(url, method: method, parameters:nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).response { (response) in switch response.result { case.failure(let error): - completionHandler(error) + completionHandler(account, error) case .success( _): - completionHandler(nil) + completionHandler(account, nil) } } } - @objc func moveFileOrFolder(fileNamePath: String, fileNamePathDestination: String,completionHandler: @escaping (_ error: Error?) -> Void) { + @objc public func moveFileOrFolder(serverUrlFileNameSource: String, serverUrlFileNameDestination: String, account: String, completionHandler: @escaping (_ account: String, _ error: Error?) -> Void) { // url - var url: URLConvertible - do { - try url = fileNamePath.asURL() - } catch let error { - completionHandler(error) + guard let url = NCCommunicationCommon.sharedInstance.encodeUrlString(serverUrlFileNameSource) else { + completionHandler(account, NCCommunicationCommon.sharedInstance.getError(code: NSURLErrorUnsupportedURL, description: "Invalid ServerUrl")) return } @@ -138,20 +170,20 @@ class NCCommunication: SessionDelegate { // headers var headers: HTTPHeaders = [.authorization(username: self.username, password: self.password)] if let userAgent = self.userAgent { headers.update(.userAgent(userAgent)) } - headers.update(name: "Destination", value: fileNamePathDestination.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "") + headers.update(name: "Destination", value: serverUrlFileNameDestination.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "") headers.update(name: "Overwrite", value: "T") - AF.request(url, method: method, parameters:nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).response { (response) in + sessionManagerData.request(url, method: method, parameters:nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).response { (response) in switch response.result { case.failure(let error): - completionHandler(error) + completionHandler(account, error) case .success( _): - completionHandler(nil) + completionHandler(account, nil) } } } - @objc func readFileOrFolder(serverUrl: String, depth: String, completionHandler: @escaping (_ result: [NCFile], _ error: Error?) -> Void) { + @objc public func readFileOrFolder(serverUrlFileName: String, depth: String, account: String, completionHandler: @escaping (_ account: String, _ files: [NCFile], _ error: Error?) -> Void) { var files = [NCFile]() var isNotFirstFileOfList: Bool = false @@ -159,7 +191,7 @@ class NCCommunication: SessionDelegate { """ <?xml version=\"1.0\" encoding=\"UTF-8\"?> <d:propfind xmlns:d=\"DAV:\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\"> - <d:prop>" + <d:prop> <d:getlastmodified /> <d:getetag /> @@ -187,11 +219,11 @@ class NCCommunication: SessionDelegate { """ // url - var serverUrl = String(serverUrl) - if depth == "1" && serverUrl.last != "/" { serverUrl = serverUrl + "/" } - if depth == "0" && serverUrl.last == "/" { serverUrl = String(serverUrl.remove(at: serverUrl.index(before: serverUrl.endIndex))) } - guard let url = NCCommunicationCommon.sharedInstance.encodeUrlString(serverUrl) else { - completionHandler(files, NSError(domain: NSCocoaErrorDomain, code: NSURLErrorUnsupportedURL, userInfo: nil)) + var serverUrlFileName = String(serverUrlFileName) + if depth == "1" && serverUrlFileName.last != "/" { serverUrlFileName = serverUrlFileName + "/" } + if depth == "0" && serverUrlFileName.last == "/" { serverUrlFileName = String(serverUrlFileName.remove(at: serverUrlFileName.index(before: serverUrlFileName.endIndex))) } + guard let url = NCCommunicationCommon.sharedInstance.encodeUrlString(serverUrlFileName) else { + completionHandler(account, files, NCCommunicationCommon.sharedInstance.getError(code: NSURLErrorUnsupportedURL, description: "Invalid ServerUrl")) return } @@ -210,14 +242,14 @@ class NCCommunication: SessionDelegate { try urlRequest = URLRequest(url: url, method: method, headers: headers) urlRequest.httpBody = dataFile.data(using: .utf8) } catch let error { - completionHandler(files, error) + completionHandler(account, files, error) return } - AF.request(urlRequest).validate(statusCode: 200..<300).responseData { (response) in + sessionManagerData.request(urlRequest).validate(statusCode: 200..<300).responseData { (response) in switch response.result { case.failure(let error): - completionHandler(files, error) + completionHandler(account, files, error) case .success( _): if let data = response.data { let xml = XML.parse(data) @@ -308,23 +340,74 @@ class NCCommunication: SessionDelegate { isNotFirstFileOfList = true; files.append(file) } - completionHandler(files, nil) + completionHandler(account, files, nil) } else { - completionHandler(files, NSError(domain: NSCocoaErrorDomain, code: NSURLErrorBadServerResponse, userInfo: nil)) + completionHandler(account, files, NCCommunicationCommon.sharedInstance.getError(code: NSURLErrorBadServerResponse, description: "Response error decode XML")) } } } } + @objc public func setFavorite(urlString: String, fileName: String, favorite: Bool, account: String, completionHandler: @escaping (_ account: String, _ error: Error?) -> Void) { + + let dataFile = + """ + <?xml version=\"1.0\" encoding=\"UTF-8\"?> + <d:propfind xmlns:d=\"DAV:\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\"> + <d:set> + <d:prop> + <oc:favorite>%i</oc:favorite> + </d:prop> + </d:set> + </d:propertyupdate> + """ + let body = NSString.init(format: dataFile as NSString, (favorite ? 1 : 0)) as String + + // url + let serverUrlFileName = urlString + "/remote.php/dav/files/" + username + "/" + fileName + + guard let url = NCCommunicationCommon.sharedInstance.encodeUrlString(serverUrlFileName) else { + completionHandler(account, NCCommunicationCommon.sharedInstance.getError(code: NSURLErrorUnsupportedURL, description: "Invalid ServerUrl")) + return + } + + // method + let method = HTTPMethod(rawValue: "PROPPATCH") + + // headers + var headers: HTTPHeaders = [.authorization(username: self.username, password: self.password)] + if let userAgent = self.userAgent { headers.update(.userAgent(userAgent)) } + headers.update(.contentType("application/xml")) + + // request + var urlRequest: URLRequest + do { + try urlRequest = URLRequest(url: url, method: method, headers: headers) + urlRequest.httpBody = body.data(using: .utf8) + } catch let error { + completionHandler(account, error) + return + } + + sessionManagerData.request(urlRequest).validate(statusCode: 200..<300).responseData { (response) in + switch response.result { + case.failure(let error): + completionHandler(account, error) + case .success( _): + completionHandler(account, nil) + } + } + } + //MARK: - API - @objc func downloadPreview(serverUrl: String, fileNamePathSource: String, fileNamePathLocalDestination: String, width: CGFloat, height: CGFloat, completionHandler: @escaping (_ data: Data?, _ error: Error?) -> Void) { + @objc public func downloadPreview(serverUrl: String, fileNamePath: String, fileNamePathLocalDestination: String, width: CGFloat, height: CGFloat, account: String, completionHandler: @escaping (_ account: String, _ data: Data?, _ error: Error?) -> Void) { // url var serverUrl = String(serverUrl) if serverUrl.last != "/" { serverUrl = serverUrl + "/" } - serverUrl = serverUrl + "index.php/core/preview.png?file=" + fileNamePathSource + "&x=\(width)&y=\(height)&a=1&mode=cover" + serverUrl = serverUrl + "index.php/core/preview.png?file=" + fileNamePath + "&x=\(width)&y=\(height)&a=1&mode=cover" guard let url = NCCommunicationCommon.sharedInstance.encodeUrlString(serverUrl) else { - completionHandler(nil, NSError(domain: NSCocoaErrorDomain, code: NSURLErrorUnsupportedURL, userInfo: nil)) + completionHandler(account, nil, NCCommunicationCommon.sharedInstance.getError(code: NSURLErrorUnsupportedURL, description: "Invalid ServerUrl")) return } @@ -335,51 +418,143 @@ class NCCommunication: SessionDelegate { var headers: HTTPHeaders = [.authorization(username: self.username, password: self.password)] if let userAgent = self.userAgent { headers.update(.userAgent(userAgent)) } - AF.request(url, method: method, parameters:nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).response { (response) in + sessionManagerData.request(url, method: method, parameters:nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).response { (response) in switch response.result { case.failure(let error): - completionHandler(nil, error) + completionHandler(account, nil, error) case .success( _): if let data = response.data { do { let url = URL.init(fileURLWithPath: fileNamePathLocalDestination) try data.write(to: url, options: .atomic) - completionHandler(data, nil) + completionHandler(account, data, nil) } catch let error { - completionHandler(nil, error) + completionHandler(account, nil, error) } } else { - completionHandler(nil, NSError(domain: NSCocoaErrorDomain, code: NSURLErrorCannotDecodeContentData, userInfo: nil)) + completionHandler(account, nil, NCCommunicationCommon.sharedInstance.getError(code: NSURLErrorCannotDecodeContentData, description: "Response error data null")) } } } } - - //MARK: - Download - - @objc func download(serverUrl: String, fileName: String, fileNamePathDestination: String, completionHandler: @escaping (_ error: Error?) -> Void) { + @objc public func getExternalSite(urlString: String, account: String, completionHandler: @escaping (_ account: String, _ externalFiles: [NCExternalFile], _ error: Error?) -> Void) { + var externalFiles = [NCExternalFile]() + // url - var serverUrl = serverUrl - var url: URLConvertible - do { - if serverUrl.last == "/" { - serverUrl = serverUrl + fileName - } else { - serverUrl = serverUrl + "/" + fileName + var urlString = String(urlString) + if urlString.last != "/" { urlString = urlString + "/" } + urlString = urlString + "ocs/v2.php/apps/external/api/v1?format=json" + guard let url = NCCommunicationCommon.sharedInstance.encodeUrlString(urlString) else { + completionHandler(account, externalFiles, NCCommunicationCommon.sharedInstance.getError(code: NSURLErrorUnsupportedURL, description: "Invalid ServerUrl")) + return + } + + // method + let method = HTTPMethod(rawValue: "GET") + + // headers + var headers: HTTPHeaders = [.authorization(username: self.username, password: self.password)] + if let userAgent = self.userAgent { headers.update(.userAgent(userAgent)) } + + sessionManagerData.request(url, method: method, parameters:nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).responseJSON { (response) in + debugPrint(response) + switch response.result { + case.failure(let error): + completionHandler(account, externalFiles, error) + case .success(let json): + let json = JSON(json) + let ocsdata = json["ocs"]["data"] + for (_, subJson):(String, JSON) in ocsdata { + let extrernalFile = NCExternalFile() + if let id = subJson["id"].int { extrernalFile.idExternalSite = id } + if let name = subJson["name"].string { extrernalFile.name = name } + if let url = subJson["url"].string { extrernalFile.url = url } + if let lang = subJson["lang"].string { extrernalFile.lang = lang } + if let icon = subJson["icon"].string { extrernalFile.icon = icon } + if let type = subJson["type"].string { extrernalFile.type = type } + externalFiles.append(extrernalFile) + } + completionHandler(account, externalFiles, nil) } - try url = serverUrl.asURL() - } catch let error { - completionHandler(error) + } + } + + @objc public func getServerStatus(urlString: String, completionHandler: @escaping (_ serverProductName: String?, _ serverVersion: String? , _ versionMajor: Int, _ versionMinor: Int, _ versionMicro: Int, _ extendedSupport: Bool, _ error: Error?) -> Void) { + + // url + var urlString = String(urlString) + if urlString.last != "/" { urlString = urlString + "/" } + urlString = urlString + "status.php" + guard let url = NCCommunicationCommon.sharedInstance.encodeUrlString(urlString) else { + completionHandler(nil, nil, 0, 0, 0, false, NCCommunicationCommon.sharedInstance.getError(code: NSURLErrorUnsupportedURL, description: "Invalid ServerUrl")) return } + // method + let method = HTTPMethod(rawValue: "GET") + + // headers + var headers: HTTPHeaders = [.authorization(username: self.username, password: self.password)] + if let userAgent = self.userAgent { headers.update(.userAgent(userAgent)) } + headers.update(name: "OCS-APIRequest", value: "true") + + sessionManagerData.request(url, method: method, parameters:nil, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).responseJSON { (response) in + switch response.result { + case.failure(let error): + completionHandler(nil, nil, 0, 0, 0, false, error) + case .success(let json): + let json = JSON(json) + var versionMajor = 0, versionMinor = 0, versionMicro = 0 + + let serverProductName = json["productname"].string?.lowercased() + let serverVersion = json["version"].string + let serverVersionString = json["versionstring"].string + let extendedSupport = json["extendedSupport"].bool + + if let arrayVersion = serverVersion?.components(separatedBy: ".") { + if arrayVersion.count == 1 { + versionMajor = Int(arrayVersion[0]) ?? 0 + } else if arrayVersion.count == 2 { + versionMajor = Int(arrayVersion[0]) ?? 0 + versionMinor = Int(arrayVersion[1]) ?? 0 + } else if arrayVersion.count >= 3 { + versionMajor = Int(arrayVersion[0]) ?? 0 + versionMinor = Int(arrayVersion[1]) ?? 0 + versionMicro = Int(arrayVersion[2]) ?? 0 + } + } + + completionHandler(serverProductName, serverVersionString, versionMajor, versionMinor, versionMicro, extendedSupport!, nil) + } + } + } + //MARK: - File transfer + + @objc public func download(serverUrlFileName: String, fileNamePathLocalDestination: String, wwan: Bool, account: String, progressHandler: @escaping (_ progress: Progress) -> Void , completionHandler: @escaping (_ account: String, _ etag: String?, _ date: NSDate?, _ lenght: Double, _ error: Error?) -> Void) -> URLSessionTask? { + + // session + let sessionManager: Alamofire.Session + if wwan { + sessionManager = sessionManagerTransferWWan + sessionManager.session.sessionDescription = NCCommunicationCommon.sharedInstance.session_description_download_wwan + } else { + sessionManager = sessionManagerTransfer + sessionManager.session.sessionDescription = NCCommunicationCommon.sharedInstance.session_description_download + } + + // url + guard let url = NCCommunicationCommon.sharedInstance.encodeUrlString(serverUrlFileName) else { + completionHandler(account, nil, nil, 0, NCCommunicationCommon.sharedInstance.getError(code: NSURLErrorUnsupportedURL, description: "Invalid ServerUrl")) + return nil + } + // destination var destination: Alamofire.DownloadRequest.Destination? - if let fileNamePathDestinationURL = URL(string: fileNamePathDestination) { + if let fileNamePathLocalDestinationURL = URL(string: fileNamePathLocalDestination) { let destinationFile: DownloadRequest.Destination = { _, _ in - return (fileNamePathDestinationURL, [.removePreviousFile, .createIntermediateDirectories]) + return (fileNamePathLocalDestinationURL, [.removePreviousFile, .createIntermediateDirectories]) } destination = destinationFile } @@ -388,28 +563,103 @@ class NCCommunication: SessionDelegate { var headers: HTTPHeaders = [.authorization(username: self.username, password: self.password)] if let userAgent = self.userAgent { headers.update(.userAgent(userAgent)) } - AF.download(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil, to: destination).downloadProgress { progress in - //self.postProgress(progress: progress) - }.responseData { response in + let request = sessionManager.download(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers, interceptor: nil, to: destination) + .downloadProgress { progress in + progressHandler(progress) + } + .validate(statusCode: 200..<300) + .response { response in switch response.result { case.failure(let error): - completionHandler(error) + completionHandler(account, nil, nil, 0, error) case .success( _): - completionHandler(nil) + let lenght = response.response?.allHeaderFields["lenght"] as! Double + var etag = response.response?.allHeaderFields["OC-ETag"] as! String? + if etag != nil { etag = etag!.replacingOccurrences(of: "\"", with: "") } + if let dateString = response.response?.allHeaderFields["Date"] as! String? { + if let date = NCCommunicationCommon.sharedInstance.convertDate(dateString, format: "EEE, dd MMM y HH:mm:ss zzz") { + completionHandler(account, etag, date, lenght, nil) + } else { completionHandler(account, nil, nil, 0, NCCommunicationCommon.sharedInstance.getError(code: NSURLErrorBadServerResponse, description: "Response error decode date format")) } + } else { completionHandler(account, nil, nil, 0, NCCommunicationCommon.sharedInstance.getError(code: NSURLErrorBadServerResponse, description: "Response error decode date format")) } } } + + return request.task + } + + @objc public func upload(serverUrlFileName: String, fileNamePathSource: String, wwan: Bool, account: String, progressHandler: @escaping (_ progress: Progress) -> Void ,completionHandler: @escaping (_ account: String, _ ocId: String?, _ etag: String?, _ date: NSDate?, _ error: Error?) -> Void) -> URLSessionTask? { + + // session + let sessionManager: Alamofire.Session + if wwan { + sessionManager = sessionManagerTransferWWan + sessionManager.session.sessionDescription = NCCommunicationCommon.sharedInstance.session_description_upload_wwan + } else { + sessionManager = sessionManagerTransfer + sessionManager.session.sessionDescription = NCCommunicationCommon.sharedInstance.session_description_upload + } + + // url + guard let url = NCCommunicationCommon.sharedInstance.encodeUrlString(serverUrlFileName) else { + completionHandler(account, nil, nil, nil, NCCommunicationCommon.sharedInstance.getError(code: NSURLErrorUnsupportedURL, description: "Invalid ServerUrl")) + return nil + } + let fileNamePathSourceUrl = URL.init(fileURLWithPath: fileNamePathSource) + + // headers + var headers: HTTPHeaders = [.authorization(username: self.username, password: self.password)] + if let userAgent = self.userAgent { headers.update(.userAgent(userAgent)) } + + let request = sessionManager.upload(fileNamePathSourceUrl, to: url, method: .put, headers: headers, interceptor: nil, fileManager: .default) + .uploadProgress { progress in + progressHandler(progress) + } + .validate(statusCode: 200..<300) + .response { response in + switch response.result { + case.failure(let error): + completionHandler(account, nil, nil, nil, error) + case .success( _): + let ocId = response.response?.allHeaderFields["OC-FileId"] as! String? + var etag = response.response?.allHeaderFields["OC-ETag"] as! String? + if etag != nil { etag = etag!.replacingOccurrences(of: "\"", with: "") } + if let dateString = response.response?.allHeaderFields["Date"] as! String? { + if let date = NCCommunicationCommon.sharedInstance.convertDate(dateString, format: "EEE, dd MMM y HH:mm:ss zzz") { + completionHandler(account, ocId, etag, date, nil) + } else { completionHandler(account, nil, nil, nil, NCCommunicationCommon.sharedInstance.getError(code: NSURLErrorBadServerResponse, description: "Response error decode date format")) } + } else { completionHandler(account, nil, nil, nil, NCCommunicationCommon.sharedInstance.getError(code: NSURLErrorBadServerResponse, description: "Response error decode date format")) } + } + } + + return request.task } //MARK: - SessionDelegate - func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { - if CCCertificate.sharedManager().checkTrustedChallenge(challenge) { - completionHandler(URLSession.AuthChallengeDisposition.performDefaultHandling, URLCredential.init(trust: challenge.protectionSpace.serverTrust!)) - } else { + delegate?.urlSession(session, didReceive: challenge, completionHandler: { (authChallengeDisposition, credential) in + completionHandler(authChallengeDisposition, credential) + }) + + if delegate == nil { completionHandler(URLSession.AuthChallengeDisposition.performDefaultHandling, nil) } + + /* + if directoryCertificate == nil { + let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) + let documentsDirectory = paths[0] + directoryCertificate = documentsDirectory + "/certificate" + } + + if NCCommunicationCertificate.sharedInstance.checkTrustedChallenge(challenge: challenge, directoryCertificate: directoryCertificate!) { + completionHandler(URLSession.AuthChallengeDisposition.performDefaultHandling, URLCredential.init(trust: challenge.protectionSpace.serverTrust!)) + } else { + completionHandler(URLSession.AuthChallengeDisposition.performDefaultHandling, nil) + } + */ } } diff --git a/iOSClient/Networking/NCCommunicationCertificate.swift b/iOSClient/Networking/NCCommunicationCertificate.swift new file mode 100644 index 000000000..d22d85903 --- /dev/null +++ b/iOSClient/Networking/NCCommunicationCertificate.swift @@ -0,0 +1,95 @@ +// +// NCCommunicationCertificate.swift +// Nextcloud +// +// Created by Marino Faggiana on 18/10/19. +// Copyright © 2018 Marino Faggiana. All rights reserved. +// +// Author Marino Faggiana <marino.faggiana@nextcloud.com> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +import Foundation +import OpenSSL + +class NCCommunicationCertificate: NSObject { + @objc static let sharedInstance: NCCommunicationCertificate = { + let instance = NCCommunicationCertificate() + return instance + }() + + static func secTrustGetLeafCertificate(_ trust: SecTrust) -> SecCertificate? { + + let result: SecCertificate? + + if SecTrustGetCertificateCount(trust) > 0 { + result = SecTrustGetCertificateAtIndex(trust, 0)! + assert(result != nil); + } else { + result = nil + } + + return result + } + + func checkTrustedChallenge(challenge: URLAuthenticationChallenge, directoryCertificate: String) -> Bool { + + var trusted = false + let protectionSpace: URLProtectionSpace = challenge.protectionSpace + let directoryCertificateUrl = URL.init(fileURLWithPath: directoryCertificate) + + if let trust: SecTrust = protectionSpace.serverTrust { + saveCertificate(trust, certName: "tmp.der", directoryCertificate: directoryCertificate) + do { + // Get the directory contents urls (including subfolders urls) + let directoryContents = try FileManager.default.contentsOfDirectory(at: directoryCertificateUrl, includingPropertiesForKeys: nil) + print(directoryContents) + for file in directoryContents { + if FileManager.default.contentsEqual(atPath: directoryCertificate+"/"+"tmp.der", andPath: file.absoluteString) { + trusted = true + } + } + } catch { print(error) } + } + + return trusted + } + + private func saveCertificate(_ trust: SecTrust, certName: String, directoryCertificate: String) { + + let currentServerCert = NCCommunicationCertificate.secTrustGetLeafCertificate(trust) + let certNamePath = directoryCertificate + "/" + certName + let data: CFData = SecCertificateCopyData(currentServerCert!) + let mem = BIO_new_mem_buf(CFDataGetBytePtr(data), Int32(CFDataGetLength(data))) + let x509cert = d2i_X509_bio(mem, nil) + + BIO_free(mem) + if x509cert == nil { + print("[LOG] OpenSSL couldn't parse X509 Certificate") + } else { + if FileManager.default.fileExists(atPath: certNamePath) { + do { + try FileManager.default.removeItem(atPath: certNamePath) + } catch { } + } + let file = fopen(certNamePath, "w") + if file != nil { + PEM_write_X509(file, x509cert); + } + fclose(file); + X509_free(x509cert); + } + } +} diff --git a/iOSClient/Networking/NCCommunicationCommon.swift b/iOSClient/Networking/NCCommunicationCommon.swift index de47908d4..402acb0db 100755 --- a/iOSClient/Networking/NCCommunicationCommon.swift +++ b/iOSClient/Networking/NCCommunicationCommon.swift @@ -29,7 +29,14 @@ class NCCommunicationCommon: NSObject { let instance = NCCommunicationCommon() return instance }() - + + // Session + @objc let session_maximumConnectionsPerHost = 5 + @objc let session_description_download: String = "com.nextcloud.download.session" + @objc let session_description_download_wwan: String = "com.nextcloud.download.sessionwwan" + @objc let session_description_upload: String = "com.nextcloud.upload.session" + @objc let session_description_upload_wwan: String = "com.nextcloud.upload.sessionwwan" + func convertDate(_ dateString: String, format: String) -> NSDate? { let dateFormatter = DateFormatter() dateFormatter.locale = Locale.init(identifier: "en_US_POSIX") @@ -54,4 +61,9 @@ class NCCommunicationCommon: NSObject { } return nil } + + func getError(code: Int, description: String) -> Error { + + return NSError(domain: "Nextcloud", code: code, userInfo: [NSLocalizedDescriptionKey : description]) + } } diff --git a/iOSClient/Networking/NCCommunicationModel.swift b/iOSClient/Networking/NCCommunicationModel.swift index cf86fe54c..a05e8351f 100755 --- a/iOSClient/Networking/NCCommunicationModel.swift +++ b/iOSClient/Networking/NCCommunicationModel.swift @@ -25,31 +25,43 @@ import Foundation //MARK: - File -@objc class NCFile: NSObject { +@objc public class NCFile: NSObject { - @objc var commentsUnread: Bool = false - @objc var contentType = "" - @objc var date = NSDate() - @objc var directory: Bool = false - @objc var e2eEncrypted: Bool = false - @objc var etag = "" - @objc var favorite: Bool = false - @objc var fileId = "" - @objc var fileName = "" - @objc var hasPreview: Bool = false - @objc var mountType = "" - @objc var ocId = "" - @objc var ownerId = "" - @objc var ownerDisplayName = "" - @objc var path = "" - @objc var permissions = "" - @objc var quotaUsedBytes: Double = 0 - @objc var quotaAvailableBytes: Double = 0 - @objc var resourceType = "" - @objc var size: Double = 0 - @objc var trashbinFileName = "" - @objc var trashbinOriginalLocation = "" - @objc var trashbinDeletionTime = NSDate() + @objc public var commentsUnread: Bool = false + @objc public var contentType = "" + @objc public var date = NSDate() + @objc public var directory: Bool = false + @objc public var e2eEncrypted: Bool = false + @objc public var etag = "" + @objc public var favorite: Bool = false + @objc public var fileId = "" + @objc public var fileName = "" + @objc public var hasPreview: Bool = false + @objc public var mountType = "" + @objc public var ocId = "" + @objc public var ownerId = "" + @objc public var ownerDisplayName = "" + @objc public var path = "" + @objc public var permissions = "" + @objc public var quotaUsedBytes: Double = 0 + @objc public var quotaAvailableBytes: Double = 0 + @objc public var resourceType = "" + @objc public var size: Double = 0 + @objc public var trashbinFileName = "" + @objc public var trashbinOriginalLocation = "" + @objc public var trashbinDeletionTime = NSDate() } -//MARK: - +@objc public class NCExternalFile: NSObject { + + @objc public var idExternalSite: Int = 0 + @objc public var name = "" + @objc public var url = "" + @objc public var lang = "" + @objc public var icon = "" + @objc public var type = "" +} + + + + diff --git a/iOSClient/Settings/CCSettings.m b/iOSClient/Settings/CCSettings.m index 654e42805..a8b9ecfff 100644 --- a/iOSClient/Settings/CCSettings.m +++ b/iOSClient/Settings/CCSettings.m @@ -111,7 +111,6 @@ [form addFormSection:section]; // Dark Mode - /* if (@available(iOS 13.0, *)) { row = [XLFormRowDescriptor formRowDescriptorWithTag:@"darkModeDetect" rowType:XLFormRowDescriptorTypeBooleanSwitch title:[NSString stringWithFormat:@"%@ (beta)", NSLocalizedString(@"_dark_mode_detect_", nil)]]; row.cellConfigAtConfigure[@"backgroundColor"] = NCBrandColor.sharedInstance.backgroundView; @@ -122,17 +121,17 @@ else row.value = @0; [section addFormRow:row]; } - */ + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"darkMode" rowType:XLFormRowDescriptorTypeBooleanSwitch title:[NSString stringWithFormat:@"%@ (beta)", NSLocalizedString(@"_dark_mode_", nil)]]; row.cellConfigAtConfigure[@"backgroundColor"] = NCBrandColor.sharedInstance.backgroundView; [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"themeLightDark"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] forKey:@"imageView.image"]; [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; [row.cellConfig setObject:NCBrandColor.sharedInstance.textView forKey:@"textLabel.textColor"]; - /* + if (@available(iOS 13.0, *)) { row.hidden = [NSString stringWithFormat:@"$%@==1", @"darkModeDetect"]; } - */ + [section addFormRow:row]; // Section : E2EEncryption -------------------------------------------------------------- diff --git a/iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings b/iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings Binary files differindex 232af1b18..122ff92a5 100644 --- a/iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/pl.lproj/Localizable.strings b/iOSClient/Supporting Files/pl.lproj/Localizable.strings Binary files differindex 97ac1e259..553a0da78 100644 --- a/iOSClient/Supporting Files/pl.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/pl.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/sl.lproj/Localizable.strings b/iOSClient/Supporting Files/sl.lproj/Localizable.strings Binary files differnew file mode 100644 index 000000000..bc50570bf --- /dev/null +++ b/iOSClient/Supporting Files/sl.lproj/Localizable.strings diff --git a/kDrive.xcodeproj/project.pbxproj b/kDrive.xcodeproj/project.pbxproj index d6a7a9d0a..ac9881e1d 100755 --- a/kDrive.xcodeproj/project.pbxproj +++ b/kDrive.xcodeproj/project.pbxproj @@ -84,6 +84,9 @@ F718088D2341FEB20039A736 /* NCActionSheetAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F718088C2341FEB20039A736 /* NCActionSheetAppearance.swift */; }; F718088E2342067C0039A736 /* NCActionSheetAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F718088C2341FEB20039A736 /* NCActionSheetAppearance.swift */; }; F718088F2342067C0039A736 /* NCActionSheetAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F718088C2341FEB20039A736 /* NCActionSheetAppearance.swift */; }; + F72132C32359919400C201B5 /* NCCommunicationCertificate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F72132C22359919400C201B5 /* NCCommunicationCertificate.swift */; }; + F72132C42359919400C201B5 /* NCCommunicationCertificate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F72132C22359919400C201B5 /* NCCommunicationCertificate.swift */; }; + F72132C52359919400C201B5 /* NCCommunicationCertificate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F72132C22359919400C201B5 /* NCCommunicationCertificate.swift */; }; F7226EDC1EE4089300EBECB1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7226EDB1EE4089300EBECB1 /* Main.storyboard */; }; F72382C02295856A005B8A07 /* FirebaseMLVisionTextModel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F72382BB22958569005B8A07 /* FirebaseMLVisionTextModel.framework */; }; F72382C22295856A005B8A07 /* GoogleMVTextDetectorResources.bundle in Resources */ = {isa = PBXBuildFile; fileRef = F72382BE22958569005B8A07 /* GoogleMVTextDetectorResources.bundle */; }; @@ -93,8 +96,6 @@ F724B1CD2351BFBD00A5753B /* NCCommunicationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F724B1CB2351BFBD00A5753B /* NCCommunicationModel.swift */; }; F724B1CE2351BFBD00A5753B /* NCCommunicationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F724B1CB2351BFBD00A5753B /* NCCommunicationModel.swift */; }; F7267A82225DFCE100D6DB7D /* AFNetworking.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7267A81225DFCE100D6DB7D /* AFNetworking.framework */; }; - F7267A83225DFCE800D6DB7D /* AFNetworking.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7267A81225DFCE100D6DB7D /* AFNetworking.framework */; }; - F7267A84225DFCEC00D6DB7D /* AFNetworking.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7267A81225DFCE100D6DB7D /* AFNetworking.framework */; }; F726EEEC1FED1C820030B9C8 /* NCEndToEndInitialize.swift in Sources */ = {isa = PBXBuildFile; fileRef = F726EEEB1FED1C820030B9C8 /* NCEndToEndInitialize.swift */; }; F729B92B217A2E4E00FE2150 /* NCActionSheetHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F729B92A217A2E4E00FE2150 /* NCActionSheetHeaderView.xib */; }; F729B92D217A2F1B00FE2150 /* NCActionSheetHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F729B92C217A2F1B00FE2150 /* NCActionSheetHeaderView.swift */; }; @@ -548,6 +549,7 @@ F7D4B69A2295666E000C2C86 /* FirebaseMLCommon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7D4B6932295666E000C2C86 /* FirebaseMLCommon.framework */; }; F7D4B69B2295666E000C2C86 /* GoogleMobileVision.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7D4B6942295666E000C2C86 /* GoogleMobileVision.framework */; }; F7D6650720FF341600BFBA9E /* NCMainCommon.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7D6650620FF341600BFBA9E /* NCMainCommon.swift */; }; + F7D88011235CD46200867DD4 /* SwiftyJSON.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7D88010235CD46200867DD4 /* SwiftyJSON.framework */; }; F7DBC37C23325E02001A85BA /* NCAppConfigView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7DBC37B23325E01001A85BA /* NCAppConfigView.swift */; }; F7DBC37F23325E2E001A85BA /* NCXMLGetAppPasswordParser.m in Sources */ = {isa = PBXBuildFile; fileRef = F7DBC37E23325E2E001A85BA /* NCXMLGetAppPasswordParser.m */; }; F7DBC38023325E2E001A85BA /* NCXMLGetAppPasswordParser.m in Sources */ = {isa = PBXBuildFile; fileRef = F7DBC37E23325E2E001A85BA /* NCXMLGetAppPasswordParser.m */; }; @@ -671,6 +673,16 @@ name = "Embed App Extensions"; runOnlyForDeploymentPostprocessing = 0; }; + F7D88013235CD46200867DD4 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -764,6 +776,7 @@ F7169A301EE59BB70086BD69 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = "<group>"; }; F7169A4C1EE59C640086BD69 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = "<group>"; }; F718088C2341FEB20039A736 /* NCActionSheetAppearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCActionSheetAppearance.swift; sourceTree = "<group>"; }; + F72132C22359919400C201B5 /* NCCommunicationCertificate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCCommunicationCertificate.swift; sourceTree = "<group>"; }; F7226EDB1EE4089300EBECB1 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; }; F7229B491DF71BB300E8C4E7 /* AUTHORS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AUTHORS; sourceTree = SOURCE_ROOT; }; F72382BB22958569005B8A07 /* FirebaseMLVisionTextModel.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = FirebaseMLVisionTextModel.framework; sourceTree = "<group>"; }; @@ -1346,6 +1359,7 @@ F7D5328F1F5D443B006568B1 /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/Localizable.strings"; sourceTree = "<group>"; }; F7D532A41F5D4461006568B1 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; }; F7D6650620FF341600BFBA9E /* NCMainCommon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMainCommon.swift; sourceTree = "<group>"; }; + F7D88010235CD46200867DD4 /* SwiftyJSON.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftyJSON.framework; path = Carthage/Build/iOS/SwiftyJSON.framework; sourceTree = "<group>"; }; F7DBC37B23325E01001A85BA /* NCAppConfigView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCAppConfigView.swift; sourceTree = "<group>"; }; F7DBC37D23325E2D001A85BA /* NCXMLGetAppPasswordParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NCXMLGetAppPasswordParser.h; sourceTree = "<group>"; }; F7DBC37E23325E2E001A85BA /* NCXMLGetAppPasswordParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NCXMLGetAppPasswordParser.m; sourceTree = "<group>"; }; @@ -1441,7 +1455,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F7267A83225DFCE800D6DB7D /* AFNetworking.framework in Frameworks */, F7B6F70321BD0EA0007D194D /* JDStatusBarNotification.framework in Frameworks */, F7B6F70221BD0E6D007D194D /* MBProgressHUD.framework in Frameworks */, F7B6F70121BD0DD3007D194D /* DZNEmptyDataSet.framework in Frameworks */, @@ -1456,7 +1469,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F7267A84225DFCEC00D6DB7D /* AFNetworking.framework in Frameworks */, F7C40C152199BA750004137E /* Realm.framework in Frameworks */, F7C40C162199BA780004137E /* RealmSwift.framework in Frameworks */, F736B557234DCF92008A5C9F /* Alamofire.framework in Frameworks */, @@ -1482,6 +1494,7 @@ F75EDFBD1E8C112F00E6F369 /* libsqlite3.0.tbd in Frameworks */, F7A377161EB2364A002856D3 /* Crashlytics.framework in Frameworks */, F733B65221997CC2001C1FFA /* TLPhotoPicker.framework in Frameworks */, + F7D88011235CD46200867DD4 /* SwiftyJSON.framework in Frameworks */, F7D4B6872295663D000C2C86 /* FirebaseAnalytics.framework in Frameworks */, F7FC7D561DC1F93800BB2C6A /* libz.tbd in Frameworks */, F7C40BE9219991A60004137E /* EAIntroView.framework in Frameworks */, @@ -1906,6 +1919,7 @@ F736B54D234DCE43008A5C9F /* NCCommunication.swift */, F724B1CB2351BFBD00A5753B /* NCCommunicationModel.swift */, F7E8561A235202DF009A3330 /* NCCommunicationCommon.swift */, + F72132C22359919400C201B5 /* NCCommunicationCertificate.swift */, F732BA031D76CE1500E9878B /* CCNetworking.h */, F732BA041D76CE1500E9878B /* CCNetworking.m */, F74D3DBD1BAC1941000BAE4B /* OCNetworking.h */, @@ -2877,6 +2891,7 @@ F7FC7D541DC1F93700BB2C6A /* Frameworks */ = { isa = PBXGroup; children = ( + F7D88010235CD46200867DD4 /* SwiftyJSON.framework */, F7E856182351D7BE009A3330 /* SwiftyXMLParser.framework */, F736B551234DCF57008A5C9F /* Alamofire.framework */, F74C4FBA2328C3C100A23E25 /* OpenSSL.framework */, @@ -3005,6 +3020,7 @@ F73B02C01DC0F1C900EC2C33 /* ShellScript */, F7A377371EB24469002856D3 /* ShellScript */, F75A40001EBCB82B00B213E8 /* ShellScript */, + F7D88013235CD46200867DD4 /* Embed Frameworks */, ); buildRules = ( ); @@ -3340,6 +3356,7 @@ "$(SRCROOT)/Carthage/Build/iOS/OpenSSL.framework", "$(SRCROOT)/Carthage/Build/iOS/Alamofire.framework", "$(SRCROOT)/Carthage/Build/iOS/SwiftyXMLParser.framework", + "$(SRCROOT)/Carthage/Build/iOS/SwiftyJSON.framework", ); outputPaths = ( ); @@ -3377,6 +3394,7 @@ F70022C01EC4C9100080073F /* OCFileDto.m in Sources */, F71459C21D12E3B700CAFEEC /* ShareViewController.m in Sources */, F77EB6281EC08036003F814F /* CCExifGeo.m in Sources */, + F72132C42359919400C201B5 /* NCCommunicationCertificate.swift in Sources */, F73CC0731E813DFF006E3047 /* BKPasscodeLockScreenManager.m in Sources */, F73CC06A1E813DFF006E3047 /* BKPasscodeDummyViewController.m in Sources */, F7E8561C235202DF009A3330 /* NCCommunicationCommon.swift in Sources */, @@ -3487,6 +3505,7 @@ F7434B6020E2445200417916 /* CCExifGeo.m in Sources */, F7E8561D235202DF009A3330 /* NCCommunicationCommon.swift in Sources */, F7434B5420E240A300417916 /* NSString+Encode.m in Sources */, + F72132C52359919400C201B5 /* NCCommunicationCertificate.swift in Sources */, F7434B4E20E2408A00417916 /* OCWebDAVClient.m in Sources */, F771E3F820E239B500AFB62D /* FileProviderExtension+Thumbnail.swift in Sources */, F7434B4D20E2408600417916 /* OCHTTPRequestOperation.m in Sources */, @@ -3633,6 +3652,7 @@ F762CB171EACB66200B38484 /* XLFormRegexValidator.m in Sources */, F729B92D217A2F1B00FE2150 /* NCActionSheetHeaderView.swift in Sources */, F760F78721F21F61006B1A73 /* PhotoEditor+Font.swift in Sources */, + F72132C32359919400C201B5 /* NCCommunicationCertificate.swift in Sources */, F73CC0691E813DFF006E3047 /* BKPasscodeDummyViewController.m in Sources */, F762CB1A1EACB66200B38484 /* XLForm.m in Sources */, F73B4EFC1F470D9100BBEE4B /* LangGreekModel.cpp in Sources */, @@ -3874,7 +3894,7 @@ CODE_SIGN_ENTITLEMENTS = iOSClient/Brand/Share.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 3; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 864VDCS2QY; FRAMEWORK_SEARCH_PATHS = ( @@ -3918,7 +3938,7 @@ CODE_SIGN_ENTITLEMENTS = iOSClient/Brand/Share.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 3; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 864VDCS2QY; FRAMEWORK_SEARCH_PATHS = ( @@ -3968,7 +3988,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 3; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 864VDCS2QY; FRAMEWORK_SEARCH_PATHS = ( @@ -4018,7 +4038,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 3; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 864VDCS2QY; FRAMEWORK_SEARCH_PATHS = ( @@ -4060,7 +4080,7 @@ CODE_SIGN_ENTITLEMENTS = iOSClient/Brand/iOSClient.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = 864VDCS2QY; ENABLE_BITCODE = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -4107,7 +4127,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = 864VDCS2QY; ENABLE_BITCODE = YES; FRAMEWORK_SEARCH_PATHS = ( diff --git a/kDrive.xcodeproj/xcshareddata/xcschemes/kDrive.xcscheme b/kDrive.xcodeproj/xcshareddata/xcschemes/kDrive.xcscheme index 6c5f638d6..076cac110 100644 --- a/kDrive.xcodeproj/xcshareddata/xcschemes/kDrive.xcscheme +++ b/kDrive.xcodeproj/xcshareddata/xcschemes/kDrive.xcscheme @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <Scheme LastUpgradeVersion = "1020" - version = "1.3"> + version = "1.7"> <BuildAction parallelizeBuildables = "YES" buildImplicitDependencies = "YES"> @@ -59,6 +59,10 @@ ReferencedContainer = "container:kDrive.xcodeproj"> </BuildableReference> </BuildableProductRunnable> + <LocationScenarioReference + identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier" + referenceType = "1"> + </LocationScenarioReference> </LaunchAction> <ProfileAction buildConfiguration = "Release" |