Browse Source

new version

marinofaggiana 5 years ago
parent
commit
7076865ec2
54 changed files with 1073 additions and 1536 deletions
  1. 1 3
      Cartfile
  2. 2 0
      Cartfile.resolved
  3. 33 19
      File Provider Extension/FileProviderData.swift
  4. 29 14
      File Provider Extension/FileProviderDomain.swift
  5. 76 94
      File Provider Extension/FileProviderEnumerator.swift
  6. 33 110
      File Provider Extension/FileProviderExtension+Actions.swift
  7. 72 0
      File Provider Extension/FileProviderExtension+NetworkingDelegate.swift
  8. 14 24
      File Provider Extension/FileProviderExtension+Thumbnail.swift
  9. 0 1
      File Provider Extension/FileProviderExtension-Bridging-Header.h
  10. 131 139
      File Provider Extension/FileProviderExtension.swift
  11. 109 68
      File Provider Extension/FileProviderItem.swift
  12. 25 38
      Nextcloud.xcodeproj/project.pbxproj
  13. 0 1
      Share/NCSelectDestination.h
  14. 26 48
      Share/NCSelectDestination.m
  15. 0 1
      Share/Share-Bridging-Header.h
  16. 0 8
      Share/ShareViewController.h
  17. 20 27
      Share/ShareViewController.m
  18. 22 2
      iOSClient/AppDelegate.m
  19. 1 1
      iOSClient/Brand/File_Provider_Extension.plist
  20. 1 1
      iOSClient/Brand/Share.plist
  21. 1 1
      iOSClient/Brand/iOSClient.plist
  22. 4 5
      iOSClient/CCGlobal.h
  23. 0 5
      iOSClient/Database/NCDatabase.swift
  24. 101 97
      iOSClient/Database/NCManageDatabase.swift
  25. 56 2
      iOSClient/Favorites/CCFavorites.m
  26. 15 0
      iOSClient/Images.xcassets/microphone_off.imageset/Contents.json
  27. BIN
      iOSClient/Images.xcassets/microphone_off.imageset/microphone_off.pdf
  28. 1 2
      iOSClient/Login/CCLogin.h
  29. 17 15
      iOSClient/Login/CCLogin.m
  30. 10 5
      iOSClient/Main/CCMain.m
  31. 4 2
      iOSClient/Main/NCMainCommon.swift
  32. 16 14
      iOSClient/Main/NCPhotosPickerViewController.swift
  33. 26 4
      iOSClient/Networking/CCNetworking.h
  34. 0 372
      iOSClient/Networking/NCCommunication.swift
  35. 0 55
      iOSClient/Networking/NCCommunicationModel.swift
  36. 202 0
      iOSClient/Networking/NCNetworking.swift
  37. 0 1
      iOSClient/Networking/NCNetworkingEndToEnd.h
  38. 5 6
      iOSClient/Networking/NCService.swift
  39. 0 43
      iOSClient/Networking/NSCommunicationCommon.swift
  40. 2 3
      iOSClient/Networking/OCNetworking.h
  41. 4 47
      iOSClient/Networking/OCNetworking.m
  42. 0 1
      iOSClient/Nextcloud-Bridging-Header.h
  43. 0 47
      iOSClient/Notification/CCNotification.storyboard
  44. 0 199
      iOSClient/Security/CCCertificate.m
  45. 3 4
      iOSClient/Settings/CCSettings.m
  46. 4 2
      iOSClient/Share/NCSharePaging.swift
  47. BIN
      iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings
  48. BIN
      iOSClient/Supporting Files/pl.lproj/Localizable.strings
  49. BIN
      iOSClient/Supporting Files/sl.lproj/Localizable.strings
  50. BIN
      iOSClient/Supporting Files/sv.lproj/Localizable.strings
  51. BIN
      iOSClient/Supporting Files/tr.lproj/Localizable.strings
  52. 2 0
      iOSClient/Utility/CCUtility.h
  53. 5 0
      iOSClient/Utility/CCUtility.m
  54. 0 5
      iOSClient/Viewer/NCViewerRichdocument.swift

+ 1 - 3
Cartfile

@@ -1,3 +1,4 @@
+github "nextcloud/ios-communication-library" "develop"
 github "tilltue/TLPhotoPicker" "1.9.3"
 github "kishikawakatsumi/UICKeyChainStore" "v2.1.2"
 github "danielsaidi/Sheeeeeeeeet" "2.0.2"
@@ -17,9 +18,6 @@ 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 "https://github.com/marinofaggiana/FastScroll" "master"
 github "https://github.com/marinofaggiana/AFNetworking" "master"
-

+ 2 - 0
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"
@@ -17,6 +18,7 @@ github "krzyzanowskim/OpenSSL" "1.0.218"
 github "malcommac/SwiftRichString" "3.0.3"
 github "marinofaggiana/AFNetworking" "2967678c3e0e98c9b8d7e06222ad12d1f49c26f2"
 github "marinofaggiana/FastScroll" "81967c2309d29bc2c330d422da612160a30bade8"
+github "nextcloud/ios-communication-library" "2dc7adbf5dd2cd64f62dff3888ea49d367e06fc0"
 github "realm/realm-cocoa" "v3.17.3"
 github "rechsteiner/Parchment" "v1.7.0"
 github "tilltue/TLPhotoPicker" "1.9.3"

+ 33 - 19
File Provider Extension/FileProviderData.swift

@@ -21,6 +21,8 @@
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //
 
+import NCCommunication
+
 class fileProviderData: NSObject {
     @objc static let sharedInstance: fileProviderData = {
         let instance = fileProviderData()
@@ -55,28 +57,37 @@ class fileProviderData: NSObject {
     // UserDefaults
     var ncUserDefaults = UserDefaults(suiteName: NCBrandOptions.sharedInstance.capabilitiesGroups)
     
+    // Error
+    enum FileProviderError: Error {
+        case downloadError
+        case uploadError
+    }
+    
     // MARK: - 
     
-    func setupActiveAccount(domain: String?) -> Bool {
+    func setupActiveAccount(domain: String?, providerExtension: NSFileProviderExtension) -> Bool {
         
         var foundAccount: Bool = false
         
         if CCUtility.getDisableFilesApp() || NCBrandOptions.sharedInstance.disable_openin_file {
             return false
         }
-        
+                
         // NO DOMAIN -> Set default account
         if domain == nil {
             
-            guard let tableAccounts = NCManageDatabase.sharedInstance.getAccountActive() else { return false }
+            guard let tableAccount = NCManageDatabase.sharedInstance.getAccountActive() else { return false }
+            
+            account = tableAccount.account
+            accountUser = tableAccount.user
+            accountUserID = tableAccount.userID
+            accountPassword = CCUtility.getPassword(tableAccount.account)
+            accountUrl = tableAccount.url
+            homeServerUrl = CCUtility.getHomeServerUrlActiveUrl(tableAccount.url)
+            
+            NCCommunicationCommon.sharedInstance.setup(username: accountUserID, password: accountPassword, userAgent: CCUtility.getUserAgent(), capabilitiesGroup: NCBrandOptions.sharedInstance.capabilitiesGroups, delegate: NCNetworking.sharedInstance)
+            NCNetworking.sharedInstance.setup(account: tableAccount.account, delegate: providerExtension as? NCNetworkingDelegate)
             
-            account = tableAccounts.account
-            accountUser = tableAccounts.user
-            accountUserID = tableAccounts.userID
-            accountPassword = CCUtility.getPassword(tableAccounts.account)
-            accountUrl = tableAccounts.url
-            homeServerUrl = CCUtility.getHomeServerUrlActiveUrl(tableAccounts.url)
-    
             return true
         }
         
@@ -96,6 +107,9 @@ class fileProviderData: NSObject {
                 accountUrl = tableAccount.url
                 homeServerUrl = CCUtility.getHomeServerUrlActiveUrl(tableAccount.url)
                 
+                NCCommunicationCommon.sharedInstance.setup(username: accountUserID, password: accountPassword, userAgent: CCUtility.getUserAgent(), capabilitiesGroup: NCBrandOptions.sharedInstance.capabilitiesGroups, delegate: NCNetworking.sharedInstance)
+                NCNetworking.sharedInstance.setup(account: tableAccount.account, delegate: providerExtension as? NCNetworkingDelegate)
+
                 foundAccount = true
             }
         }
@@ -103,7 +117,7 @@ class fileProviderData: NSObject {
         return foundAccount
     }
     
-    func setupActiveAccount(itemIdentifier: NSFileProviderItemIdentifier) -> Bool {
+    func setupActiveAccount(itemIdentifier: NSFileProviderItemIdentifier, providerExtension: NSFileProviderExtension) -> Bool {
         
         var foundAccount: Bool = false
 
@@ -121,6 +135,9 @@ class fileProviderData: NSObject {
                 accountUrl = tableAccount.url
                 homeServerUrl = CCUtility.getHomeServerUrlActiveUrl(tableAccount.url)
                 
+                NCCommunicationCommon.sharedInstance.setup(username: accountUserID, password: accountPassword, userAgent: CCUtility.getUserAgent(), capabilitiesGroup: NCBrandOptions.sharedInstance.capabilitiesGroups, delegate: NCNetworking.sharedInstance)
+                NCNetworking.sharedInstance.setup(account: tableAccount.account, delegate: providerExtension as? NCNetworkingDelegate)
+                
                 foundAccount = true
             }
         }
@@ -139,15 +156,12 @@ class fileProviderData: NSObject {
         // (ADD)
         for (identifier, _) in listFavoriteIdentifierRank {
             
-            if !oldListFavoriteIdentifierRank.keys.contains(identifier) {
-            
-                guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", identifier)) else { continue }
-                guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadata, homeServerUrl: homeServerUrl) else { continue }
-                let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier)
+            guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", identifier)) else { continue }
+            guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadata, homeServerUrl: homeServerUrl) else { continue }
+            let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier)
                 
-                fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
-                updateWorkingSet = true
-            }
+            fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
+            updateWorkingSet = true
         }
         
         // (REMOVE)

+ 29 - 14
File Provider Extension/FileProviderDomain.swift

@@ -29,9 +29,7 @@ class FileProviderDomain: NSObject {
         return instance
     }()
 
-    @available(iOS 11.0, *)
-    
-    @objc func registerDomain() {
+    @available(iOS 11.0, *) @objc func registerDomain() {
         
         NSFileProviderManager.getDomainsWithCompletionHandler { (fileProviderDomain, error) in
             
@@ -43,6 +41,16 @@ class FileProviderDomain: NSObject {
                 domains.append(domain.identifier.rawValue)
             }
             
+            // Delete all domains
+            for domain in domains {
+                let domainRawValue = NSFileProviderDomain(identifier: NSFileProviderDomainIdentifier(rawValue: domain), displayName: domain, pathRelativeToDocumentStorage: pathRelativeToDocumentStorage)
+                NSFileProviderManager.remove(domainRawValue, completionHandler: { (error) in
+                    if error != nil {
+                        print("Error  domain: \(domainRawValue) error: \(String(describing: error))")
+                    }
+                })
+            }
+            
             // Check account->domain & (add)
             for tableAccount in tableAccounts {
                 guard let url = NSURL(string: tableAccount.url) else {
@@ -52,19 +60,26 @@ class FileProviderDomain: NSObject {
                     continue
                 }
                 let accountDomain =  tableAccount.userID + " (" + host + ")"
-                if domains.contains(accountDomain) {
-                    domains = domains.filter() {$0 != accountDomain}
-                } else {
-                    let domainRawValue = NSFileProviderDomain(identifier: NSFileProviderDomainIdentifier(rawValue: accountDomain), displayName: accountDomain, pathRelativeToDocumentStorage: pathRelativeToDocumentStorage)
-                    NSFileProviderManager.add(domainRawValue, completionHandler: { (error) in
-                        if error != nil {
-                            print("Error  domain: \(domainRawValue) error: \(String(describing: error))")
-                        }
-                    })
-                }
+                let domainRawValue = NSFileProviderDomain(identifier: NSFileProviderDomainIdentifier(rawValue: accountDomain), displayName: accountDomain, pathRelativeToDocumentStorage: pathRelativeToDocumentStorage)
+                NSFileProviderManager.add(domainRawValue, completionHandler: { (error) in
+                    if error != nil {
+                        print("Error  domain: \(domainRawValue) error: \(String(describing: error))")
+                    }
+                })
             }
+        }
+    }
+    
+    @available(iOS 11.0, *) @objc func removeAllDomain() {
+        
+        NSFileProviderManager.getDomainsWithCompletionHandler { (fileProviderDomain, error) in
             
-            // Check if remove domain
+            var domains = [String]()
+            let pathRelativeToDocumentStorage = NSFileProviderManager.default.documentStorageURL.absoluteString
+
+            for domain in fileProviderDomain {
+                domains.append(domain.identifier.rawValue)
+            }
             for domain in domains {
                 let domainRawValue = NSFileProviderDomain(identifier: NSFileProviderDomainIdentifier(rawValue: domain), displayName: domain, pathRelativeToDocumentStorage: pathRelativeToDocumentStorage)
                 NSFileProviderManager.remove(domainRawValue, completionHandler: { (error) in

+ 76 - 94
File Provider Extension/FileProviderEnumerator.swift

@@ -22,6 +22,7 @@
 //
 
 import FileProvider
+import NCCommunication
 
 class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
     
@@ -125,70 +126,54 @@ 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
-
-                if errorCode == 0 && account == fileProviderData.sharedInstance.account {
-                    
-                    if fileProviderData.sharedInstance.listServerUrlEtag[serverUrl] == nil || fileProviderData.sharedInstance.listServerUrlEtag[serverUrl] != metadata!.etag || metadatasFromDB == nil {
+            NCCommunication.sharedInstance.readFileOrFolder(serverUrlFileName: serverUrl, depth: "0", account: fileProviderData.sharedInstance.account, completionHandler: { (account, files, errorCode, errorDescription) in
+                
+                var etag = ""
+                let etagServerUrl = fileProviderData.sharedInstance.listServerUrlEtag[serverUrl]
+                if errorCode == 0 && files != nil && files!.count == 1 { etag = files![0].etag }
+                
+                if etag != etagServerUrl {
+                                
+                    NCCommunication.sharedInstance.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", account: fileProviderData.sharedInstance.account, completionHandler: { (account, files, errorCode, errorDescription) in
                         
-                        OCNetworking.sharedManager().readFolder(withAccount: fileProviderData.sharedInstance.account, serverUrl: serverUrl, depth: "1", completion: { (account, metadatas, metadataFolder, message, errorCode) in
+                        if errorCode == 0 && files != nil  && files!.count >= 1 {
                             
-                            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)
+                            let file = files![0]
+
+                            // 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
+                            
+                            NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d)", account, serverUrl, k_metadataStatusNormal, k_metadataStatusHide))
                                 
-                            } else if errorCode != 0 {
+                            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)
+                             
+                            let metadatasInUpload = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d OR status == %d OR status == %d)", account, serverUrl, k_metadataStatusWaitUpload, k_metadataStatusInUpload, k_metadataStatusUploading, k_metadataStatusUploadError), sorted: nil, ascending: false)
+                           
+                            NCManageDatabase.sharedInstance.addMetadatas(files: files!, account: account, serverUrl: serverUrl, removeFirst: true)
+                            
+                            if metadatasInDownload != nil {
+                                _ = NCManageDatabase.sharedInstance.addMetadatas(metadatasInDownload!)
                             }
-                        })
-                        
-                    } else {
-                        
-                        self.selectFirstPageItems(metadatasFromDB, observer: observer)
-                    }
+                            if metadatasInUpload != nil {
+                                _ = NCManageDatabase.sharedInstance.addMetadatas(metadatasInUpload!)
+                            }
+                            
+                            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)
+                        }
+                    })
                     
                 } else {
+                    
                     self.selectFirstPageItems(metadatasFromDB, observer: observer)
                 }
             })
@@ -197,44 +182,42 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
     
     func enumerateChanges(for observer: NSFileProviderChangeObserver, from anchor: NSFileProviderSyncAnchor) {
         
-        DispatchQueue.main.async {
-            var itemsDelete = [NSFileProviderItemIdentifier]()
-            var itemsUpdate = [FileProviderItem]()
-            
-            // Report the deleted items
-            //
-            if self.enumeratedItemIdentifier == .workingSet {
-                for (itemIdentifier, _) in fileProviderData.sharedInstance.fileProviderSignalDeleteWorkingSetItemIdentifier {
-                    itemsDelete.append(itemIdentifier)
-                }
-                fileProviderData.sharedInstance.fileProviderSignalDeleteWorkingSetItemIdentifier.removeAll()
-            } else {
-                for (itemIdentifier, _) in fileProviderData.sharedInstance.fileProviderSignalDeleteContainerItemIdentifier {
-                    itemsDelete.append(itemIdentifier)
-                }
-                fileProviderData.sharedInstance.fileProviderSignalDeleteContainerItemIdentifier.removeAll()
+        var itemsDelete = [NSFileProviderItemIdentifier]()
+        var itemsUpdate = [FileProviderItem]()
+        
+        // Report the deleted items
+        //
+        if self.enumeratedItemIdentifier == .workingSet {
+            for (itemIdentifier, _) in fileProviderData.sharedInstance.fileProviderSignalDeleteWorkingSetItemIdentifier {
+                itemsDelete.append(itemIdentifier)
             }
-            
-            // Report the updated items
-            //
-            if self.enumeratedItemIdentifier == .workingSet {
-                for (_, item) in fileProviderData.sharedInstance.fileProviderSignalUpdateWorkingSetItem {
-                    itemsUpdate.append(item)
-                }
-                fileProviderData.sharedInstance.fileProviderSignalUpdateWorkingSetItem.removeAll()
-            } else {
-                for (_, item) in fileProviderData.sharedInstance.fileProviderSignalUpdateContainerItem {
-                    itemsUpdate.append(item)
-                }
-                fileProviderData.sharedInstance.fileProviderSignalUpdateContainerItem.removeAll()
+            fileProviderData.sharedInstance.fileProviderSignalDeleteWorkingSetItemIdentifier.removeAll()
+        } else {
+            for (itemIdentifier, _) in fileProviderData.sharedInstance.fileProviderSignalDeleteContainerItemIdentifier {
+                itemsDelete.append(itemIdentifier)
             }
-            
-            observer.didDeleteItems(withIdentifiers: itemsDelete)
-            observer.didUpdate(itemsUpdate)
-            
-            let data = "\(fileProviderData.sharedInstance.currentAnchor)".data(using: .utf8)
-            observer.finishEnumeratingChanges(upTo: NSFileProviderSyncAnchor(data!), moreComing: false)
+            fileProviderData.sharedInstance.fileProviderSignalDeleteContainerItemIdentifier.removeAll()
         }
+        
+        // Report the updated items
+        //
+        if self.enumeratedItemIdentifier == .workingSet {
+            for (_, item) in fileProviderData.sharedInstance.fileProviderSignalUpdateWorkingSetItem {
+                itemsUpdate.append(item)
+            }
+            fileProviderData.sharedInstance.fileProviderSignalUpdateWorkingSetItem.removeAll()
+        } else {
+            for (_, item) in fileProviderData.sharedInstance.fileProviderSignalUpdateContainerItem {
+                itemsUpdate.append(item)
+            }
+            fileProviderData.sharedInstance.fileProviderSignalUpdateContainerItem.removeAll()
+        }
+        
+        observer.didDeleteItems(withIdentifiers: itemsDelete)
+        observer.didUpdate(itemsUpdate)
+        
+        let data = "\(fileProviderData.sharedInstance.currentAnchor)".data(using: .utf8)
+        observer.finishEnumeratingChanges(upTo: NSFileProviderSyncAnchor(data!), moreComing: false)
     }
     
     func currentSyncAnchor(completionHandler: @escaping (NSFileProviderSyncAnchor?) -> Void) {
@@ -273,8 +256,7 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
             
             for metadata in metadatas {
                 
-                // E2EE Remove
-                if metadata.e2eEncrypted || metadata.status == Int(k_metadataStatusHide) || (metadata.session != "" && metadata.session != k_download_session_extension && metadata.session != k_upload_session_extension) { continue }
+                if metadata.e2eEncrypted || metadata.status == Int(k_metadataStatusHide) || (metadata.session != "" && metadata.session != k_upload_session_extension) { continue }
                 
                 counter += 1
                 if (counter >= start && counter <= stop) {

+ 33 - 110
File Provider Extension/FileProviderExtension+Actions.swift

@@ -22,6 +22,7 @@
 //
 
 import FileProvider
+import NCCommunication
 
 extension FileProviderExtension {
 
@@ -32,20 +33,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, errorCode, errorDescription) in
             
-            if errorCode == 0 && account == fileProviderData.sharedInstance.account {
+            if errorCode == 0 {
                 
                 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 +54,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 +66,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 +80,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, errorCode, errorDescription) in
+            
+            if errorCode == 0 { //|| error == kOCErrorServerPathNotFound {
+            
                 let fileNamePath = CCUtility.getDirectoryProviderStorageOcId(itemIdentifier.rawValue)!
                 do {
                     try fileProviderUtility.sharedInstance.fileManager.removeItem(atPath: fileNamePath)
@@ -89,7 +95,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 +106,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 +132,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, errorCode, errorDescription) in
+       
+            if errorCode == 0 {
                 
                 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 +154,7 @@ extension FileProviderExtension {
             } else {
                 completionHandler(nil, NSFileProviderError(.serverUnreachable))
             }
-        })
+        }
     }
     
     override func renameItem(withIdentifier itemIdentifier: NSFileProviderItemIdentifier, toName itemName: String, completionHandler: @escaping (NSFileProviderItem?, Error?) -> Void) {
@@ -167,9 +173,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, errorCode, errorDescription) in
+       
+            if errorCode == 0 {
                 
                 // Rename metadata
                 guard let metadata = NCManageDatabase.sharedInstance.renameMetadata(fileNameTo: itemName, ocId: metadata.ocId) else {
@@ -179,7 +185,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 +209,7 @@ extension FileProviderExtension {
             } else {
                 completionHandler(nil, NSFileProviderError(.serverUnreachable))
             }
-        })
+        }
     }
     
     override func setFavoriteRank(_ favoriteRank: NSNumber?, forItemIdentifier itemIdentifier: NSFileProviderItemIdentifier, completionHandler: @escaping (NSFileProviderItem?, Error?) -> Void) {
@@ -230,10 +236,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, errorCode, errorDescription) in
+                if errorCode == 0 {
                     // Change DB
                     metadata.favorite = favorite
                     guard let metadataUpdate = NCManageDatabase.sharedInstance.addMetadata(metadata) else {
@@ -246,18 +252,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))
                 }
-            })
+            }
         }
     }
     
@@ -297,88 +302,6 @@ extension FileProviderExtension {
         }
         
         let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier)
-        item.lastUsedDate = lastUsedDate
-
         completionHandler(item, nil)
     }
-    
-    override func importDocument(at fileURL: URL, toParentItemIdentifier parentItemIdentifier: NSFileProviderItemIdentifier, completionHandler: @escaping (NSFileProviderItem?, Error?) -> Void) {
-                
-        DispatchQueue.main.async {
-            
-            autoreleasepool {
-            
-                var size = 0 as Double
-                var error: NSError?
-                
-                guard let tableDirectory = fileProviderUtility.sharedInstance.getTableDirectoryFromParentItemIdentifier(parentItemIdentifier, account: fileProviderData.sharedInstance.account, homeServerUrl: fileProviderData.sharedInstance.homeServerUrl) else {
-                    completionHandler(nil, NSFileProviderError(.noSuchItem))
-                    return
-                }
-                
-                if fileURL.startAccessingSecurityScopedResource() == false {
-                    completionHandler(nil, NSFileProviderError(.noSuchItem))
-                    return
-                }
-                
-                // typefile directory ? (NOT PERMITTED)
-                do {
-                    let attributes = try fileProviderUtility.sharedInstance.fileManager.attributesOfItem(atPath: fileURL.path)
-                    size = attributes[FileAttributeKey.size] as! Double
-                    let typeFile = attributes[FileAttributeKey.type] as! FileAttributeType
-                    if typeFile == FileAttributeType.typeDirectory {
-                        completionHandler(nil, NSFileProviderError(.noSuchItem))
-                        return
-                    }
-                } catch {
-                    completionHandler(nil, NSFileProviderError(.noSuchItem))
-                    return
-                }
-        
-                let fileName = NCUtility.sharedInstance.createFileName(fileURL.lastPathComponent, serverUrl: tableDirectory.serverUrl, account: fileProviderData.sharedInstance.account)
-                let fileNameServerUrl = tableDirectory.serverUrl + "/" + fileName
-                let fileTemporaryDirectory = NSTemporaryDirectory() + fileName
-                
-                self.fileCoordinator.coordinate(readingItemAt: fileURL, options: .withoutChanges, error: &error) { (url) in
-                    _ = fileProviderUtility.sharedInstance.copyFile(url.path, toPath: fileTemporaryDirectory)
-                }
-                
-                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 {
-                        
-                        _ = fileProviderUtility.sharedInstance.moveFile(fileTemporaryDirectory, toPath: CCUtility.getDirectoryProviderStorageOcId(ocId, fileNameView: fileName))
-                        
-                        let metadata = tableMetadata()
-                        metadata.account = fileProviderData.sharedInstance.account
-                        metadata.date = date! as NSDate
-                        metadata.directory = false
-                        metadata.etag = etag!
-                        metadata.ocId = ocId!
-                        metadata.fileName = fileName
-                        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))
-                    }                   
-                })
-            }
-        }
-    }
 }

+ 72 - 0
File Provider Extension/FileProviderExtension+NetworkingDelegate.swift

@@ -0,0 +1,72 @@
+//
+//  FileProviderExtension+NetworkingDelegate.swift
+//  File Provider Extension
+//
+//  Created by Marino Faggiana on 02/11/2019.
+//  Copyright © 2019 TWS. All rights reserved.
+//
+
+import FileProvider
+import NCCommunication
+
+extension FileProviderExtension: NCNetworkingDelegate {
+
+    func uploadComplete(fileName: String, serverUrl: String, ocId: String?, etag: String?, date: NSDate?, description: String?, error: Error?, statusCode: Int) {
+                
+        guard let ocIdTemp = description else { return }
+        guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdTemp)) else { return }
+        
+        let url = URL(fileURLWithPath: CCUtility.getDirectoryProviderStorageOcId(ocIdTemp, fileNameView: fileName))
+        outstandingSessionTasks.removeValue(forKey: url)
+        outstandingOcIdTemp[ocIdTemp] = ocId
+        
+        if error == nil && statusCode >= 200 && statusCode < 300 {
+            
+            guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadata, homeServerUrl: fileProviderData.sharedInstance.homeServerUrl) else {
+                return
+            }
+            var item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier)
+            
+            // New file
+            if ocId != ocIdTemp {
+                
+                fileProviderData.sharedInstance.fileProviderSignalDeleteContainerItemIdentifier[item.itemIdentifier] = item.itemIdentifier
+                fileProviderData.sharedInstance.fileProviderSignalDeleteWorkingSetItemIdentifier[item.itemIdentifier] = item.itemIdentifier
+                fileProviderData.sharedInstance.signalEnumerator(for: [parentItemIdentifier, .workingSet])
+            }
+            
+            metadata.fileName = fileName
+            metadata.serverUrl = serverUrl
+            if let etag = etag { metadata.etag = etag }
+            if let ocId = ocId { metadata.ocId = ocId }
+            if let date = date { metadata.date = date }
+            metadata.session = ""
+            metadata.status = Int(k_metadataStatusNormal)
+                  
+            guard let metadataUpdated = NCManageDatabase.sharedInstance.addMetadata(metadata) else { return }
+            NCManageDatabase.sharedInstance.addLocalFile(metadata: metadataUpdated)
+            
+            // New file
+            if ocId != ocIdTemp {
+            
+                NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdTemp))
+                
+                // File system
+                let atPath = CCUtility.getDirectoryProviderStorageOcId(ocIdTemp)
+                let toPath = CCUtility.getDirectoryProviderStorageOcId(ocId)
+                CCUtility.copyFile(atPath: atPath, toPath: toPath)
+            }
+            
+            // Signal update
+            item = FileProviderItem(metadata: metadataUpdated, parentItemIdentifier: parentItemIdentifier)
+            fileProviderData.sharedInstance.fileProviderSignalUpdateContainerItem[item.itemIdentifier] = item
+            fileProviderData.sharedInstance.fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
+            fileProviderData.sharedInstance.signalEnumerator(for: [parentItemIdentifier, .workingSet])
+            
+        } else {
+           
+            // Error
+            NCManageDatabase.sharedInstance.setMetadataSession("", sessionError: "", sessionSelector: "", sessionTaskIdentifier: 0, status: Int(k_metadataStatusUploadError), predicate: NSPredicate(format: "ocId == %@", ocIdTemp))
+        }
+    }
+}

+ 14 - 24
File Provider Extension/FileProviderExtension+Thumbnail.swift

@@ -22,6 +22,7 @@
 //
 
 import FileProvider
+import NCCommunication
 
 extension FileProviderExtension {
 
@@ -35,10 +36,7 @@ extension FileProviderExtension {
             guard let metadata = fileProviderUtility.sharedInstance.getTableMetadataFromItemIdentifier(itemIdentifier) else {
                 
                 counterProgress += 1
-                if (counterProgress == progress.totalUnitCount) {
-                    completionHandler(nil)
-                }
-                
+                if (counterProgress == progress.totalUnitCount) { completionHandler(nil) }
                 continue
             }
             
@@ -47,37 +45,29 @@ 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 fileNamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, activeUrl: fileProviderData.sharedInstance.accountUrl)!
+                let fileNameLocalPath = CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, fileNameView: metadata.fileNameView)!
+                let serverUrl = fileProviderData.sharedInstance.accountUrl
+                    
+                NCCommunication.sharedInstance.downloadPreview(serverUrl: serverUrl, fileNamePath: fileNamePath, fileNameLocalPath: fileNameLocalPath ,width: width, height: height, account: fileProviderData.sharedInstance.account) { (account, data, errorCode, errorDescription) in
+                    if errorCode == 0 && data != nil {
+                        perThumbnailCompletionHandler(itemIdentifier, data, nil)
                     } else {
                         perThumbnailCompletionHandler(itemIdentifier, nil, NSFileProviderError(.serverUnreachable))
                     }
                     
                     counterProgress += 1
-                    if (counterProgress == progress.totalUnitCount) {
-                        completionHandler(nil)
-                    }
-                })
-                
+                    if (counterProgress == progress.totalUnitCount) { completionHandler(nil) }
+                }
+               
             } else {
                 
                 counterProgress += 1
-                if (counterProgress == progress.totalUnitCount) {
-                    completionHandler(nil)
-                }
+                if (counterProgress == progress.totalUnitCount) { completionHandler(nil) }
             }
         }
         
         return progress
     }
-
+    
 }

+ 0 - 1
File Provider Extension/FileProviderExtension-Bridging-Header.h

@@ -36,4 +36,3 @@
 #import "OCSharedDto.h"
 #import "HCFeatures.h"
 #import "NCComments.h"
-#import "CCCertificate.h"

+ 131 - 139
File Provider Extension/FileProviderExtension.swift

@@ -22,6 +22,7 @@
 //
 
 import FileProvider
+import NCCommunication
 
 /* -----------------------------------------------------------------------------------------------------------------------------------------------
                                                             STRUCT item
@@ -51,13 +52,7 @@ import FileProvider
 class FileProviderExtension: NSFileProviderExtension {
     
     var outstandingSessionTasks = [URL: URLSessionTask]()
-    
-    lazy var fileCoordinator: NSFileCoordinator = {
-        
-        let fileCoordinator = NSFileCoordinator()
-        fileCoordinator.purposeIdentifier = NSFileProviderManager.default.providerIdentifier
-        return fileCoordinator
-    }()
+    var outstandingOcIdTemp = [String:String]()
     
     override init() {
         super.init()
@@ -72,21 +67,31 @@ class FileProviderExtension: NSFileProviderExtension {
         
         var maybeEnumerator: NSFileProviderEnumerator? = nil
         
-        // Check account
-        if (containerItemIdentifier != NSFileProviderItemIdentifier.workingSet) {
-            if containerItemIdentifier == NSFileProviderItemIdentifier.rootContainer && self.domain?.identifier.rawValue == nil {
-                throw NSError(domain: NSFileProviderErrorDomain, code: NSFileProviderError.notAuthenticated.rawValue, userInfo:[:])
-            } else if self.domain?.identifier.rawValue != nil {
-                if fileProviderData.sharedInstance.setupActiveAccount(domain: self.domain?.identifier.rawValue) == false {
+        if Int(k_fileProvider_domain) == 1 {
+            
+            if (containerItemIdentifier != NSFileProviderItemIdentifier.workingSet) {
+                if containerItemIdentifier == NSFileProviderItemIdentifier.rootContainer && self.domain?.identifier.rawValue == nil {
                     throw NSError(domain: NSFileProviderErrorDomain, code: NSFileProviderError.notAuthenticated.rawValue, userInfo:[:])
+                } else if self.domain?.identifier.rawValue != nil {
+                    if fileProviderData.sharedInstance.setupActiveAccount(domain: self.domain?.identifier.rawValue, providerExtension: self) == false {
+                        throw NSError(domain: NSFileProviderErrorDomain, code: NSFileProviderError.notAuthenticated.rawValue, userInfo:[:])
+                    }
+                } else {
+                    if fileProviderData.sharedInstance.setupActiveAccount(itemIdentifier: containerItemIdentifier, providerExtension: self) == false {
+                        throw NSError(domain: NSFileProviderErrorDomain, code: NSFileProviderError.notAuthenticated.rawValue, userInfo:[:])
+                    }
                 }
-            } else {
-                if fileProviderData.sharedInstance.setupActiveAccount(itemIdentifier: containerItemIdentifier) == false {
+            }
+            
+        } else {
+            
+            if (containerItemIdentifier != NSFileProviderItemIdentifier.workingSet) {
+                if fileProviderData.sharedInstance.setupActiveAccount(domain: nil, providerExtension: self) == false {
                     throw NSError(domain: NSFileProviderErrorDomain, code: NSFileProviderError.notAuthenticated.rawValue, userInfo:[:])
                 }
             }
         }
-
+        
         if (containerItemIdentifier == NSFileProviderItemIdentifier.rootContainer) {
             maybeEnumerator = FileProviderEnumerator(enumeratedItemIdentifier: containerItemIdentifier)
         } else if (containerItemIdentifier == NSFileProviderItemIdentifier.workingSet) {
@@ -122,8 +127,8 @@ class FileProviderExtension: NSFileProviderExtension {
             metadata.account = fileProviderData.sharedInstance.account
             metadata.directory = true
             metadata.ocId = NSFileProviderItemIdentifier.rootContainer.rawValue
-            metadata.fileName = ""
-            metadata.fileNameView = ""
+            metadata.fileName = "root"
+            metadata.fileNameView = "root"
             metadata.serverUrl = fileProviderData.sharedInstance.homeServerUrl
             metadata.typeFile = k_metadataTypeFile_directory
             
@@ -175,9 +180,7 @@ class FileProviderExtension: NSFileProviderExtension {
         let itemIdentifier = NSFileProviderItemIdentifier(pathComponents[pathComponents.count - 2])
         return itemIdentifier
     }
-    
-    // MARK: -
-    
+        
     override func providePlaceholder(at url: URL, completionHandler: @escaping (Error?) -> Void) {
         
         guard let identifier = persistentIdentifierForItem(at: url) else {
@@ -190,8 +193,7 @@ class FileProviderExtension: NSFileProviderExtension {
             let placeholderURL = NSFileProviderManager.placeholderURL(for: url)
             try NSFileProviderManager.writePlaceholder(at: placeholderURL,withMetadata: fileProviderItem)
             completionHandler(nil)
-        } catch let error {
-            print("error: \(error)")
+        } catch {
             completionHandler(error)
         }
     }
@@ -202,6 +204,7 @@ class FileProviderExtension: NSFileProviderExtension {
         let identifier = NSFileProviderItemIdentifier(pathComponents[pathComponents.count - 2])
         
         if let _ = outstandingSessionTasks[url] {
+            completionHandler(nil)
             return
         }
         
@@ -215,42 +218,34 @@ 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 serverUrlFileName = metadata.serverUrl + "/" + metadata.fileName
+        let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileName)!
+        
+        let task = NCCommunication.sharedInstance.download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, account: fileProviderData.sharedInstance.account, progressHandler: { (progress) in }) { (account, etag, date, length, errorCode, errorDescription) in
             
-            // remove Task
             self.outstandingSessionTasks.removeValue(forKey: url)
             
-            if errorCode == 0 && account == metadata.account {
-
-                guard let metadata = fileProviderUtility.sharedInstance.getTableMetadataFromItemIdentifier(identifier) else {
-                    completionHandler(NSFileProviderError(.noSuchItem))
-                    return
-                }
+            if errorCode == 0  {
                 
-                metadata.date = date! as NSDate
-                metadata.etag = etag!
-                metadata.size = Double(lenght)
-                
-                guard let metadataUpdate = NCManageDatabase.sharedInstance.addMetadata(metadata) else { return }
-                NCManageDatabase.sharedInstance.addLocalFile(metadata: metadataUpdate)
+                metadata.status = Int(k_metadataStatusNormal)
+                guard let metadataDownloaded = NCManageDatabase.sharedInstance.addMetadata(metadata) else { return }
+                NCManageDatabase.sharedInstance.addLocalFile(metadata: metadataDownloaded)
                 
                 completionHandler(nil)
                 
             } else {
                 
-                if errorCode == Int(CFNetworkErrors.cfurlErrorCancelled.rawValue) {
-                    completionHandler(NSFileProviderError(.noSuchItem))
-                } else {
-                    completionHandler(NSFileProviderError(.serverUnreachable))
-                }
+                // Error
+                NCManageDatabase.sharedInstance.setMetadataSession("", sessionError: "", sessionSelector: "", sessionTaskIdentifier: 0, status: Int(k_metadataStatusDownloadError), predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
                 
-                return
+                completionHandler(NSFileProviderError(.noSuchItem))
             }
-        })
-       
-        // Add and register task
+        }
+        
         if task != nil {
+            
             outstandingSessionTasks[url] = task
+            
             NSFileProviderManager.default.register(task!, forItemWithIdentifier: NSFileProviderItemIdentifier(identifier.rawValue)) { (error) in }
         }
     }
@@ -260,107 +255,29 @@ class FileProviderExtension: NSFileProviderExtension {
         let pathComponents = url.pathComponents
         assert(pathComponents.count > 2)
         let itemIdentifier = NSFileProviderItemIdentifier(pathComponents[pathComponents.count - 2])
-        
-        guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", itemIdentifier.rawValue)) else { return }
-
-        let fileName = pathComponents[pathComponents.count - 1]
-        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 {
-                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))
-            }
-        })
-    }
-    
-    /*
-    override func itemChanged(at url: URL) {
-        
-        var size = 0 as Double
-        let pathComponents = url.pathComponents
-        assert(pathComponents.count > 2)
-        let itemIdentifier = NSFileProviderItemIdentifier(pathComponents[pathComponents.count - 2])
-        
-        guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account == %@ AND ocId == %@", fileProviderData.sharedInstance.account, itemIdentifier.rawValue)) else { return }
-        guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadata, homeServerUrl: fileProviderData.sharedInstance.homeServerUrl) else { return }
-        
-        // typefile directory ? (NOT PERMITTED)
-        do {
-            let attributes = try fileProviderUtility.sharedInstance.fileManager.attributesOfItem(atPath: url.path)
-            size = attributes[FileAttributeKey.size] as! Double
-            let typeFile = attributes[FileAttributeKey.type] as! FileAttributeType
-            if typeFile == FileAttributeType.typeDirectory {
-                return
-            }
-        } catch { return }
-        
         let fileName = pathComponents[pathComponents.count - 1]
-        let fileNameServerUrl = metadata.serverUrl + "/" + fileName
+        var ocId = itemIdentifier.rawValue
+        
+        // Temp ocId ?
+        if outstandingOcIdTemp[ocId] != nil && outstandingOcIdTemp[ocId] != ocId {
+            ocId = outstandingOcIdTemp[ocId]!
+            let atPath = CCUtility.getDirectoryProviderStorageOcId(itemIdentifier.rawValue, fileNameView: fileName)
+            let toPath = CCUtility.getDirectoryProviderStorageOcId(ocId, fileNameView: fileName)
+            CCUtility.copyFile(atPath: atPath, toPath: toPath)
+        }
+        guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocId)) else { return }
+
+        let serverUrlFileName = metadata.serverUrl + "/" + fileName
         let fileNameLocalPath = url.path
         
-        let task = 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
-            
-            // remove Task
-            self.outstandingSessionTasks.removeValue(forKey: url)
-            
-            guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account == %@ AND ocId == %@", fileProviderData.sharedInstance.account, itemIdentifier.rawValue)) else { return }
-            
-            if account == fileProviderData.sharedInstance.account && errorCode == 0 {
-                
-                metadata.sessionTaskIdentifier = Int(k_taskIdentifierDone)
-                metadata.status = Int(k_metadataStatusNormal)
-                metadata.session = ""
-                metadata.date = date! as NSDate
-                metadata.etag = etag!
-                metadata.size = size
-                
-                guard let metadataUpdate = NCManageDatabase.sharedInstance.addMetadata(metadata) else { return }
-                NCManageDatabase.sharedInstance.setLocalFile(ocId: metadataUpdate.ocId, date: metadataUpdate.date, exifDate: nil, exifLatitude: nil, exifLongitude: nil, fileName: nil, etag: metadataUpdate.etag)
-                
-                // Signal update/delete
-                _ = fileProviderData.sharedInstance.fileProviderSignal(metadata: metadataUpdate, parentItemIdentifier: parentItemIdentifier, delete: false, update: true)
-                
-            } else {
-                
-                metadata.sessionTaskIdentifier = Int(k_taskIdentifierDone)
-                metadata.status = Int(k_metadataStatusNormal)
-                metadata.session = ""
-                _ = NCManageDatabase.sharedInstance.addMetadata(metadata)
-            }
-        })
-        
-        // Add and register task
-        if task != nil {
-            
-            metadata.sessionTaskIdentifier = Int(task!.taskIdentifier)
-            metadata.status = Int(k_metadataStatusUploading)
-            metadata.session = k_upload_session_extension
-            
-            guard let metadataUpdate = NCManageDatabase.sharedInstance.addMetadata(metadata) else { return }
-            
-            // Signal update/delete
-            _ = fileProviderData.sharedInstance.fileProviderSignal(metadata: metadataUpdate, parentItemIdentifier: parentItemIdentifier, delete: false, update: true)
+        if let task = NCCommunicationBackground.sharedInstance.upload(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, description: metadata.ocId, session: NCCommunicationBackground.sharedInstance.sessionManagerTransferExtension) {
             
-            self.outstandingSessionTasks[url] = task
-            NSFileProviderManager.default.register(task!, forItemWithIdentifier: NSFileProviderItemIdentifier(itemIdentifier.rawValue)) { (error) in }
+            NSFileProviderManager.default.register(task, forItemWithIdentifier: NSFileProviderItemIdentifier(metadata.fileId)) { (error) in }
         }
     }
-    */
     
     override func stopProvidingItem(at url: URL) {
-        // Called after the last claim to the file has been released. At this point, it is safe for the file provider to remove the content file.
-        // Care should be taken that the corresponding placeholder file stays behind after the content file has been deleted.
-        
-        // Called after the last claim to the file has been released. At this point, it is safe for the file provider to remove the content file.
-        
-        // look up whether the file has local changes
+      
         let fileHasLocalChanges = false
         
         if !fileHasLocalChanges {
@@ -383,4 +300,79 @@ class FileProviderExtension: NSFileProviderExtension {
             outstandingSessionTasks.removeValue(forKey: url)
         }
     }
+    
+    override func importDocument(at fileURL: URL, toParentItemIdentifier parentItemIdentifier: NSFileProviderItemIdentifier, completionHandler: @escaping (NSFileProviderItem?, Error?) -> Void) {
+                
+        DispatchQueue.main.async {
+            
+            autoreleasepool {
+            
+                var size = 0 as Double
+                var error: NSError?
+                let metadata = tableMetadata()
+                
+                guard let tableDirectory = fileProviderUtility.sharedInstance.getTableDirectoryFromParentItemIdentifier(parentItemIdentifier, account: fileProviderData.sharedInstance.account, homeServerUrl: fileProviderData.sharedInstance.homeServerUrl) else {
+                    completionHandler(nil, NSFileProviderError(.noSuchItem))
+                    return
+                }
+                
+                if fileURL.startAccessingSecurityScopedResource() == false {
+                    completionHandler(nil, NSFileProviderError(.noSuchItem))
+                    return
+                }
+                
+                // typefile directory ? (NOT PERMITTED)
+                do {
+                    let attributes = try fileProviderUtility.sharedInstance.fileManager.attributesOfItem(atPath: fileURL.path)
+                    size = attributes[FileAttributeKey.size] as! Double
+                    let typeFile = attributes[FileAttributeKey.type] as! FileAttributeType
+                    if typeFile == FileAttributeType.typeDirectory {
+                        completionHandler(nil, NSFileProviderError(.noSuchItem))
+                        return
+                    }
+                } catch {
+                    completionHandler(nil, NSFileProviderError(.noSuchItem))
+                    return
+                }
+        
+                let fileName = NCUtility.sharedInstance.createFileName(fileURL.lastPathComponent, serverUrl: tableDirectory.serverUrl, account: fileProviderData.sharedInstance.account)
+                let ocIdTemp = NSUUID().uuidString.lowercased()
+                
+                NSFileCoordinator().coordinate(readingItemAt: fileURL, options: .withoutChanges, error: &error) { (url) in
+                    _ = fileProviderUtility.sharedInstance.copyFile(url.path, toPath: CCUtility.getDirectoryProviderStorageOcId(ocIdTemp, fileNameView: fileName))
+                }
+                
+                fileURL.stopAccessingSecurityScopedResource()
+                                
+                metadata.account = fileProviderData.sharedInstance.account
+                metadata.date = NSDate()
+                metadata.directory = false
+                metadata.etag = ""
+                metadata.fileName = fileName
+                metadata.fileNameView = fileName
+                metadata.ocId = ocIdTemp
+                metadata.serverUrl = tableDirectory.serverUrl
+                metadata.session = k_upload_session_extension
+                metadata.size = size
+                metadata.status = Int(k_metadataStatusInUpload)
+                CCUtility.insertTypeFileIconName(fileName, metadata: metadata)
+                
+                guard let metadataForUpload = NCManageDatabase.sharedInstance.addMetadata(metadata) else {
+                    completionHandler(nil, NSFileProviderError(.noSuchItem))
+                    return
+                }
+                
+                let serverUrlFileName = tableDirectory.serverUrl + "/" + fileName
+                let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(ocIdTemp, fileNameView: fileName)!
+                
+                if let task = NCCommunicationBackground.sharedInstance.upload(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, description: ocIdTemp, session: NCCommunicationBackground.sharedInstance.sessionManagerTransferExtension) {
+                    self.outstandingSessionTasks[URL(fileURLWithPath: fileNameLocalPath)] = task as URLSessionTask
+                    NSFileProviderManager.default.register(task, forItemWithIdentifier: NSFileProviderItemIdentifier(ocIdTemp)) { (error) in }
+                }
+                
+                let item = FileProviderItem(metadata: metadataForUpload, parentItemIdentifier: parentItemIdentifier)
+                completionHandler(item, nil)
+            }
+        }
+    }
 }

+ 109 - 68
File Provider Extension/FileProviderItem.swift

@@ -25,86 +25,127 @@ import FileProvider
 
 class FileProviderItem: NSObject, NSFileProviderItem {
 
-    // Providing Required Properties
-    var itemIdentifier: NSFileProviderItemIdentifier                // The item's persistent identifier
-    var filename: String = ""                                       // The item's filename
-    var typeIdentifier: String = ""                                 // The item's uniform type identifiers
-    var capabilities: NSFileProviderItemCapabilities {              // The item's capabilities
-        if (self.isDirectory) {
+    var metadata: tableMetadata
+    var parentItemIdentifier: NSFileProviderItemIdentifier
+
+    var itemIdentifier: NSFileProviderItemIdentifier {
+        return fileProviderUtility.sharedInstance.getItemIdentifier(metadata: metadata)
+    }
+    
+    var filename: String {
+        return metadata.fileNameView
+    }
+    
+    var documentSize: NSNumber? {
+        return NSNumber(value: metadata.size)
+    }
+    
+    var typeIdentifier: String {
+        return CCUtility.insertTypeFileIconName(metadata.fileNameView, metadata: metadata)
+    }
+    
+    var contentModificationDate: Date? {
+        return metadata.date as Date
+    }
+    
+    var creationDate: Date? {
+        return metadata.date as Date
+    }
+    
+    var lastUsedDate: Date? {
+        return metadata.date as Date
+    }
+
+    var capabilities: NSFileProviderItemCapabilities {
+        if (metadata.directory) {
             return [ .allowsAddingSubItems, .allowsContentEnumerating, .allowsReading, .allowsDeleting, .allowsRenaming ]
         } else {
             return [ .allowsWriting, .allowsReading, .allowsDeleting, .allowsRenaming, .allowsReparenting ]
         }
     }
     
-    // Managing Content
-    var childItemCount: NSNumber?                                   // The number of items contained by this item
-    var documentSize: NSNumber?                                     // The document's size, in bytes
-
-    // Specifying Content Location
-    var parentItemIdentifier: NSFileProviderItemIdentifier          // The persistent identifier of the item's parent folder
-    var isTrashed: Bool = false                                     // A Boolean value that indicates whether an item is in the trash
-   
-    // Tracking Usage
-    var contentModificationDate: Date?                              // The date the item was last modified
-    var creationDate: Date?                                         // The date the item was created
-    var lastUsedDate: Date? = Date()                                // The date the item was last used, default to the moment when the item is created 
-
-    // Tracking Versions
-    var versionIdentifier: Data?                                    // A data value used to determine when the item changes
-    var isMostRecentVersionDownloaded: Bool = true                  // A Boolean value that indicates whether the item is the most recent version downloaded from the server
+    var isTrashed: Bool {
+        return false
+    }
+    
+    var childItemCount: NSNumber? {
+        return nil
+    }
 
-    // Monitoring File Transfers
-    var isUploading: Bool = false                                   // A Boolean value that indicates whether the item is currently uploading to your remote server
-    var isUploaded: Bool = true                                     // A Boolean value that indicates whether the item has been uploaded to your remote server
-    var uploadingError: Error?                                      // An error that occurred while uploading to your remote server
+    var versionIdentifier: Data? {
+        return metadata.etag.data(using: .utf8)
+    }
     
-    var isDownloading: Bool = false                                 // A Boolean value that indicates whether the item is currently downloading from your remote server
-    var isDownloaded: Bool = true                                   // A Boolean value that indicates whether the item has been downloaded from your remote server
-    var downloadingError: Error?                                    // An error that occurred while downloading the item
+    var tagData: Data? {
+        if let tableTag = NCManageDatabase.sharedInstance.getTag(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) {
+            return tableTag.tagIOS
+        } else {
+            return nil
+        }
+    }
+    
+    var favoriteRank: NSNumber? {
+        if let rank = fileProviderData.sharedInstance.listFavoriteIdentifierRank[metadata.ocId] {
+            return rank
+        } else {
+            return nil
+        }
+    }
 
-    var tagData: Data?                                              // Tag
-    var favoriteRank: NSNumber?                                     // Favorite
-    var isDirectory = false
+    var isMostRecentVersionDownloaded: Bool {
+        return true
+    }
+    
+    var isDownloaded: Bool {
+        if NCManageDatabase.sharedInstance.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) != nil {
+            return true
+        } else {
+            return false
+        }
+    }
+    
+    var isDownloading: Bool {
+        if metadata.status == Int(k_metadataStatusInDownload) {
+            return true
+        } else {
+            return false
+        }
+    }
+    
+    var downloadingError: Error? {
+        if metadata.status == Int(k_metadataStatusDownloadError) {
+            return fileProviderData.FileProviderError.downloadError
+        } else {
+            return nil
+        }
+    }
 
-    init(metadata: tableMetadata, parentItemIdentifier: NSFileProviderItemIdentifier) {
-        
-        self.parentItemIdentifier = parentItemIdentifier
-        self.itemIdentifier = fileProviderUtility.sharedInstance.getItemIdentifier(metadata: metadata)
-                
-        self.contentModificationDate = metadata.date as Date
-        self.creationDate = metadata.date as Date
-        self.documentSize = NSNumber(value: metadata.size)
-        self.filename = metadata.fileNameView
-        self.isDirectory = metadata.directory
-        self.typeIdentifier = CCUtility.insertTypeFileIconName(metadata.fileNameView, metadata: metadata)
-        self.versionIdentifier = metadata.etag.data(using: .utf8)
-        
-        if (!metadata.directory) {
-            
-            self.documentSize = NSNumber(value: metadata.size)
-           
-            let tableLocalFile = NCManageDatabase.sharedInstance.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-            if tableLocalFile == nil {
-//                isMostRecentVersionDownloaded = false
-            } else {
-//                isMostRecentVersionDownloaded = true
-            }
-            
+    var isUploaded: Bool {
+        if metadata.status == Int(k_metadataStatusInUpload) {
+            return false
         } else {
-            
-            // Favorite directory
-            let rank = fileProviderData.sharedInstance.listFavoriteIdentifierRank[metadata.ocId]
-            if (rank == nil) {
-                favoriteRank = nil
-            } else {
-                favoriteRank = fileProviderData.sharedInstance.listFavoriteIdentifierRank[metadata.ocId]
-            }
+            return true
         }
-        
-        // Tag
-        if let tableTag = NCManageDatabase.sharedInstance.getTag(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) {
-            tagData = tableTag.tagIOS
+    }
+    
+    var isUploading: Bool {
+        if metadata.status == Int(k_metadataStatusInUpload) {
+            return true
+        } else {
+            return false
+        }
+    }
+    
+    var uploadingError: Error? {
+        if metadata.status == Int(k_metadataStatusUploadError) {
+            return fileProviderData.FileProviderError.uploadError
+        } else {
+            return nil
         }
     }
+
+    init(metadata: tableMetadata, parentItemIdentifier: NSFileProviderItemIdentifier) {
+        self.metadata = metadata
+        self.parentItemIdentifier = parentItemIdentifier
+    }
 }

+ 25 - 38
Nextcloud.xcodeproj/project.pbxproj

@@ -81,6 +81,8 @@
 		F7169A1C1EE590930086BD69 /* NCShares.m in Sources */ = {isa = PBXBuildFile; fileRef = F7169A181EE590930086BD69 /* NCShares.m */; };
 		F7169A1D1EE590930086BD69 /* NCSharesCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F7169A1A1EE590930086BD69 /* NCSharesCell.m */; };
 		F7169A1E1EE590930086BD69 /* NCSharesCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F7169A1B1EE590930086BD69 /* NCSharesCell.xib */; };
+		F716FE7823795E5000FABE50 /* NCCommunication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F716FE7723795E5000FABE50 /* NCCommunication.framework */; settings = {ATTRIBUTES = (Required, ); }; };
+		F716FE7A23795EC500FABE50 /* FileProviderExtension+NetworkingDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F716FE7923795EC500FABE50 /* FileProviderExtension+NetworkingDelegate.swift */; };
 		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 */; };
@@ -89,9 +91,6 @@
 		F72382C22295856A005B8A07 /* GoogleMVTextDetectorResources.bundle in Resources */ = {isa = PBXBuildFile; fileRef = F72382BE22958569005B8A07 /* GoogleMVTextDetectorResources.bundle */; };
 		F72382C32295856A005B8A07 /* GoogleToolboxForMac.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F72382BF22958569005B8A07 /* GoogleToolboxForMac.framework */; };
 		F723B3DD22FC6D1D00301EFE /* NCShareCommentsCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F723B3DC22FC6D1C00301EFE /* NCShareCommentsCell.xib */; };
-		F724B1CC2351BFBD00A5753B /* NCCommunicationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F724B1CB2351BFBD00A5753B /* NCCommunicationModel.swift */; };
-		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 */; };
@@ -102,13 +101,12 @@
 		F72AAECB1E5C60C700BB17E1 /* AHKActionSheetViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F72AAEC51E5C60C700BB17E1 /* AHKActionSheetViewController.m */; };
 		F72D1007210B6882009C96B7 /* NCPushNotificationEncryption.m in Sources */ = {isa = PBXBuildFile; fileRef = F72D1005210B6882009C96B7 /* NCPushNotificationEncryption.m */; };
 		F72E0B9D21AD60BC00898D7B /* WeScan.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F72E0B9C21AD60BC00898D7B /* WeScan.framework */; };
+		F72FBC5C2379648F002CEAD0 /* NCCommunication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F716FE7723795E5000FABE50 /* NCCommunication.framework */; };
+		F72FBC5D237964A2002CEAD0 /* NCCommunication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F716FE7723795E5000FABE50 /* NCCommunication.framework */; };
 		F732BA061D76CE1500E9878B /* CCNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = F732BA041D76CE1500E9878B /* CCNetworking.m */; };
 		F732BA0B1D76DBA500E9878B /* CCNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = F732BA041D76CE1500E9878B /* CCNetworking.m */; };
 		F733B65221997CC2001C1FFA /* TLPhotoPicker.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F733B65121997CC1001C1FFA /* TLPhotoPicker.framework */; };
 		F7362A1F220C853A005101B5 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7362A1E220C853A005101B5 /* LaunchScreen.storyboard */; };
-		F736B54E234DCE43008A5C9F /* NCCommunication.swift in Sources */ = {isa = PBXBuildFile; fileRef = F736B54D234DCE43008A5C9F /* NCCommunication.swift */; };
-		F736B54F234DCE43008A5C9F /* NCCommunication.swift in Sources */ = {isa = PBXBuildFile; fileRef = F736B54D234DCE43008A5C9F /* NCCommunication.swift */; };
-		F736B550234DCE43008A5C9F /* NCCommunication.swift in Sources */ = {isa = PBXBuildFile; fileRef = F736B54D234DCE43008A5C9F /* NCCommunication.swift */; };
 		F736B554234DCF7B008A5C9F /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F736B551234DCF57008A5C9F /* Alamofire.framework */; };
 		F736B557234DCF92008A5C9F /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F736B551234DCF57008A5C9F /* Alamofire.framework */; };
 		F7381EE1218218C9000B1560 /* NCOffline.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7381EDA218218C9000B1560 /* NCOffline.swift */; };
@@ -211,7 +209,6 @@
 		F7434B5D20E241E800417916 /* CCUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = F7053E3D1C639DF500741EA5 /* CCUtility.m */; };
 		F7434B5E20E241EC00417916 /* CCGraphics.m in Sources */ = {isa = PBXBuildFile; fileRef = F76C3B841C6388BC00DC4301 /* CCGraphics.m */; };
 		F7434B6020E2445200417916 /* CCExifGeo.m in Sources */ = {isa = PBXBuildFile; fileRef = F7A54C351C6267B500E2C8BF /* CCExifGeo.m */; };
-		F7434B6120E2445C00417916 /* CCCertificate.m in Sources */ = {isa = PBXBuildFile; fileRef = F7F801011D98205A007537BC /* CCCertificate.m */; };
 		F7434B6220E249F700417916 /* NSNotificationCenter+MainThread.m in Sources */ = {isa = PBXBuildFile; fileRef = F78071081EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m */; };
 		F7434B6320E249FB00417916 /* NSString+TruncateToWidth.m in Sources */ = {isa = PBXBuildFile; fileRef = F73049B91CB567F000C7C320 /* NSString+TruncateToWidth.m */; };
 		F745B251222D871800346520 /* QRCodeReader.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F745B250222D871800346520 /* QRCodeReader.framework */; };
@@ -236,6 +233,9 @@
 		F758B45A212C564000515F55 /* Scan.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F758B457212C564000515F55 /* Scan.storyboard */; };
 		F758B45E212C569D00515F55 /* ScanCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F758B45D212C569C00515F55 /* ScanCell.swift */; };
 		F758B460212C56A400515F55 /* ScanCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F758B45F212C56A400515F55 /* ScanCollectionView.swift */; };
+		F75A9EE623796C6F0044CFCE /* NCNetworking.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75A9EE523796C6F0044CFCE /* NCNetworking.swift */; };
+		F75A9EE723796C6F0044CFCE /* NCNetworking.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75A9EE523796C6F0044CFCE /* NCNetworking.swift */; };
+		F75A9EE823796C6F0044CFCE /* NCNetworking.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75A9EE523796C6F0044CFCE /* NCNetworking.swift */; };
 		F75AC2431F1F62450073EC19 /* NCManageAutoUploadFileName.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75AC2421F1F62450073EC19 /* NCManageAutoUploadFileName.swift */; };
 		F75ADF451DC75FFE008A7347 /* CCLogin.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F75ADF441DC75FFE008A7347 /* CCLogin.storyboard */; };
 		F75EDFBD1E8C112F00E6F369 /* libsqlite3.0.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = F75EDFBC1E8C112F00E6F369 /* libsqlite3.0.tbd */; };
@@ -389,7 +389,6 @@
 		F77B0F8C1D118A16002130FE /* CCCellMainTransfer.xib in Resources */ = {isa = PBXBuildFile; fileRef = F70211F91BAC56E9003FC03E /* CCCellMainTransfer.xib */; };
 		F77D49A91DC238E500CDC568 /* loading.gif in Resources */ = {isa = PBXBuildFile; fileRef = F77D49A71DC238E500CDC568 /* loading.gif */; };
 		F77EB6281EC08036003F814F /* CCExifGeo.m in Sources */ = {isa = PBXBuildFile; fileRef = F7A54C351C6267B500E2C8BF /* CCExifGeo.m */; };
-		F77EB62A1EC0B50A003F814F /* CCCertificate.m in Sources */ = {isa = PBXBuildFile; fileRef = F7F801011D98205A007537BC /* CCCertificate.m */; };
 		F78071091EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m in Sources */ = {isa = PBXBuildFile; fileRef = F78071081EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m */; };
 		F780710A1EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m in Sources */ = {isa = PBXBuildFile; fileRef = F78071081EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m */; };
 		F781996922636BFA00EBDF6A /* HCFeatures.m in Sources */ = {isa = PBXBuildFile; fileRef = F781996822636BFA00EBDF6A /* HCFeatures.m */; };
@@ -565,9 +564,6 @@
 		F7E0E1DE22327DBA006B0911 /* NCAudioRecorderViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7E0E1DD22327DBA006B0911 /* NCAudioRecorderViewController.storyboard */; };
 		F7E4D9C422ED929B003675FD /* NCShareComments.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E4D9C322ED929B003675FD /* NCShareComments.swift */; };
 		F7E856192351D7BE009A3330 /* SwiftyXMLParser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7E856182351D7BE009A3330 /* SwiftyXMLParser.framework */; };
-		F7E8561B235202DF009A3330 /* NSCommunicationCommon.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E8561A235202DF009A3330 /* NSCommunicationCommon.swift */; };
-		F7E8561C235202DF009A3330 /* NSCommunicationCommon.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E8561A235202DF009A3330 /* NSCommunicationCommon.swift */; };
-		F7E8561D235202DF009A3330 /* NSCommunicationCommon.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E8561A235202DF009A3330 /* NSCommunicationCommon.swift */; };
 		F7E9C41B20F4CA870040CF18 /* CCTransfers.m in Sources */ = {isa = PBXBuildFile; fileRef = F7E9C41820F4CA870040CF18 /* CCTransfers.m */; };
 		F7ECBA6D1E239DCD003E6328 /* NCCreateFormUploadRichdocuments.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7ECBA6C1E239DCD003E6328 /* NCCreateFormUploadRichdocuments.swift */; };
 		F7F54CE51E5B14C700E19C62 /* ImageError.png in Resources */ = {isa = PBXBuildFile; fileRef = F7F54CAF1E5B14C700E19C62 /* ImageError.png */; };
@@ -610,7 +606,6 @@
 		F7F54D0C1E5B14C800E19C62 /* MWTapDetectingView.m in Sources */ = {isa = PBXBuildFile; fileRef = F7F54CE01E5B14C700E19C62 /* MWTapDetectingView.m */; };
 		F7F54D0D1E5B14C800E19C62 /* MWZoomingScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = F7F54CE21E5B14C700E19C62 /* MWZoomingScrollView.m */; };
 		F7F54D0E1E5B14C800E19C62 /* UIImage+MWPhotoBrowser.m in Sources */ = {isa = PBXBuildFile; fileRef = F7F54CE41E5B14C700E19C62 /* UIImage+MWPhotoBrowser.m */; };
-		F7F801031D98205A007537BC /* CCCertificate.m in Sources */ = {isa = PBXBuildFile; fileRef = F7F801011D98205A007537BC /* CCCertificate.m */; };
 		F7F878AE1FB9E3B900599E4F /* NCEndToEndMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F878AD1FB9E3B900599E4F /* NCEndToEndMetadata.swift */; };
 		F7F878AF1FB9E3B900599E4F /* NCEndToEndMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F878AD1FB9E3B900599E4F /* NCEndToEndMetadata.swift */; };
 		F7F8D71C1ED6183000E711F3 /* CCCellShareExt.m in Sources */ = {isa = PBXBuildFile; fileRef = F7F8D71A1ED6183000E711F3 /* CCCellShareExt.m */; };
@@ -763,6 +758,8 @@
 		F7169A1B1EE590930086BD69 /* NCSharesCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCSharesCell.xib; sourceTree = "<group>"; };
 		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>"; };
+		F716FE7723795E5000FABE50 /* NCCommunication.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NCCommunication.framework; path = Carthage/Build/iOS/NCCommunication.framework; sourceTree = "<group>"; };
+		F716FE7923795EC500FABE50 /* FileProviderExtension+NetworkingDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FileProviderExtension+NetworkingDelegate.swift"; sourceTree = "<group>"; };
 		F718088C2341FEB20039A736 /* NCActionSheetAppearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCActionSheetAppearance.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; };
@@ -770,7 +767,6 @@
 		F72382BE22958569005B8A07 /* GoogleMVTextDetectorResources.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = GoogleMVTextDetectorResources.bundle; sourceTree = "<group>"; };
 		F72382BF22958569005B8A07 /* GoogleToolboxForMac.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = GoogleToolboxForMac.framework; sourceTree = "<group>"; };
 		F723B3DC22FC6D1C00301EFE /* NCShareCommentsCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCShareCommentsCell.xib; sourceTree = "<group>"; };
-		F724B1CB2351BFBD00A5753B /* NCCommunicationModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCCommunicationModel.swift; sourceTree = "<group>"; };
 		F7267A81225DFCE100D6DB7D /* AFNetworking.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AFNetworking.framework; path = Carthage/Build/iOS/AFNetworking.framework; sourceTree = "<group>"; };
 		F726EEEB1FED1C820030B9C8 /* NCEndToEndInitialize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCEndToEndInitialize.swift; sourceTree = "<group>"; };
 		F7296A661C8880ED001A7809 /* CCloadItemData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CCloadItemData.swift; sourceTree = "<group>"; };
@@ -791,7 +787,6 @@
 		F732BA041D76CE1500E9878B /* CCNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCNetworking.m; sourceTree = "<group>"; };
 		F733B65121997CC1001C1FFA /* TLPhotoPicker.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = TLPhotoPicker.framework; path = Carthage/Build/iOS/TLPhotoPicker.framework; sourceTree = "<group>"; };
 		F7362A1E220C853A005101B5 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
-		F736B54D234DCE43008A5C9F /* NCCommunication.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCCommunication.swift; sourceTree = "<group>"; };
 		F736B551234DCF57008A5C9F /* Alamofire.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Alamofire.framework; path = Carthage/Build/iOS/Alamofire.framework; sourceTree = "<group>"; };
 		F7381EDA218218C9000B1560 /* NCOffline.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCOffline.swift; sourceTree = "<group>"; };
 		F7381EDE218218C9000B1560 /* NCOffline.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = NCOffline.storyboard; sourceTree = "<group>"; };
@@ -923,6 +918,7 @@
 		F758B457212C564000515F55 /* Scan.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Scan.storyboard; sourceTree = "<group>"; };
 		F758B45D212C569C00515F55 /* ScanCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScanCell.swift; sourceTree = "<group>"; };
 		F758B45F212C56A400515F55 /* ScanCollectionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScanCollectionView.swift; sourceTree = "<group>"; };
+		F75A9EE523796C6F0044CFCE /* NCNetworking.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCNetworking.swift; sourceTree = "<group>"; };
 		F75AC2421F1F62450073EC19 /* NCManageAutoUploadFileName.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCManageAutoUploadFileName.swift; sourceTree = "<group>"; };
 		F75ADF441DC75FFE008A7347 /* CCLogin.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = CCLogin.storyboard; sourceTree = "<group>"; };
 		F75B91E21ECAE17800199C96 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
@@ -1363,7 +1359,6 @@
 		F7E45E6D21E75BF200579249 /* ja-JP */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ja-JP"; path = "ja-JP.lproj/Localizable.strings"; sourceTree = "<group>"; };
 		F7E4D9C322ED929B003675FD /* NCShareComments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareComments.swift; sourceTree = "<group>"; };
 		F7E856182351D7BE009A3330 /* SwiftyXMLParser.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftyXMLParser.framework; path = Carthage/Build/iOS/SwiftyXMLParser.framework; sourceTree = "<group>"; };
-		F7E8561A235202DF009A3330 /* NSCommunicationCommon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSCommunicationCommon.swift; sourceTree = "<group>"; };
 		F7E9C41520F4CA870040CF18 /* CCTransfers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCTransfers.h; sourceTree = "<group>"; };
 		F7E9C41820F4CA870040CF18 /* CCTransfers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCTransfers.m; sourceTree = "<group>"; };
 		F7ECBA6C1E239DCD003E6328 /* NCCreateFormUploadRichdocuments.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCCreateFormUploadRichdocuments.swift; sourceTree = "<group>"; };
@@ -1420,8 +1415,6 @@
 		F7F54CE41E5B14C700E19C62 /* UIImage+MWPhotoBrowser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+MWPhotoBrowser.m"; sourceTree = "<group>"; };
 		F7F67BAD1A24D27800EE80DA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
 		F7F67BB81A24D27800EE80DA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
-		F7F801001D98205A007537BC /* CCCertificate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCCertificate.h; sourceTree = "<group>"; };
-		F7F801011D98205A007537BC /* CCCertificate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCCertificate.m; sourceTree = "<group>"; };
 		F7F878AD1FB9E3B900599E4F /* NCEndToEndMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCEndToEndMetadata.swift; sourceTree = "<group>"; };
 		F7F8D7191ED6183000E711F3 /* CCCellShareExt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCCellShareExt.h; sourceTree = "<group>"; };
 		F7F8D71A1ED6183000E711F3 /* CCCellShareExt.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCCellShareExt.m; sourceTree = "<group>"; };
@@ -1441,6 +1434,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				F72FBC5C2379648F002CEAD0 /* NCCommunication.framework in Frameworks */,
 				F7267A83225DFCE800D6DB7D /* AFNetworking.framework in Frameworks */,
 				F7B6F70321BD0EA0007D194D /* JDStatusBarNotification.framework in Frameworks */,
 				F7B6F70221BD0E6D007D194D /* MBProgressHUD.framework in Frameworks */,
@@ -1456,6 +1450,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				F72FBC5D237964A2002CEAD0 /* NCCommunication.framework in Frameworks */,
 				F7267A84225DFCEC00D6DB7D /* AFNetworking.framework in Frameworks */,
 				F7C40C152199BA750004137E /* Realm.framework in Frameworks */,
 				F7C40C162199BA780004137E /* RealmSwift.framework in Frameworks */,
@@ -1468,6 +1463,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				F716FE7823795E5000FABE50 /* NCCommunication.framework in Frameworks */,
 				F7CD050C234E724A00064685 /* Alamofire.framework in Frameworks */,
 				F74C4FBB2328C3C200A23E25 /* OpenSSL.framework in Frameworks */,
 				F7421EAF2294044B00C4B7C1 /* Accelerate.framework in Frameworks */,
@@ -1903,9 +1899,7 @@
 			isa = PBXGroup;
 			children = (
 				F755BD9A20594AC7008C5FBB /* NCService.swift */,
-				F736B54D234DCE43008A5C9F /* NCCommunication.swift */,
-				F724B1CB2351BFBD00A5753B /* NCCommunicationModel.swift */,
-				F7E8561A235202DF009A3330 /* NSCommunicationCommon.swift */,
+				F75A9EE523796C6F0044CFCE /* NCNetworking.swift */,
 				F732BA031D76CE1500E9878B /* CCNetworking.h */,
 				F732BA041D76CE1500E9878B /* CCNetworking.m */,
 				F74D3DBD1BAC1941000BAE4B /* OCNetworking.h */,
@@ -2199,15 +2193,16 @@
 		F771E3D120E2392D00AFB62D /* File Provider Extension */ = {
 			isa = PBXGroup;
 			children = (
-				F771E3D220E2392D00AFB62D /* FileProviderExtension.swift */,
+				F771E3F220E239A600AFB62D /* FileProviderData.swift */,
+				F76673EC22C901F5007ED366 /* FileProviderDomain.swift */,
 				F771E3D620E2392D00AFB62D /* FileProviderEnumerator.swift */,
+				F7434B5F20E2440600417916 /* FileProviderExtension-Bridging-Header.h */,
+				F771E3D220E2392D00AFB62D /* FileProviderExtension.swift */,
 				F771E3F420E239B400AFB62D /* FileProviderExtension+Actions.swift */,
+				F716FE7923795EC500FABE50 /* FileProviderExtension+NetworkingDelegate.swift */,
 				F771E3F520E239B400AFB62D /* FileProviderExtension+Thumbnail.swift */,
 				F771E3D420E2392D00AFB62D /* FileProviderItem.swift */,
-				F76673EC22C901F5007ED366 /* FileProviderDomain.swift */,
-				F771E3F220E239A600AFB62D /* FileProviderData.swift */,
 				F76673EF22C90433007ED366 /* FileProviderUtility.swift */,
-				F7434B5F20E2440600417916 /* FileProviderExtension-Bridging-Header.h */,
 			);
 			path = "File Provider Extension";
 			sourceTree = "<group>";
@@ -2877,6 +2872,7 @@
 		F7FC7D541DC1F93700BB2C6A /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				F716FE7723795E5000FABE50 /* NCCommunication.framework */,
 				F7E856182351D7BE009A3330 /* SwiftyXMLParser.framework */,
 				F736B551234DCF57008A5C9F /* Alamofire.framework */,
 				F74C4FBA2328C3C100A23E25 /* OpenSSL.framework */,
@@ -2944,8 +2940,6 @@
 			children = (
 				F7FE125C1BAC03FB0041924B /* CCBKPasscode.h */,
 				F7FE125D1BAC03FB0041924B /* CCBKPasscode.m */,
-				F7F801001D98205A007537BC /* CCCertificate.h */,
-				F7F801011D98205A007537BC /* CCCertificate.m */,
 				F7F878AD1FB9E3B900599E4F /* NCEndToEndMetadata.swift */,
 				F72D1006210B6882009C96B7 /* NCPushNotificationEncryption.h */,
 				F72D1005210B6882009C96B7 /* NCPushNotificationEncryption.m */,
@@ -3340,6 +3334,7 @@
 				"$(SRCROOT)/Carthage/Build/iOS/OpenSSL.framework",
 				"$(SRCROOT)/Carthage/Build/iOS/Alamofire.framework",
 				"$(SRCROOT)/Carthage/Build/iOS/SwiftyXMLParser.framework",
+				"$(SRCROOT)/Carthage/Build/iOS/NCCommunication.framework",
 			);
 			outputPaths = (
 			);
@@ -3379,7 +3374,6 @@
 				F77EB6281EC08036003F814F /* CCExifGeo.m in Sources */,
 				F73CC0731E813DFF006E3047 /* BKPasscodeLockScreenManager.m in Sources */,
 				F73CC06A1E813DFF006E3047 /* BKPasscodeDummyViewController.m in Sources */,
-				F7E8561C235202DF009A3330 /* NSCommunicationCommon.swift in Sources */,
 				F73CC07C1E813DFF006E3047 /* BKTouchIDManager.m in Sources */,
 				F7B6ACD722FC2BD4008AB646 /* NCXMLCommentsParser.m in Sources */,
 				F70022B71EC4C9100080073F /* OCCapabilities.m in Sources */,
@@ -3405,8 +3399,8 @@
 				F70022CF1EC4C9100080073F /* OCShareUser.m in Sources */,
 				F71459E11D12E3B700CAFEEC /* CCHud.m in Sources */,
 				F70022EA1EC4C9100080073F /* OCXMLShareByLinkParser.m in Sources */,
-				F77EB62A1EC0B50A003F814F /* CCCertificate.m in Sources */,
 				F70022D81EC4C9100080073F /* NSDate+RFC1123.m in Sources */,
+				F75A9EE723796C6F0044CFCE /* NCNetworking.swift in Sources */,
 				F70022E71EC4C9100080073F /* OCXMLServerErrorsParser.m in Sources */,
 				F781996A22636BFA00EBDF6A /* HCFeatures.m in Sources */,
 				F70022C91EC4C9100080073F /* OCRichObjectStrings.m in Sources */,
@@ -3425,9 +3419,7 @@
 				F76B3CCF1EAE01BD00921AC9 /* NCBrand.swift in Sources */,
 				F73CC0761E813DFF006E3047 /* BKPasscodeViewController.m in Sources */,
 				F70022D21EC4C9100080073F /* OCUserProfile.m in Sources */,
-				F724B1CD2351BFBD00A5753B /* NCCommunicationModel.swift in Sources */,
 				F70022C61EC4C9100080073F /* OCNotificationsAction.m in Sources */,
-				F736B54F234DCE43008A5C9F /* NCCommunication.swift in Sources */,
 				F7BAADCC1ED5A87C00B7EAD4 /* NCManageDatabase.swift in Sources */,
 				F70022DE1EC4C9100080073F /* OCWebDAVClient.m in Sources */,
 			);
@@ -3451,13 +3443,13 @@
 				F7434B4C20E2408300417916 /* NSDate+RFC1123.m in Sources */,
 				F7434B5920E241B600417916 /* OCNetworking.m in Sources */,
 				F7434B5520E240A900417916 /* UtilsFramework.m in Sources */,
+				F75A9EE823796C6F0044CFCE /* NCNetworking.swift in Sources */,
 				F7434B4120E2405200417916 /* OCRichObjectStrings.m in Sources */,
 				F76673F022C90434007ED366 /* FileProviderUtility.swift in Sources */,
 				F7434B3420E23FD700417916 /* NCDatabase.swift in Sources */,
 				F7434B4020E2404E00417916 /* OCNotificationsAction.m in Sources */,
 				F7434B5320E2409E00417916 /* OCXMLSharedParser.m in Sources */,
 				F7434B4320E2405900417916 /* OCShareUser.m in Sources */,
-				F7434B6120E2445C00417916 /* CCCertificate.m in Sources */,
 				F7434B5A20E241BB00417916 /* NCNetworkingEndToEnd.m in Sources */,
 				F76673EE22C901F6007ED366 /* FileProviderDomain.swift in Sources */,
 				F7434B3820E2400600417916 /* NCBrand.swift in Sources */,
@@ -3472,20 +3464,18 @@
 				F7434B5E20E241EC00417916 /* CCGraphics.m in Sources */,
 				F771E3D320E2392D00AFB62D /* FileProviderExtension.swift in Sources */,
 				F7434B5B20E241D100417916 /* NCEndToEndMetadata.swift in Sources */,
-				F736B550234DCE43008A5C9F /* NCCommunication.swift in Sources */,
 				F7B6ACDD22FC2D15008AB646 /* NCComments.m in Sources */,
 				F7434B5D20E241E800417916 /* CCUtility.m in Sources */,
 				F7434B5220E2409900417916 /* OCXMLShareByLinkParser.m in Sources */,
 				F771E3D520E2392D00AFB62D /* FileProviderItem.swift in Sources */,
 				F7434B3620E23FE000417916 /* NCManageDatabase.swift in Sources */,
+				F716FE7A23795EC500FABE50 /* FileProviderExtension+NetworkingDelegate.swift in Sources */,
 				F771E3F320E239A600AFB62D /* FileProviderData.swift in Sources */,
 				F771E3D720E2392D00AFB62D /* FileProviderEnumerator.swift in Sources */,
 				F7434B4220E2405500417916 /* OCSharedDto.m in Sources */,
-				F724B1CE2351BFBD00A5753B /* NCCommunicationModel.swift in Sources */,
 				F718088F2342067C0039A736 /* NCActionSheetAppearance.swift in Sources */,
 				F7434B3F20E2404B00417916 /* OCNotifications.m in Sources */,
 				F7434B6020E2445200417916 /* CCExifGeo.m in Sources */,
-				F7E8561D235202DF009A3330 /* NSCommunicationCommon.swift in Sources */,
 				F7434B5420E240A300417916 /* NSString+Encode.m in Sources */,
 				F7434B4E20E2408A00417916 /* OCWebDAVClient.m in Sources */,
 				F771E3F820E239B500AFB62D /* FileProviderExtension+Thumbnail.swift in Sources */,
@@ -3567,6 +3557,7 @@
 				F73B4F111F470D9100BBEE4B /* nsSBCSGroupProber.cpp in Sources */,
 				F7B6ACD622FC2BD4008AB646 /* NCXMLCommentsParser.m in Sources */,
 				F738E8421F90FFD100F95C8E /* NCManageEndToEndEncryption.m in Sources */,
+				F75A9EE623796C6F0044CFCE /* NCNetworking.swift in Sources */,
 				F760F79D21F21F61006B1A73 /* CropRectView.swift in Sources */,
 				F73B4F091F470D9100BBEE4B /* nsEUCKRProber.cpp in Sources */,
 				F758B460212C56A400515F55 /* ScanCollectionView.swift in Sources */,
@@ -3624,7 +3615,6 @@
 				F762CB191EACB66200B38484 /* XLFormValidator.m in Sources */,
 				F760F78C21F21F61006B1A73 /* StickersViewController.swift in Sources */,
 				F762CB0D1EACB66200B38484 /* NSArray+XLFormAdditions.m in Sources */,
-				F7F801031D98205A007537BC /* CCCertificate.m in Sources */,
 				F77B0E4F1D118A16002130FE /* CCManageAutoUpload.m in Sources */,
 				F7FCFFE01D707B83000E6E29 /* CCPeekPop.m in Sources */,
 				F760F77D21F21F61006B1A73 /* ColorsCollectionViewDelegate.swift in Sources */,
@@ -3668,7 +3658,6 @@
 				F7DBC37F23325E2E001A85BA /* NCXMLGetAppPasswordParser.m in Sources */,
 				F750374D1DBFA91A008FB480 /* ALView+PureLayout.m in Sources */,
 				F7381EE1218218C9000B1560 /* NCOffline.swift in Sources */,
-				F7E8561B235202DF009A3330 /* NSCommunicationCommon.swift in Sources */,
 				F7D423861F0596C6009C9782 /* ReaderThumbRequest.m in Sources */,
 				F73B4EF51F470D9100BBEE4B /* JpCntx.cpp in Sources */,
 				F78071091EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m in Sources */,
@@ -3694,7 +3683,6 @@
 				F77B0E9B1D118A16002130FE /* CCBKPasscode.m in Sources */,
 				F760F77F21F21F61006B1A73 /* PhotoEditor+Controls.swift in Sources */,
 				F7169A1D1EE590930086BD69 /* NCSharesCell.m in Sources */,
-				F736B54E234DCE43008A5C9F /* NCCommunication.swift in Sources */,
 				F77B0EA61D118A16002130FE /* NSString+TruncateToWidth.m in Sources */,
 				F70022C21EC4C9100080073F /* OCNotifications.m in Sources */,
 				F70022BF1EC4C9100080073F /* OCFileDto.m in Sources */,
@@ -3746,7 +3734,6 @@
 				F745B253222D88AE00346520 /* NCLoginQRCode.swift in Sources */,
 				F760F79221F21F61006B1A73 /* EmojisCollectionViewDelegate.swift in Sources */,
 				F7169A1C1EE590930086BD69 /* NCShares.m in Sources */,
-				F724B1CC2351BFBD00A5753B /* NCCommunicationModel.swift in Sources */,
 				F769454822E9F20D000A798A /* NCShareNetworking.swift in Sources */,
 				F77B0EC61D118A16002130FE /* CCCellMain.m in Sources */,
 				F7C9555521F0C5470024296E /* NCActivity.swift in Sources */,

+ 0 - 1
Share/NCSelectDestination.h

@@ -26,7 +26,6 @@
 
 #import "CCBKPasscode.h"
 #import "CCUtility.h"
-#import "OCNetworking.h"
 #import "CCHud.h"
 
 @class tableMetadata;

+ 26 - 48
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,10 +52,7 @@
     if (tableAccount) {
         
         activeAccount = tableAccount.account;
-        activePassword = [CCUtility getPassword:tableAccount.account];
         activeUrl = tableAccount.url;
-        activeUser = tableAccount.user;
-        activeUserID = tableAccount.userID;
         
     } else {
         
@@ -103,7 +97,7 @@
     _autoUploadDirectory = [[NCManageDatabase sharedInstance] getAccountAutoUploadDirectory:activeUrl];
     
     // read file->folder
-    [self readFile];
+    [self readFolder];
 }
 
 // Apparirà
@@ -268,62 +262,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, NSInteger errorCode, NSString *errorDecription) {
+        
+        if (errorCode == 0 && 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] addMetadatasWithFiles: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:errorDecription 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 +313,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, NSInteger errorCode, NSString *errorDecription) {
+        if (errorCode == 0) {
+           [self readFolder];
+        } else {
+            UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_error_",nil) message:errorDecription 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.");
         }
     }];
 }

+ 0 - 1
Share/Share-Bridging-Header.h

@@ -12,4 +12,3 @@
 #import "OCSharedDto.h"
 #import "HCFeatures.h"
 #import "NCComments.h"
-#import "CCCertificate.h"

+ 0 - 8
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;

+ 20 - 27
Share/ShareViewController.m

@@ -57,11 +57,10 @@
         
     } else {
         
+        // Networking
+        [[NCCommunicationCommon sharedInstance] setupWithUsername:tableAccount.userID password:[CCUtility getPassword:tableAccount.account] userAgent:[CCUtility getUserAgent] capabilitiesGroup:[NCBrandOptions sharedInstance].capabilitiesGroups delegate:[NCNetworking sharedInstance]];
+       
         _activeAccount = tableAccount.account;
-        _activePassword = [CCUtility getPassword:tableAccount.account];
-        _activeUrl = tableAccount.url;
-        _activeUser = tableAccount.user;
-        _activeUserID = tableAccount.userID;
         
         if ([_activeAccount isEqualToString:[CCUtility getActiveAccountExt]]) {
             
@@ -77,7 +76,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 +211,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 fileNameLocalPath:fileNameLocal account:self.activeAccount progressHandler:^(NSProgress * progress) {
+            [self.hud progress:progress.fractionCompleted];
+        } completionHandler:^(NSString *account, NSString *ocId, NSString *etag, NSDate *date, NSInteger errorCode, NSString *errorDescription) {
             [self.hud hideHud];
-            
             [self.filesName removeObject:fileName];
-
+           
             if (errorCode == 0) {
-                
+               
                 [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 +231,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: errorDescription 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];
             }

+ 22 - 2
iOSClient/AppDelegate.m

@@ -53,6 +53,9 @@ PKPushRegistry *pushRegistry;
 {
     [CCUtility createDirectoryStandard];
     
+    // Networking
+    [[NCCommunicationCommon sharedInstance] setupWithUserAgent:[CCUtility getUserAgent] capabilitiesGroup:[NCBrandOptions sharedInstance].capabilitiesGroups delegate:[NCNetworking sharedInstance]];
+    
     // Verify upgrade
     if ([self upgrade]) {
         // Set account, if no exists clear all
@@ -268,12 +271,26 @@ PKPushRegistry *pushRegistry;
     
     // check unauthorized server (401)
     if ([CCUtility getPassword:self.activeAccount].length == 0) {
+        
         [self openLoginView:self.window.rootViewController selector:k_intro_login openLoginWeb:true];
     }
     
     // check certificate untrusted (-1202)
     if ([CCUtility getCertificateError:self.activeAccount]) {
-        [[CCCertificate sharedManager] presentViewControllerCertificateWithAccount:self.activeAccount viewController:self.window.rootViewController delegate:self];
+        
+        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_ssl_certificate_untrusted_", nil) message:NSLocalizedString(@"_connect_server_anyway_", nil)  preferredStyle:UIAlertControllerStyleAlert];
+        [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_yes_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
+            [[NCNetworking sharedInstance] wrtiteCertificateWithDirectoryCertificate:[CCUtility getDirectoryCerificates]];
+            [self startTimerErrorNetworking];
+        }]];
+                       
+        [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_no_", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
+            [self startTimerErrorNetworking];
+        }]];
+        [self.window.rootViewController presentViewController:alertController animated:YES completion:^{
+            // Stop timer error network
+            [self.timerErrorNetworking invalidate];
+        }];
     }
 }
 
@@ -383,6 +400,9 @@ PKPushRegistry *pushRegistry;
     
     // Setting Account to Networking
     [CCNetworking sharedNetworking].delegate = [NCNetworkingMain sharedInstance];
+    
+    [[NCNetworking sharedInstance] setupWithAccount:activeAccount delegate:nil];
+    [[NCCommunicationCommon sharedInstance] setupWithUsername:activeUserID password:activePassword userAgent:[CCUtility getUserAgent] capabilitiesGroup:[NCBrandOptions sharedInstance].capabilitiesGroups delegate:[NCNetworking sharedInstance]];
 }
 
 - (void)deleteAccount:(NSString *)account wipe:(BOOL)wipe
@@ -1434,7 +1454,7 @@ PKPushRegistry *pushRegistry;
     
     // Verify internal error download (lost task)
     //
-    NSArray *matadatasInDownloading = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"session != %@ AND status == %d", k_download_session_extension, k_metadataStatusDownloading] sorted:nil ascending:true];
+    NSArray *matadatasInDownloading = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"status == %d", k_metadataStatusDownloading] sorted:nil ascending:true];
     for (tableMetadata *metadata in matadatasInDownloading) {
         
         NSURLSession *session = [[CCNetworking sharedNetworking] getSessionfromSessionDescription:metadata.session];

+ 1 - 1
iOSClient/Brand/File_Provider_Extension.plist

@@ -17,7 +17,7 @@
 	<key>CFBundlePackageType</key>
 	<string>XPC!</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.24.4</string>
+	<string>2.24.5</string>
 	<key>CFBundleVersion</key>
 	<string>1</string>
 	<key>NSAppTransportSecurity</key>

+ 1 - 1
iOSClient/Brand/Share.plist

@@ -17,7 +17,7 @@
 	<key>CFBundlePackageType</key>
 	<string>XPC!</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.24.4</string>
+	<string>2.24.5</string>
 	<key>CFBundleVersion</key>
 	<string>1</string>
 	<key>NSAppTransportSecurity</key>

+ 1 - 1
iOSClient/Brand/iOSClient.plist

@@ -46,7 +46,7 @@
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.24.4</string>
+	<string>2.24.5</string>
 	<key>CFBundleSignature</key>
 	<string>????</string>
 	<key>CFBundleURLTypes</key>

+ 4 - 5
iOSClient/CCGlobal.h

@@ -82,7 +82,7 @@
 
 // Database Realm
 #define k_databaseDefault                               @"nextcloud.realm"
-#define k_databaseSchemaVersion                         79
+#define k_databaseSchemaVersion                         80
 
 // Intro selector
 #define k_intro_login                                   0
@@ -93,9 +93,6 @@
 #define k_login_Add_Forced                              1
 #define k_login_Add_SignUp                              2
 
-// Picker select image
-#define k_pickerControllerMax                           1000.0
-
 // define Nextcloud IOS
 #define k_share_link_middle_part_url_after_version_8    @"index.php/s/"
 
@@ -124,7 +121,6 @@
 #define k_upload_session_wwan                           @"it.twsweb.Crypto-Cloud.upload.sessionwwan"
 
 // Session Download Upload Extension
-#define k_download_session_extension                    @"com.nextcloud.download.session.extension"
 #define k_upload_session_extension                      @"com.nextcloud.upload.session.extension"
 
 // OperationQueue
@@ -304,5 +300,8 @@
 #define k_nextcloud_version_17_0                        17
 
 // -----------------------------------------------------------------------------------------------------------
+// INTERNAL
 // -----------------------------------------------------------------------------------------------------------
 
+#define k_fileProvider_domain                           0
+

+ 0 - 5
iOSClient/Database/NCDatabase.swift

@@ -199,11 +199,6 @@ class tableCapabilities: Object {
     @objc dynamic var isExtendedSupportEnabled: Bool = false
 }
 
-class tableCertificates: Object {
-    
-    @objc dynamic var certificateLocation = ""
-}
-
 class tableComments: Object {
     
     @objc dynamic var account = ""

+ 101 - 97
iOSClient/Database/NCManageDatabase.swift

@@ -22,6 +22,7 @@
 //
 
 import RealmSwift
+import NCCommunication
 
 class NCManageDatabase: NSObject {
         
@@ -35,80 +36,98 @@ class NCManageDatabase: NSObject {
         let dirGroup = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: NCBrandOptions.sharedInstance.capabilitiesGroups)
         let databaseFilePath = dirGroup?.appendingPathComponent("\(k_appDatabaseNextcloud)/\(k_databaseDefault)")
 
-        let configCompact = Realm.Configuration(
+        let bundleUrl: URL = Bundle.main.bundleURL
+        let bundlePathExtension: String = bundleUrl.pathExtension
+        let isAppex: Bool = bundlePathExtension == "appex"
+        
+        if isAppex {
             
-            fileURL: databaseFilePath,
-            schemaVersion: UInt64(k_databaseSchemaVersion),
+            // App Extension config
             
-            migrationBlock: { migration, oldSchemaVersion in
-                
-                if oldSchemaVersion < 41 {
-                    migration.deleteData(forType: tableActivity.className())
-                    migration.deleteData(forType: tableMetadata.className())
-                    migration.deleteData(forType: tableDirectory.className())
-                }
+            let config = Realm.Configuration(
+                fileURL: dirGroup?.appendingPathComponent("\(k_appDatabaseNextcloud)/\(k_databaseDefault)"),
+                schemaVersion: UInt64(k_databaseSchemaVersion),
+                objectTypes: [tableMetadata.self, tableLocalFile.self, tableDirectory.self, tableTag.self, tableAccount.self, tableCapabilities.self]
+            )
+            
+            Realm.Configuration.defaultConfiguration = config
+            
+        } else {
+            
+            // App config
+
+            let configCompact = Realm.Configuration(
                 
-                if oldSchemaVersion < 61 {
-                    migration.deleteData(forType: tableShare.className())
-                }
+                fileURL: databaseFilePath,
+                schemaVersion: UInt64(k_databaseSchemaVersion),
                 
-                if oldSchemaVersion < 74 {
+                migrationBlock: { migration, oldSchemaVersion in
                     
-                    migration.enumerateObjects(ofType: tableLocalFile.className()) { oldObject, newObject in
-                        newObject!["ocId"] = oldObject!["fileID"]
+                    if oldSchemaVersion < 41 {
+                        migration.deleteData(forType: tableActivity.className())
+                        migration.deleteData(forType: tableMetadata.className())
+                        migration.deleteData(forType: tableDirectory.className())
                     }
                     
-                    migration.enumerateObjects(ofType: tableTrash.className()) { oldObject, newObject in
-                        newObject!["fileId"] = oldObject!["fileID"]
+                    if oldSchemaVersion < 61 {
+                        migration.deleteData(forType: tableShare.className())
                     }
                     
-                    migration.enumerateObjects(ofType: tableTag.className()) { oldObject, newObject in
-                        newObject!["ocId"] = oldObject!["fileID"]
+                    if oldSchemaVersion < 74 {
+                        
+                        migration.enumerateObjects(ofType: tableLocalFile.className()) { oldObject, newObject in
+                            newObject!["ocId"] = oldObject!["fileID"]
+                        }
+                        
+                        migration.enumerateObjects(ofType: tableTrash.className()) { oldObject, newObject in
+                            newObject!["fileId"] = oldObject!["fileID"]
+                        }
+                        
+                        migration.enumerateObjects(ofType: tableTag.className()) { oldObject, newObject in
+                            newObject!["ocId"] = oldObject!["fileID"]
+                        }
+                        
+                        migration.enumerateObjects(ofType: tableE2eEncryptionLock.className()) { oldObject, newObject in
+                            newObject!["ocId"] = oldObject!["fileID"]
+                        }
                     }
                     
-                    migration.enumerateObjects(ofType: tableE2eEncryptionLock.className()) { oldObject, newObject in
-                        newObject!["ocId"] = oldObject!["fileID"]
+                    if oldSchemaVersion < 78 {
+                        migration.deleteData(forType: tableActivity.className())
+                        migration.deleteData(forType: tableActivityPreview.className())
+                        migration.deleteData(forType: tableActivitySubjectRich.className())
+                        migration.deleteData(forType: tableComments.className())
+                        migration.deleteData(forType: tableDirectory.className())
+                        migration.deleteData(forType: tableMetadata.className())
+                        migration.deleteData(forType: tableMedia.className())
+                        migration.deleteData(forType: tableE2eEncryptionLock.className())
+                        migration.deleteData(forType: tableTag.className())
+                        migration.deleteData(forType: tableTrash.className())
                     }
+                    
+                }, shouldCompactOnLaunch: { totalBytes, usedBytes in
+                    
+                    // totalBytes refers to the size of the file on disk in bytes (data + free space)
+                    // usedBytes refers to the number of bytes used by data in the file
+                    
+                    // Compact if the file is over 100MB in size and less than 50% 'used'
+                    let oneHundredMB = 100 * 1024 * 1024
+                    return (totalBytes > oneHundredMB) && (Double(usedBytes) / Double(totalBytes)) < 0.5
                 }
-                
-                if oldSchemaVersion < 78 {
-                    migration.deleteData(forType: tableActivity.className())
-                    migration.deleteData(forType: tableActivityPreview.className())
-                    migration.deleteData(forType: tableActivitySubjectRich.className())
-                    migration.deleteData(forType: tableComments.className())
-                    migration.deleteData(forType: tableDirectory.className())
-                    migration.deleteData(forType: tableMetadata.className())
-                    migration.deleteData(forType: tableMedia.className())
-                    migration.deleteData(forType: tableE2eEncryptionLock.className())
-                    migration.deleteData(forType: tableTag.className())
-                    migration.deleteData(forType: tableTrash.className())
-                }
-                
-            }, shouldCompactOnLaunch: { totalBytes, usedBytes in
-                
-                // totalBytes refers to the size of the file on disk in bytes (data + free space)
-                // usedBytes refers to the number of bytes used by data in the file
-                
-                // Compact if the file is over 100MB in size and less than 50% 'used'
-                let oneHundredMB = 100 * 1024 * 1024
-                return (totalBytes > oneHundredMB) && (Double(usedBytes) / Double(totalBytes)) < 0.5
-            }
-        )
-        
-        do {
-            // Realm is compacted on the first open if the configuration block conditions were met.
-            _ = try Realm(configuration: configCompact)
-        } catch {
-            // handle error compacting or opening Realm
+            )
+            
+            do {
+                _ = try Realm(configuration: configCompact)
+            } catch { }
+                        
+            let config = Realm.Configuration(
+                fileURL: dirGroup?.appendingPathComponent("\(k_appDatabaseNextcloud)/\(k_databaseDefault)"),
+                schemaVersion: UInt64(k_databaseSchemaVersion)
+            )
+            
+            Realm.Configuration.defaultConfiguration = config
         }
         
-        let config = Realm.Configuration(
-        
-            fileURL: dirGroup?.appendingPathComponent("\(k_appDatabaseNextcloud)/\(k_databaseDefault)"),
-            schemaVersion: UInt64(k_databaseSchemaVersion)
-        )
-        
-        Realm.Configuration.defaultConfiguration = config
         _ = try! Realm()
     }
     
@@ -973,37 +992,6 @@ class NCManageDatabase: NSObject {
         return Array(result.richdocumentsMimetypes)
     }
     
-    //MARK: -
-    //MARK: Table Certificates
-    
-    @objc func addCertificates(_ certificateLocation: String) {
-    
-        let realm = try! Realm()
-
-        do {
-            try realm.write {
-
-                let addObject = tableCertificates()
-            
-                addObject.certificateLocation = certificateLocation
-            
-                realm.add(addObject)
-            }
-        } catch let error {
-            print("[LOG] Could not write to database: ", error)
-        }
-    }
-    
-    @objc func getCertificatesLocation(_ localCertificatesFolder: String) -> [String] {
-        
-        let realm = try! Realm()
-        realm.refresh()
-        
-        let results = realm.objects(tableCertificates.self)
-    
-        return Array(results.map { "\(localCertificatesFolder)/\($0.certificateLocation)" })
-    }
-   
     //MARK: -
     //MARK: Table Comments
     
@@ -1781,7 +1769,7 @@ class NCManageDatabase: NSObject {
         return Array(metadatas.map { tableMetadata.init(value:$0) })
     }
 
-    @objc func addMetadata(files: [NCFile], account: String, serverUrl: String, removeFirst: Bool) {
+    @objc func addMetadatas(files: [NCFile], account: String, serverUrl: String, removeFirst: Bool) {
     
         var isNotFirstFileOfList: Bool = false
         let realm = try! Realm()
@@ -1795,6 +1783,10 @@ class NCManageDatabase: NSObject {
                         continue
                     }
                     
+                    if !CCUtility.getShowHiddenFiles() && file.fileName.first == "." {
+                        continue
+                    }
+                    
                     let metadata = tableMetadata()
                     
                     metadata.account = account
@@ -1819,8 +1811,25 @@ 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 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)
+                    }
                 }
             }
         } catch let error {
@@ -1828,11 +1837,6 @@ class NCManageDatabase: NSObject {
             return
         }
         
-        // Create directory records
-        for file in files {
-            if file.directory { _ = self.addDirectory(encrypted: file.e2eEncrypted, favorite: file.favorite, ocId: file.ocId, permissions: file.permissions, serverUrl: CCUtility.stringAppendServerUrl(serverUrl, addFileName: file.fileName), account: account) }
-        }
-        
         self.setDateReadDirectory(serverUrl: serverUrl, account: account)
     }
     

+ 56 - 2
iOSClient/Favorites/CCFavorites.m

@@ -158,12 +158,13 @@
 {
     NSString *fileNameServerUrl = [CCUtility returnFileNamePathFromFileName:metadata.fileName serverUrl:metadata.serverUrl activeUrl:appDelegate.activeUrl];
     
-    [[OCNetworking sharedManager] settingFavoriteWithAccount:appDelegate.activeAccount fileName:fileNameServerUrl favorite:favorite completion:^(NSString *account, NSString *message, NSInteger errorCode) {
+    [[NCCommunication sharedInstance] setFavoriteWithUrlString:appDelegate.activeUrl fileName:fileNameServerUrl favorite:favorite account:appDelegate.activeAccount completionHandler:^(NSString *account, NSInteger errorCode, NSString *errorDecription) {
+        
         if (errorCode == 0 && [account isEqualToString:appDelegate.activeAccount]) {
             [[NCManageDatabase sharedInstance] setMetadataFavoriteWithOcId:metadata.ocId favorite:favorite];
             [[NCMainCommon sharedInstance] reloadDatasourceWithServerUrl:metadata.serverUrl ocId:metadata.ocId action:k_action_MOD];
         } else if (errorCode != 0) {
-            [appDelegate messageNotification:@"_error_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
+            [appDelegate messageNotification:@"_error_" description:errorDecription visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
         } else {
             NSLog(@"[LOG] It has been changed user during networking process, error.");
         }
@@ -180,6 +181,59 @@
     if (appDelegate.activeAccount.length == 0)
         return;
     
+    [[NCCommunication sharedInstance] listingFavoritesWithUrlString:appDelegate.activeUrl account:appDelegate.activeAccount completionHandler:^(NSString *account, NSArray *files, NSInteger errorCode, NSString *errorDescription) {
+        
+        if (errorCode == 0 && [account isEqualToString:appDelegate.activeAccount]) {
+            
+            NSString *father = @"";
+            NSMutableArray *filesOcId = [NSMutableArray new];
+            
+            NSArray *metadatas = [[NCNetworking sharedInstance] convertFiles:files urlString:[CCUtility getHomeServerUrlActiveUrl:appDelegate.activeUrl] serverUrl:nil user:appDelegate.activeUserID];
+            
+            for (tableMetadata *metadata in metadatas) {
+                
+                // insert for test NOT favorite
+                [filesOcId addObject:metadata.ocId];
+                
+                NSString *serverUrl = metadata.serverUrl;
+                NSString *serverUrlSon = [CCUtility stringAppendServerUrl:serverUrl addFileName:metadata.fileName];
+                
+                if (![serverUrlSon containsString:father]) {
+                    
+                    if (metadata.directory) {
+                        
+                        if ([CCUtility getFavoriteOffline])
+                            [[CCSynchronize sharedSynchronize] readFolder:[CCUtility stringAppendServerUrl:serverUrl addFileName:metadata.fileName] selector:selectorReadFolderWithDownload account:account];
+                        else
+                            [[CCSynchronize sharedSynchronize] readFolder:[CCUtility stringAppendServerUrl:serverUrl addFileName:metadata.fileName] selector:selectorReadFolder account:account];
+                        
+                    } else {
+                        
+                        if ([CCUtility getFavoriteOffline])
+                            [[CCSynchronize sharedSynchronize] readFile:metadata.ocId fileName:metadata.fileName serverUrl:serverUrl selector:selectorReadFileWithDownload account:account];
+                        else
+                            [[CCSynchronize sharedSynchronize] readFile:metadata.ocId fileName:metadata.fileName serverUrl:serverUrl selector:selectorReadFile account:account];
+                    }
+                    
+                    father = serverUrlSon;
+                }
+            }
+            
+            // Verify remove favorite
+            NSArray *allRecordFavorite = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND favorite == true", account] sorted:nil ascending:NO];
+            
+            for (tableMetadata *metadata in allRecordFavorite) {
+                if (![filesOcId containsObject:metadata.ocId])
+                    [[NCManageDatabase sharedInstance] setMetadataFavoriteWithOcId:metadata.ocId favorite:NO];
+            }
+            
+        } else if (errorCode != 0) {
+            [appDelegate messageNotification:@"_error_" description:errorDescription visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
+        } else {
+            NSLog(@"[LOG] It has been changed user during networking process, error.");
+        }
+    }];
+    
     [[OCNetworking sharedManager] listingFavoritesWithAccount:appDelegate.activeAccount completion:^(NSString *account, NSArray *metadatas, NSString *message, NSInteger errorCode) {
         
         if (errorCode == 0 && [account isEqualToString:appDelegate.activeAccount]) {

+ 15 - 0
iOSClient/Images.xcassets/microphone_off.imageset/Contents.json

@@ -0,0 +1,15 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "filename" : "microphone_off.pdf"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  },
+  "properties" : {
+    "preserves-vector-representation" : true
+  }
+}

BIN
iOSClient/Images.xcassets/microphone_off.imageset/microphone_off.pdf


+ 1 - 2
iOSClient/Login/CCLogin.h

@@ -24,13 +24,12 @@
 #import <UIKit/UIKit.h>
 
 #import "UIImage+animatedGIF.h"
-#import "CCCertificate.h"
 #import "OCNetworking.h"
 
 @class NCLoginWeb;
 @class NCLoginQRCode;
 
-@interface CCLogin : UIViewController <UITextFieldDelegate, CCCertificateDelegate>
+@interface CCLogin : UIViewController <UITextFieldDelegate>
 
 @property (nonatomic, weak) IBOutlet UIImageView *imageBrand;
 

+ 17 - 15
iOSClient/Login/CCLogin.m

@@ -174,8 +174,8 @@
     // Remove trailing slash
     if ([self.baseUrl.text hasSuffix:@"/"])
         self.baseUrl.text = [self.baseUrl.text substringToIndex:[self.baseUrl.text length] - 1];
-    
-    [[OCNetworking sharedManager] serverStatusUrl:self.baseUrl.text completion:^(NSString *serverProductName, NSInteger versionMajor, NSInteger versionMicro, NSInteger versionMinor, BOOL extendedSupport, NSString *message, NSInteger errorCode) {
+        
+    [[NCCommunication sharedInstance] getServerStatusWithUrlString:self.baseUrl.text completionHandler:^(NSString *serverProductName, NSString *serverVersion, NSInteger versionMajor, NSInteger versionMinor, NSInteger versionMicro, BOOL extendedSupport, NSInteger errorCode, NSString *errorDescription) {
         
         if (errorCode == 0) {
             
@@ -211,31 +211,33 @@
             
             if (errorCode == NSURLErrorServerCertificateUntrusted) {
                 
-                [[CCCertificate sharedManager] presentViewControllerCertificateWithAccount:nil viewController:self delegate:self];
+                UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_ssl_certificate_untrusted_", nil) message:NSLocalizedString(@"_connect_server_anyway_", nil)  preferredStyle:UIAlertControllerStyleAlert];
+                [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_yes_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
+                    [[NCNetworking sharedInstance] wrtiteCertificateWithDirectoryCertificate:[CCUtility getDirectoryCerificates]];
+                    [appDelegate startTimerErrorNetworking];
+                }]];
+                               
+                [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_no_", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
+                    [appDelegate startTimerErrorNetworking];
+                }]];
+                [self presentViewController:alertController animated:YES completion:^{
+                    // Stop timer error network
+                    [appDelegate.timerErrorNetworking invalidate];
+                }];
                 
             } else {
                 
-                UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_connection_error_", nil) message:message preferredStyle:UIAlertControllerStyleAlert];
+                UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_connection_error_", nil) message:errorDescription preferredStyle:UIAlertControllerStyleAlert];
                 UIAlertAction *okAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {}];
                 
                 [alertController addAction:okAction];
                 [self presentViewController:alertController animated:YES completion:nil];
             }
         }
+        
     }];
 }
 
-- (void)trustedCerticateAccepted
-{
-    NSLog(@"[LOG] Certificate trusted");
-}
-
-- (void)trustedCerticateDenied
-{
-   // if (_loginType == k_login_Modify_Password)
-        //[self handleAnnulla:self];
-}
-
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark == TextField ==
 #pragma --------------------------------------------------------------------------------------------

+ 10 - 5
iOSClient/Main/CCMain.m

@@ -382,7 +382,11 @@
     
     // Registeration domain File Provider
     if (@available(iOS 11, *) ) {
-        [FileProviderDomain.sharedInstance registerDomain];
+        if (k_fileProvider_domain) {
+            [FileProviderDomain.sharedInstance registerDomain];
+        } else {
+            [FileProviderDomain.sharedInstance removeAllDomain];
+        }        
     }    
 }
 
@@ -773,7 +777,7 @@
 
 - (void)openAssetsPickerController
 {
-    NCPhotosPickerViewController *viewController = [[NCPhotosPickerViewController alloc] init:self];
+    NCPhotosPickerViewController *viewController = [[NCPhotosPickerViewController alloc] init:self maxSelectedAssets:100];
     
     [viewController openPhotosPickerViewControllerWithPhAssets:^(NSArray<PHAsset *> * _Nonnull assets) {
         if (assets.count > 0) {
@@ -1889,7 +1893,7 @@
 {
     NSString *fileNameServerUrl = [CCUtility returnFileNamePathFromFileName:metadata.fileName serverUrl:self.serverUrl activeUrl:appDelegate.activeUrl];
     
-    [[OCNetworking sharedManager] settingFavoriteWithAccount:appDelegate.activeAccount fileName:fileNameServerUrl favorite:favorite completion:^(NSString *account, NSString *message, NSInteger errorCode) {
+    [[NCCommunication sharedInstance] setFavoriteWithUrlString:appDelegate.activeUrl fileName:fileNameServerUrl favorite:favorite account:appDelegate.activeAccount completionHandler:^(NSString *account, NSInteger errorCode, NSString *errorDecription) {
         
         if (errorCode == 0 && [appDelegate.activeAccount isEqualToString:account]) {
             
@@ -1910,7 +1914,7 @@
                 else
                     selector = selectorReadFolder;
                 
-                [[CCSynchronize sharedSynchronize] readFolder:[CCUtility stringAppendServerUrl:self.serverUrl addFileName:metadata.fileName] selector:selector account:appDelegate.activeAccount];                
+                [[CCSynchronize sharedSynchronize] readFolder:[CCUtility stringAppendServerUrl:self.serverUrl addFileName:metadata.fileName] selector:selector account:appDelegate.activeAccount];
             }
             
             if (!metadata.directory && favorite && [CCUtility getFavoriteOffline]) {
@@ -1929,10 +1933,11 @@
             }
             
         } else if (errorCode != 0) {
-            [appDelegate messageNotification:@"_error_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
+            [appDelegate messageNotification:@"_error_" description:errorDecription visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
         } else {
             NSLog(@"[LOG] It has been changed user during networking process, error.");
         }
+        
     }];
 }
 

+ 4 - 2
iOSClient/Main/NCMainCommon.swift

@@ -28,6 +28,7 @@ import ZIPFoundation
 //MARK: - Main Common
 
 class NCMainCommon: NSObject, PhotoEditorDelegate, NCAudioRecorderViewControllerDelegate, UIDocumentInteractionControllerDelegate {
+    
     @objc static let sharedInstance: NCMainCommon = {
         let instance = NCMainCommon()
         instance.createImagesThemingColor()
@@ -1146,8 +1147,6 @@ class NCMainCommon: NSObject, PhotoEditorDelegate, NCAudioRecorderViewController
         self.appDelegate.window.rootViewController?.present(viewController, animated: true, completion: nil)
     }
     
-    func didFinishWithoutRecording(_ viewController: NCAudioRecorderViewController, fileName: String) { }
-
     func didFinishRecording(_ viewController: NCAudioRecorderViewController, fileName: String) {
         
         guard let navigationController = UIStoryboard(name: "NCCreateFormUploadVoiceNote", bundle: nil).instantiateInitialViewController() else { return }
@@ -1157,6 +1156,9 @@ class NCMainCommon: NSObject, PhotoEditorDelegate, NCAudioRecorderViewController
         viewController.setup(serverUrl: appDelegate.activeMain.serverUrl, fileNamePath: NSTemporaryDirectory() + fileName, fileName: fileName)
         self.appDelegate.window.rootViewController?.present(navigationController, animated: true, completion: nil)
     }
+    
+    func didFinishWithoutRecording(_ viewController: NCAudioRecorderViewController, fileName: String) {
+    }
 }
     
 //MARK: - Main TabBarController

+ 16 - 14
iOSClient/Main/NCPhotosPickerViewController.swift

@@ -27,10 +27,12 @@ import TLPhotoPicker
 class NCPhotosPickerViewController: NSObject {
     
     let appDelegate = UIApplication.shared.delegate as! AppDelegate
-    var sourceViewController : UIViewController
+    var sourceViewController: UIViewController
+    var maxSelectedAssets = 1
 
-    @objc init (_ viewController : UIViewController) {
+    @objc init (_ viewController: UIViewController, maxSelectedAssets: Int) {
         sourceViewController = viewController
+        self.maxSelectedAssets = maxSelectedAssets
     }
     
     @objc func openPhotosPickerViewController(phAssets: @escaping ([PHAsset]) -> ()) {
@@ -43,7 +45,7 @@ class NCPhotosPickerViewController: NSObject {
         configure.emptyMessage = NSLocalizedString("_no_albums_", comment: "")
         configure.tapHereToChange = NSLocalizedString("_tap_here_to_change_", comment: "")
         
-        configure.maxSelectedAssets = Int(k_pickerControllerMax)
+        configure.maxSelectedAssets = self.maxSelectedAssets
         configure.selectedColor = NCBrandColor.sharedInstance.brand
         
         let viewController = customPhotoPickerViewController(withTLPHAssets: { (assets) in
@@ -85,19 +87,19 @@ class customPhotoPickerViewController: TLPhotosPickerViewController {
     override func makeUI() {
         super.makeUI()
         
-        self.view.backgroundColor = NCBrandColor.sharedInstance.brand
-
-        self.navigationBar.barTintColor = NCBrandColor.sharedInstance.brand
-        self.navigationBar.tintColor = NCBrandColor.sharedInstance.brandText
-        
-        self.titleLabel.textColor = NCBrandColor.sharedInstance.brandText
-        self.subTitleLabel.textColor = NCBrandColor.sharedInstance.brandText
+        self.customNavItem.leftBarButtonItem?.tintColor = NCBrandColor.sharedInstance.textView
+        self.customNavItem.rightBarButtonItem?.tintColor = NCBrandColor.sharedInstance.textView
         
-        self.subTitleArrowImageView.image = CCGraphics.changeThemingColorImage(self.subTitleArrowImageView.image, multiplier: 1, color: NCBrandColor.sharedInstance.brandText)
+        self.titleLabel.textColor = NCBrandColor.sharedInstance.icon
+        self.subTitleLabel.textColor = NCBrandColor.sharedInstance.graySoft
+        self.subTitleArrowImageView.image = CCGraphics.changeThemingColorImage(self.subTitleArrowImageView.image, multiplier: 1, color: NCBrandColor.sharedInstance.graySoft)
         
         self.collectionView.backgroundColor = NCBrandColor.sharedInstance.backgroundView
-    }
-    
-    open override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
+        self.view.backgroundColor = NCBrandColor.sharedInstance.backgroundView
+        if CCUtility.getDarkMode() {
+            self.navigationBar.barStyle = .black
+        }
+        self.titleLabel.textColor = NCBrandColor.sharedInstance.textView
+        self.subTitleLabel.textColor = NCBrandColor.sharedInstance.textView
     }
 }

+ 26 - 4
iOSClient/Networking/CCNetworking.h

@@ -25,7 +25,6 @@
 #import "NCEndToEndEncryption.h"
 #import "NCNetworkingEndToEnd.h"
 #import "AppDelegate.h"
-#import "CCCertificate.h"
 #import "NSDate+ISO8601.h"
 #import "NSString+Encode.h"
 #import "NCBridgeSwift.h"
@@ -187,6 +186,27 @@
     return sessionUploadForeground;
 }
 
+- (NSURLSession *)sessionUploadExtension
+{
+    static NSURLSession *sessionUpload = nil;
+    
+    if (sessionUpload == nil) {
+        
+        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:k_upload_session_extension];
+        
+        configuration.allowsCellularAccess = YES;
+        configuration.sessionSendsLaunchEvents = YES;
+        configuration.discretionary = NO;
+        configuration.HTTPMaximumConnectionsPerHost = 1;
+        configuration.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
+        configuration.sharedContainerIdentifier = [NCBrandOptions sharedInstance].capabilitiesGroups;
+        
+        sessionUpload = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
+        sessionUpload.sessionDescription = k_upload_session_extension;
+    }
+    return sessionUpload;
+}
+
 - (NSURLSession *)getSessionfromSessionDescription:(NSString *)sessionDescription
 {
     if ([sessionDescription isEqualToString:k_download_session]) return [self sessionDownload];
@@ -197,6 +217,8 @@
     if ([sessionDescription isEqualToString:k_upload_session_wwan]) return [self sessionWWanUpload];
     if ([sessionDescription isEqualToString:k_upload_session_foreground]) return [self sessionUploadForeground];
     
+    if ([sessionDescription isEqualToString:k_upload_session_extension]) return [self sessionUploadExtension];
+
     return nil;
 }
 
@@ -218,8 +240,7 @@
 - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
 {
     // The pinnning check
-    
-    if ([[CCCertificate sharedManager] checkTrustedChallenge:challenge]) {
+    if ([[NCNetworking sharedInstance] checkTrustedChallengeWithChallenge:challenge directoryCertificate:[CCUtility getDirectoryCerificates]]) {
         completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
     } else {
         completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
@@ -901,7 +922,8 @@
     if ([metadata.session isEqualToString:k_upload_session]) sessionUpload = [self sessionUpload];
     else if ([metadata.session isEqualToString:k_upload_session_wwan]) sessionUpload = [self sessionWWanUpload];
     else if ([metadata.session isEqualToString:k_upload_session_foreground]) sessionUpload = [self sessionUploadForeground];
-
+    else if ([metadata.session isEqualToString:k_upload_session_extension]) sessionUpload = [self sessionUploadExtension];
+    
     NSURLSessionUploadTask *uploadTask = [sessionUpload uploadTaskWithRequest:request fromFile:[NSURL fileURLWithPath:[CCUtility getDirectoryProviderStorageOcId:metadata.ocId fileNameView:metadata.fileName]]];
     
     // Error

+ 0 - 372
iOSClient/Networking/NCCommunication.swift

@@ -1,372 +0,0 @@
-//
-//  NCCommunication.swift
-//  Nextcloud
-//
-//  Created by Marino Faggiana on 12/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 Alamofire
-import SwiftyXMLParser
-
-class NCCommunication: SessionDelegate {
-    @objc static let sharedInstance: NCCommunication = {
-        let instance = NCCommunication()
-        return instance
-    }()
-    
-    var username = ""
-    var password = ""
-    var userAgent: String?
-    
-    //MARK: - Settings
-
-    @objc func settingAccount(username: String, password: String) {
-        self.username = username
-        self.password = password
-    }
-    
-    @objc func settingUserAgent(_ userAgent: String) {
-        self.userAgent = userAgent
-    }
-    
-    //MARK: - webDAV
-
-    @objc func createFolder(serverUrl: String, fileName: String, completionHandler: @escaping (_ 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)
-            return
-        }
-        
-        // method
-        let method = HTTPMethod(rawValue: "MKCOL")
-        
-        // headers
-        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
-            switch response.result {
-            case.failure(let error):
-                completionHandler(error)
-            case .success( _):
-                completionHandler(nil)
-            }
-        }
-    }
-    
-    @objc func deleteFileOrFolder(serverUrl: String, fileName: String, completionHandler: @escaping (_ 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)
-            return
-        }
-        
-        // method
-        let method = HTTPMethod(rawValue: "DELETE")
-        
-        // headers
-        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
-            switch response.result {
-            case.failure(let error):
-                completionHandler(error)
-            case .success( _):
-                completionHandler(nil)
-            }
-        }
-    }
-    
-    @objc func moveFileOrFolder(fileNamePath: String, fileNamePathDestination: String,completionHandler: @escaping (_ error: Error?) -> Void) {
-        
-        // url
-        var url: URLConvertible
-        do {
-            try url = fileNamePath.asURL()
-        } catch let error {
-            completionHandler(error)
-            return
-        }
-        
-        // method
-        let method = HTTPMethod(rawValue: "MOVE")
-        
-        // 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: "Overwrite", value: "T")
-        
-        AF.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)
-            case .success( _):
-                completionHandler(nil)
-            }
-        }
-    }
-    
-    @objc func readFileOrFolder(serverUrl: String, depth: String, completionHandler: @escaping (_ result: [NCFile], _ error: Error?) -> Void) {
-        
-        var files = [NCFile]()
-        var isNotFirstFileOfList: Bool = false
-        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:prop>"
-
-        <d:getlastmodified />
-        <d:getetag />
-        <d:getcontenttype />
-        <d:resourcetype />
-        <d:quota-available-bytes />
-        <d:quota-used-bytes />
-
-        <permissions xmlns=\"http://owncloud.org/ns\"/>
-        <id xmlns=\"http://owncloud.org/ns\"/>
-        <fileid xmlns=\"http://owncloud.org/ns\"/>
-        <size xmlns=\"http://owncloud.org/ns\"/>
-        <favorite xmlns=\"http://owncloud.org/ns\"/>
-        <share-types xmlns=\"http://owncloud.org/ns\"/>
-        <owner-id xmlns=\"http://owncloud.org/ns\"/>
-        <owner-display-name xmlns=\"http://owncloud.org/ns\"/>
-        <comments-unread xmlns=\"http://owncloud.org/ns\"/>
-
-        <is-encrypted xmlns=\"http://nextcloud.org/ns\"/>
-        <has-preview xmlns=\"http://nextcloud.org/ns\"/>
-        <mount-type xmlns=\"http://nextcloud.org/ns\"/>
-
-        </d:prop>
-        </d:propfind>
-        """
-
-        // url
-        var serverUrl = String(serverUrl)
-        var url: URLConvertible
-        do {
-            if depth == "1" && serverUrl.last != "/" { serverUrl = serverUrl + "/" }
-            if depth == "0" && serverUrl.last == "/" { serverUrl = String(serverUrl.removeLast()) }
-            serverUrl = serverUrl.addingPercentEncoding(withAllowedCharacters: CharacterSet(charactersIn: ";?@&=$+{}<>,!'* ").inverted)! //";?@&=$+{}<>,!'*"
-            try url = serverUrl.asURL()
-        } catch let error {
-            completionHandler(files,error)
-            return
-        }
-        
-        // method
-        let method = HTTPMethod(rawValue: "PROPFIND")
-        
-        // 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"))
-        headers.update(name: "Depth", value: depth)
-
-        // request
-        var urlRequest: URLRequest
-        do {
-            try urlRequest = URLRequest(url: url, method: method, headers: headers)
-            urlRequest.httpBody = dataFile.data(using: .utf8)
-        } catch let error {
-            completionHandler(files, error)
-            return
-        }
-        
-        AF.request(urlRequest).validate(statusCode: 200..<300).responseData { (response) in
-            switch response.result {
-            case.failure(let error):
-                completionHandler(files, error)
-            case .success( _):
-                if let data = response.data {
-                    let xml = XML.parse(data)
-                    let elements = xml["d:multistatus", "d:response"]
-                    for element in elements {
-                        let file = NCFile()
-                        if let href = element["d:href"].text {
-                            var fileNamePath = href
-                            // directory
-                            if href.last == "/" {
-                                fileNamePath = String(href[..<href.index(before: href.endIndex)])
-                                file.directory = true
-                            }
-                            // path
-                            file.path = (fileNamePath as NSString).deletingLastPathComponent + "/"
-                            file.path = file.path.removingPercentEncoding ?? ""
-                            // fileName
-                            if isNotFirstFileOfList {
-                                file.fileName = (fileNamePath as NSString).lastPathComponent
-                                file.fileName = file.fileName.removingPercentEncoding ?? ""
-                            } else {
-                                file.fileName = ""
-                            }
-                        }
-                        let propstat = element["d:propstat"][0]
-                        
-                        // d:
-                        
-                        if let getlastmodified = propstat["d:prop", "d:getlastmodified"].text {
-                            if let date = NCCommunicationCommon.sharedInstance.convertDate(getlastmodified, format: "EEE, dd MMM y HH:mm:ss zzz") {
-                                file.date = date
-                            }
-                        }
-                        if let getetag = propstat["d:prop", "d:getetag"].text {
-                            file.etag = getetag.replacingOccurrences(of: "\"", with: "")
-                        }
-                        if let getcontenttype = propstat["d:prop", "d:getcontenttype"].text {
-                            file.contentType = getcontenttype
-                        }
-                        if let resourcetype = propstat["d:prop", "d:resourcetype"].text {
-                            file.resourceType = resourcetype
-                        }
-                        if let quotaavailablebytes = propstat["d:prop", "d:quota-available-bytes"].text {
-                            file.quotaAvailableBytes = Double(quotaavailablebytes) ?? 0
-                        }
-                        if let quotausedbytes = propstat["d:prop", "d:quota-used-bytes"].text {
-                            file.quotaUsedBytes = Double(quotausedbytes) ?? 0
-                        }
-                        
-                        // oc:
-                       
-                        if let permissions = propstat["d:prop", "oc:permissions"].text {
-                            file.permissions = permissions
-                        }
-                        if let ocId = propstat["d:prop", "oc:id"].text {
-                            file.ocId = ocId
-                        }
-                        if let fileId = propstat["d:prop", "oc:fileid"].text {
-                            file.fileId = fileId
-                        }
-                        if let size = propstat["d:prop", "oc:size"].text {
-                            file.size = Double(size) ?? 0
-                        }
-                        if let favorite = propstat["d:prop", "oc:favorite"].text {
-                            file.favorite = (favorite as NSString).boolValue
-                        }
-                        if let ownerid = propstat["d:prop", "oc:owner-id"].text {
-                            file.ownerId = ownerid
-                        }
-                        if let ownerdisplayname = propstat["d:prop", "oc:owner-display-name"].text {
-                            file.ownerDisplayName = ownerdisplayname
-                        }
-                        if let commentsunread = propstat["d:prop", "oc:comments-unread"].text {
-                            file.commentsUnread = (commentsunread as NSString).boolValue
-                        }
-                        
-                        // nc:
-                        if let encrypted = propstat["d:prop", "nc:encrypted"].text {
-                            file.e2eEncrypted = (encrypted as NSString).boolValue
-                        }
-                        if let haspreview = propstat["d:prop", "nc:has-preview"].text {
-                            file.hasPreview = (haspreview as NSString).boolValue
-                        }
-                        if let mounttype = propstat["d:prop", "nc:mount-type"].text {
-                            file.mountType = mounttype
-                        }
-                        
-                        isNotFirstFileOfList = true;
-                        files.append(file)
-                    }
-                }
-                completionHandler(files, nil)
-            }
-        }
-    }
-    
-    //MARK: - Download
-    
-    @objc func download(serverUrl: String, fileName: String, fileNamePathDestination: String, completionHandler: @escaping (_ 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)
-            return
-        }
-        
-        // destination
-        var destination: Alamofire.DownloadRequest.Destination?
-        if let fileNamePathDestinationURL = URL(string: fileNamePathDestination) {
-            let destinationFile: DownloadRequest.Destination = { _, _ in
-                return (fileNamePathDestinationURL, [.removePreviousFile, .createIntermediateDirectories])
-            }
-            destination = destinationFile
-        }
-        
-        // headers
-        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
-            switch response.result {
-            case.failure(let error):
-                completionHandler(error)
-            case .success( _):
-                completionHandler(nil)
-            }
-        }
-    }
-    
-    //MARK: - SessionDelegate
-
-    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 {
-            completionHandler(URLSession.AuthChallengeDisposition.performDefaultHandling, nil)
-        }
-        
-    }
-}
-

+ 0 - 55
iOSClient/Networking/NCCommunicationModel.swift

@@ -1,55 +0,0 @@
-//
-//  NCCommunicationModel.swift
-//  Nextcloud
-//
-//  Created by Marino Faggiana on 12/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
-
-//MARK: - File
-
-@objc 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()
-}
-
-//MARK: -

+ 202 - 0
iOSClient/Networking/NCNetworking.swift

@@ -0,0 +1,202 @@
+//
+//  NCNetworking.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 23/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
+import NCCommunication
+
+@objc public protocol NCNetworkingDelegate {
+    @objc optional func downloadProgress(_ progress: Double, fileName: String, ServerUrl: String, session: URLSession, task: URLSessionTask)
+    @objc optional func uploadProgress(_ progress: Double, fileName: String, ServerUrl: String, session: URLSession, task: URLSessionTask)
+    @objc optional func downloadComplete(fileName: String, serverUrl: String, etag: String?, date: NSDate?, dateLastModified: NSDate?, length: Double, description: String?, error: Error?, statusCode: Int)
+    @objc optional func uploadComplete(fileName: String, serverUrl: String, ocId: String?, etag: String?, date: NSDate? ,description: String?, error: Error?, statusCode: Int)
+}
+
+
+@objc class NCNetworking: NSObject, NCCommunicationCommonDelegate {
+    @objc public static let sharedInstance: NCNetworking = {
+        let instance = NCNetworking()
+        return instance
+    }()
+    
+    var account = ""
+    
+    // Protocol
+    var delegate: NCNetworkingDelegate?
+    
+    //MARK: - Setup
+    
+    @objc public func setup(account: String, delegate: NCNetworkingDelegate?) {
+        self.account = account
+        self.delegate = delegate
+    }
+    
+    //MARK: - Communication Delegate
+       
+    func authenticationChallenge(_ challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
+        if NCNetworking.sharedInstance.checkTrustedChallenge(challenge: challenge, directoryCertificate: CCUtility.getDirectoryCerificates()) {
+            completionHandler(URLSession.AuthChallengeDisposition.useCredential, URLCredential.init(trust: challenge.protectionSpace.serverTrust!))
+        } else {
+            completionHandler(URLSession.AuthChallengeDisposition.performDefaultHandling, nil)
+        }
+    }
+    
+    func downloadProgress(_ progress: Double, fileName: String, ServerUrl: String, session: URLSession, task: URLSessionTask) {
+        delegate?.downloadProgress?(progress, fileName: fileName, ServerUrl: ServerUrl, session: session, task: task)
+    }
+    
+    func uploadProgress(_ progress: Double, fileName: String, ServerUrl: String, session: URLSession, task: URLSessionTask) {
+        delegate?.uploadProgress?(progress, fileName: fileName, ServerUrl: ServerUrl, session: session, task: task)
+    }
+    
+    func uploadComplete(fileName: String, serverUrl: String, ocId: String?, etag: String?, date: NSDate?, description: String?, error: Error?, statusCode: Int) {
+        delegate?.uploadComplete?(fileName: fileName, serverUrl: serverUrl, ocId: ocId, etag: etag, date: date, description: description, error: error, statusCode: statusCode)
+    }
+    
+    func downloadComplete(fileName: String, serverUrl: String, etag: String?, date: NSDate?, dateLastModified: NSDate?, length: Double, description: String?, error: Error?, statusCode: Int) {
+        delegate?.downloadComplete?(fileName: fileName, serverUrl: serverUrl, etag: etag, date: date, dateLastModified: dateLastModified, length: length, description: description, error: error, statusCode: statusCode)
+    }
+    
+    //MARK: - Pinning check
+    
+    @objc 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 {
+            saveX509Certificate(trust, certName: "tmp.der", directoryCertificate: directoryCertificate)
+            do {
+                let directoryContents = try FileManager.default.contentsOfDirectory(at: directoryCertificateUrl, includingPropertiesForKeys: nil)
+                let certTmpPath = directoryCertificate+"/"+"tmp.der"
+                for file in directoryContents {
+                    let certPath = file.path
+                    if certPath == certTmpPath { continue }
+                    if FileManager.default.contentsEqual(atPath:certTmpPath, andPath: certPath) {
+                        trusted = true
+                        break
+                    }
+                }
+            } catch { print(error) }
+        }
+        
+        return trusted
+    }
+    
+    @objc func wrtiteCertificate(directoryCertificate: String) {
+        
+        let certificateAtPath = directoryCertificate + "/tmp.der"
+        let certificateToPath = directoryCertificate + "/" + CCUtility.getTimeIntervalSince197() + ".der"
+        
+        do {
+            try FileManager.default.moveItem(atPath: certificateAtPath, toPath: certificateToPath)
+        } catch { }
+    }
+    
+    private func saveX509Certificate(_ trust: SecTrust, certName: String, directoryCertificate: String) {
+        
+        let currentServerCert = 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);
+        }
+    }
+    
+    private func secTrustGetLeafCertificate(_ trust: SecTrust) -> SecCertificate? {
+        
+        let result: SecCertificate?
+        
+        if SecTrustGetCertificateCount(trust) > 0 {
+            result = SecTrustGetCertificateAtIndex(trust, 0)!
+            assert(result != nil);
+        } else {
+            result = nil
+        }
+        
+        return result
+    }
+    
+    @objc func convertFiles(_ files: [NCFile], urlString: String, serverUrl : String?, user: String) -> [tableMetadata] {
+        
+        var metadatas = [tableMetadata]()
+        
+        for file in files {
+            
+            if !CCUtility.getShowHiddenFiles() && file.fileName.first == "." { continue }
+            if file.fileName.count == 0 { continue }
+            
+            let metadata = tableMetadata()
+            
+            metadata.account = account
+            metadata.commentsUnread = file.commentsUnread
+            metadata.contentType = file.contentType
+            metadata.date = file.date
+            metadata.directory = file.directory
+            metadata.e2eEncrypted = file.e2eEncrypted
+            metadata.etag = file.etag
+            metadata.favorite = file.favorite
+            metadata.fileId = file.fileId
+            metadata.fileName = file.fileName
+            metadata.fileNameView = file.fileName
+            metadata.hasPreview = file.hasPreview
+            metadata.mountType = file.mountType
+            metadata.ocId = file.ocId
+            metadata.ownerId = file.ownerId
+            metadata.ownerDisplayName = file.ownerDisplayName
+            metadata.permissions = file.permissions
+            metadata.quotaUsedBytes = file.quotaUsedBytes
+            metadata.quotaAvailableBytes = file.quotaAvailableBytes
+            metadata.resourceType = file.resourceType
+            if serverUrl == nil {
+                metadata.serverUrl = urlString + file.path.replacingOccurrences(of: "/remote.php/dav/files/"+user, with: "").dropLast()
+            } else {
+                metadata.serverUrl = serverUrl!
+            }
+            metadata.size = file.size
+                        
+            CCUtility.insertTypeFileIconName(file.fileName, metadata: metadata)
+            
+            metadatas.append(metadata)
+        }
+        
+        return metadatas
+    }
+}

+ 0 - 1
iOSClient/Networking/NCNetworkingEndToEnd.h

@@ -24,7 +24,6 @@
 #import "NCNetworkingEndToEnd.h"
 #import "OCNetworking.h"
 #import "CCUtility.h"
-#import "CCCertificate.h"
 #import "NCBridgeSwift.h"
 
 

+ 5 - 6
iOSClient/Networking/NCService.swift

@@ -23,16 +23,16 @@
 
 import Foundation
 import SVGKit
+import NCCommunication
 
 class NCService: NSObject {
-    
-    let appDelegate = UIApplication.shared.delegate as! AppDelegate
-
     @objc static let sharedInstance: NCService = {
         let instance = NCService()
         return instance
     }()
     
+    let appDelegate = UIApplication.shared.delegate as! AppDelegate
+    
     //MARK: -
     //MARK: Start Services API NC
     
@@ -112,7 +112,7 @@ class NCService: NSObject {
     
     private func requestServerStatus() {
         
-        OCNetworking.sharedManager().serverStatusUrl(appDelegate.activeUrl, completion: { (serverProductName, versionMajor, versionMicro, versionMinor, extendedSupport, message, errorCode) in
+        NCCommunication.sharedInstance.getServerStatus(urlString: appDelegate.activeUrl) { (serverProductName, serverVersion, versionMajor, versionMinor, versionMicro, extendedSupport, errorCode, errorMessage) in
             if errorCode == 0 {
                 if extendedSupport == false {
                     if serverProductName == "owncloud" {
@@ -122,8 +122,7 @@ class NCService: NSObject {
                     }
                 }
             }
-            
-        })
+        }
     }
     
     private func requestServerCapabilities() {

+ 0 - 43
iOSClient/Networking/NSCommunicationCommon.swift

@@ -1,43 +0,0 @@
-//
-//  NSCommunicationCommon.swift
-//  Nextcloud
-//
-//  Created by Marino Faggiana on 12/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
-
-class NCCommunicationCommon: NSObject {
-    @objc static let sharedInstance: NCCommunicationCommon = {
-        let instance = NCCommunicationCommon()
-        return instance
-    }()
-
-    
-    func convertDate(_ dateString: String, format: String) -> NSDate? {
-        let dateFormatter = DateFormatter()
-        dateFormatter.locale = Locale.init(identifier: "en_US_POSIX")
-        dateFormatter.dateFormat = format
-        if let date = dateFormatter.date(from: dateString) {
-            return date as NSDate
-        } else {
-            return nil
-        }
-    }
-}

+ 2 - 3
iOSClient/Networking/OCNetworking.h

@@ -34,12 +34,11 @@
 #pragma mark ===== OCCommunication =====
 
 - (OCCommunication *)sharedOCCommunication;
-- (OCCommunication *)sharedOCCommunicationExtension;
 
 #pragma mark ===== Server =====
 
 - (void)checkServerUrl:(NSString *)serverUrl user:(NSString *)user userID:(NSString *)userID password:(NSString *)password completion:(void (^)(NSString *message, NSInteger errorCode))completion;
-- (void)serverStatusUrl:(NSString *)serverUrl completion:(void(^)(NSString *serverProductName, NSInteger versionMajor, NSInteger versionMicro, NSInteger versionMinor, BOOL extendedSupport, NSString *message, NSInteger errorCode))completion;
+//- (void)serverStatusUrl:(NSString *)serverUrl completion:(void(^)(NSString *serverProductName, NSInteger versionMajor, NSInteger versionMicro, NSInteger versionMinor, BOOL extendedSupport, NSString *message, NSInteger errorCode))completion;
 - (void)downloadContentsOfUrl:(NSString *)serverUrl completion:(void(^)(NSData *data, NSString *message, NSInteger errorCode))completion;
 - (void)getAppPassword:(NSString *)serverUrl username:(NSString *)username password:(NSString *)password completion:(void(^)(NSString *token, NSString *message, NSInteger errorCode))completion;
 
@@ -68,7 +67,7 @@
 #pragma mark ===== Favorite =====
 
 - (void)listingFavoritesWithAccount:(NSString *)account completion:(void(^)(NSString *account, NSArray *metadatas, NSString *message, NSInteger errorCode))completion;
-- (void)settingFavoriteWithAccount:(NSString *)account fileName:(NSString *)fileName favorite:(BOOL)favorite completion:(void (^)(NSString *account, NSString *message, NSInteger errorCode))completion;
+
 
 #pragma mark ===== Share =====
 

+ 4 - 47
iOSClient/Networking/OCNetworking.m

@@ -25,7 +25,6 @@
 
 #import "CCUtility.h"
 #import "CCGraphics.h"
-#import "CCCertificate.h"
 #import "NSString+Encode.h"
 #import "NCBridgeSwift.h"
 #import "NCXMLGetAppPasswordParser.h"
@@ -108,50 +107,6 @@
     return sharedOCCommunication;
 }
 
-- (OCCommunication *)sharedOCCommunicationExtension
-{
-    static OCCommunication *sharedOCCommunicationExtension = nil;
-    
-    if (sharedOCCommunicationExtension == nil)
-    {
-        // Download
-        NSURLSessionConfiguration *configurationDownload = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:k_download_session_extension];
-        configurationDownload.sharedContainerIdentifier = [NCBrandOptions sharedInstance].capabilitiesGroups;
-        configurationDownload.HTTPMaximumConnectionsPerHost = 1;
-        configurationDownload.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
-        configurationDownload.timeoutIntervalForRequest = k_timeout_upload;
-        configurationDownload.sessionSendsLaunchEvents = YES;
-        configurationDownload.allowsCellularAccess = YES;
-        configurationDownload.discretionary = NO;
-        
-        OCURLSessionManager *downloadSessionManager = [[OCURLSessionManager alloc] initWithSessionConfiguration:configurationDownload];
-        [downloadSessionManager.operationQueue setMaxConcurrentOperationCount:1];
-        [downloadSessionManager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition (NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential) {
-            return NSURLSessionAuthChallengePerformDefaultHandling;
-        }];
-        
-        // Upload
-        NSURLSessionConfiguration *configurationUpload = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:k_upload_session_extension];
-        configurationUpload.sharedContainerIdentifier = [NCBrandOptions sharedInstance].capabilitiesGroups;
-        configurationUpload.HTTPMaximumConnectionsPerHost = 1;
-        configurationUpload.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
-        configurationUpload.timeoutIntervalForRequest = k_timeout_upload;
-        configurationUpload.sessionSendsLaunchEvents = YES;
-        configurationUpload.allowsCellularAccess = YES;
-        configurationUpload.discretionary = NO;
-        
-        OCURLSessionManager *uploadSessionManager = [[OCURLSessionManager alloc] initWithSessionConfiguration:configurationUpload];
-        [uploadSessionManager.operationQueue setMaxConcurrentOperationCount:k_maxHTTPConnectionsPerHost];
-        [uploadSessionManager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition (NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential) {
-            return NSURLSessionAuthChallengePerformDefaultHandling;
-        }];
-        
-        sharedOCCommunicationExtension = [[OCCommunication alloc] initWithUploadSessionManager:uploadSessionManager andDownloadSessionManager:downloadSessionManager andNetworkSessionManager:nil];
-    }
-    
-    return sharedOCCommunicationExtension;
-}
-
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark ===== Server =====
 #pragma --------------------------------------------------------------------------------------------
@@ -185,6 +140,7 @@
     }];
 }
 
+/*
 - (void)serverStatusUrl:(NSString *)serverUrl completion:(void(^)(NSString *serverProductName, NSInteger versionMajor, NSInteger versionMicro, NSInteger versionMinor, BOOL extendedSupport,NSString *message, NSInteger errorCode))completion
 {
     NSString *urlTest = [serverUrl stringByAppendingString:k_serverStatus];
@@ -274,6 +230,7 @@
     
     [task resume];
 }
+*/
 
 - (void)downloadContentsOfUrl:(NSString *)serverUrl completion:(void(^)(NSData *data, NSString *message, NSInteger errorCode))completion
 {
@@ -3040,7 +2997,7 @@
 -(void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler
 {
     // The pinnning check
-    if ([[CCCertificate sharedManager] checkTrustedChallenge:challenge]) {
+    if ([[NCNetworking sharedInstance] checkTrustedChallengeWithChallenge:challenge directoryCertificate:[CCUtility getDirectoryCerificates]]) {
         completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
     } else {
         completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
@@ -3058,7 +3015,7 @@
 - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
 {
     // The pinnning check
-    if ([[CCCertificate sharedManager] checkTrustedChallenge:challenge]) {
+    if ([[NCNetworking sharedInstance] checkTrustedChallengeWithChallenge:challenge directoryCertificate:[CCUtility getDirectoryCerificates]]) {
         completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
     } else {
         completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);

+ 0 - 1
iOSClient/Nextcloud-Bridging-Header.h

@@ -27,4 +27,3 @@
 #import "NCRichDocumentTemplate.h"
 #import "HCFeatures.h"
 #import "NCComments.h"
-#import "CCCertificate.h"

+ 0 - 47
iOSClient/Notification/CCNotification.storyboard

@@ -1,47 +0,0 @@
-//
-//  CCCertificate.h
-//  Nextcloud
-//
-//  Created by Marino Faggiana on 10/08/16.
-//  Copyright (c) 2017 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/Foundation.h>
-#import <UIKit/UIKit.h>
-
-@protocol CCCertificateDelegate <NSObject>
-
-@optional - (void)trustedCerticateAccepted;
-@optional - (void)trustedCerticateDenied;
-
-@end
-
-@interface CCCertificate : NSObject
-
-@property (weak) id<CCCertificateDelegate> delegate;
-
-+ (CCCertificate *)sharedManager;
-
-- (BOOL)checkTrustedChallenge:(NSURLAuthenticationChallenge *)challenge;
-- (BOOL)acceptCertificate;
-- (void)saveCertificate:(SecTrustRef) trust withName:(NSString *) certName;
-
-- (void)presentViewControllerCertificateWithAccount:(NSString *)account viewController:(UIViewController *)viewController delegate:(id)delegate;
-
-@end
-

+ 0 - 199
iOSClient/Security/CCCertificate.m

@@ -1,199 +0,0 @@
-//
-//  CCCertificate.m
-//  Nextcloud
-//
-//  Created by Marino Faggiana on 10/08/16.
-//  Copyright (c) 2017 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 "CCUtility.h"
-#import "CCCertificate.h"
-#import "NCBridgeSwift.h"
-#import "AppDelegate.h"
-#import <OpenSSL/OpenSSL.h>
-
-@implementation CCCertificate
-
-//Singleton
-+ (CCCertificate *)sharedManager {
-    static CCCertificate *CCCertificate = nil;
-    static dispatch_once_t onceToken;
-    dispatch_once(&onceToken, ^{
-        CCCertificate = [[self alloc] init];
-    });
-    return CCCertificate;
-}
-
-static SecCertificateRef SecTrustGetLeafCertificate(SecTrustRef trust)
-// Returns the leaf certificate from a SecTrust object (that is always the 
-// certificate at index 0).
-{
-    SecCertificateRef   result;
-    
-    assert(trust != NULL);
-    
-    if (SecTrustGetCertificateCount(trust) > 0) {
-        result = SecTrustGetCertificateAtIndex(trust, 0);
-        assert(result != NULL);
-    } else {
-        result = NULL;
-    }
-    return result;
-}
-
-- (BOOL)checkTrustedChallenge:(NSURLAuthenticationChallenge *)challenge
-{
-    BOOL trusted = NO;
-    SecTrustRef trust;
-    NSURLProtectionSpace *protectionSpace;
-    
-    protectionSpace = [challenge protectionSpace];
-    trust = [protectionSpace serverTrust];
-        
-    if(trust != nil) {
-        
-        [self saveCertificate:trust withName:@"tmp.der"];
-        
-        NSString *localCertificatesFolder = [CCUtility getDirectoryCerificates];
-        
-        NSArray *listCertificateLocation = [[NCManageDatabase sharedInstance] getCertificatesLocation:[CCUtility getDirectoryCerificates]];
-        
-        for (int i = 0 ; i < [listCertificateLocation count] ; i++) {
-         
-            NSString *currentLocalCertLocation = [listCertificateLocation objectAtIndex:i];
-            
-            NSFileManager *fileManager = [ NSFileManager defaultManager];
-            
-            if([fileManager contentsEqualAtPath:[NSString stringWithFormat:@"%@/%@",localCertificatesFolder,@"tmp.der"] andPath:[NSString stringWithFormat:@"%@",currentLocalCertLocation]]) {
-                
-                NSLog(@"[LOG] Is the same certificate!!!");
-                trusted = YES;
-            }
-        }
-        
-    } else
-        trusted = NO;
-    
-    return trusted;
-}
-
-- (void)saveCertificate:(SecTrustRef)trust withName:(NSString *)certName
-{
-    SecCertificateRef currentServerCert = SecTrustGetLeafCertificate(trust);
-    
-    CFDataRef data = SecCertificateCopyData(currentServerCert);
-    X509 *x509cert = NULL;
-    if (data) {
-        BIO *mem = BIO_new_mem_buf((void *)CFDataGetBytePtr(data), (int)CFDataGetLength(data));
-        x509cert = d2i_X509_bio(mem, NULL);
-        BIO_free(mem);
-        CFRelease(data);
-        
-        if (!x509cert) {
-            
-            NSLog(@"[LOG] OpenSSL couldn't parse X509 Certificate");
-            
-        } else {
-            
-            NSString *localCertificatesFolder = [CCUtility getDirectoryCerificates];
-            
-            certName = [NSString stringWithFormat:@"%@/%@",localCertificatesFolder,certName];
-            
-            if ([[NSFileManager defaultManager] fileExistsAtPath:certName]) {
-                NSError *error;
-                [[NSFileManager defaultManager] removeItemAtPath:certName error:&error];
-            }
-            
-            FILE *file;
-            file = fopen([certName UTF8String], "w");
-            if (file) {
-                PEM_write_X509(file, x509cert);
-            }
-            fclose(file);
-        }
-    
-    } else {
-        
-        NSLog(@"[LOG] Failed to retrieve DER data from Certificate Ref");
-    }
-    
-    //Free
-    X509_free(x509cert);
-}
-
-- (void)presentViewControllerCertificateWithAccount:(NSString *)account viewController:(UIViewController *)viewController delegate:(id)delegate
-{
-    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
-    _delegate = delegate;
-    
-    if (![viewController isKindOfClass:[UIViewController class]])
-        return;
-    
-    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
-    
-        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"_ssl_certificate_untrusted_", nil) message:NSLocalizedString(@"_connect_server_anyway_", nil)  preferredStyle:UIAlertControllerStyleAlert];
-    
-        [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_yes_", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
-                                                           
-            [[CCCertificate sharedManager] acceptCertificate];
-            if (account != nil) [CCUtility setCertificateError:account error:NO];
-            [appDelegate startTimerErrorNetworking];
-            
-            if([self.delegate respondsToSelector:@selector(trustedCerticateAccepted)])
-                [self.delegate trustedCerticateAccepted];
-        }]];
-    
-        [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_no_", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
-            
-            [appDelegate startTimerErrorNetworking];
-
-            if([self.delegate respondsToSelector:@selector(trustedCerticateDenied)])
-                [self.delegate trustedCerticateDenied];
-        }]];
-        
-        [viewController presentViewController:alertController animated:YES completion:^{
-            // Stop timer error network
-            [appDelegate.timerErrorNetworking invalidate];
-        }];
-    });
-}
-
-- (BOOL)acceptCertificate
-{
-    NSString *localCertificatesFolder = [CCUtility getDirectoryCerificates];
-    NSError *error;
-    NSFileManager *fm = [[NSFileManager alloc] init];
-    NSTimeInterval dateCertificate = [[NSDate date] timeIntervalSince1970];
-    NSString *currentCertLocation = [NSString stringWithFormat:@"%@/%f.der",localCertificatesFolder, dateCertificate];
-    
-    NSLog(@"[LOG] currentCertLocation: %@", currentCertLocation);
-    
-    if(![fm moveItemAtPath:[NSString stringWithFormat:@"%@/%@",localCertificatesFolder, @"tmp.der"] toPath:currentCertLocation error:&error]) {
-        
-        NSLog(@"[LOG] Error: %@", [error localizedDescription]);
-        return NO;
-        
-    } else {
-        
-        [[NCManageDatabase sharedInstance] addCertificates:[NSString stringWithFormat:@"%f.der", dateCertificate]];
-    }
-    
-    return YES;
-}
-
-@end

+ 3 - 4
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 --------------------------------------------------------------

+ 4 - 2
iOSClient/Share/NCSharePaging.swift

@@ -24,6 +24,7 @@
 
 import Foundation
 import Parchment
+import NCCommunication
 
 class NCSharePaging: UIViewController {
     
@@ -269,7 +270,8 @@ class NCShareHeaderView: UIView {
     @IBAction func touchUpInsideFavorite(_ sender: UIButton) {
         
         if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocId)) {
-            OCNetworking.sharedManager()?.settingFavorite(withAccount: metadata.account, fileName: metadata.fileName, favorite: !metadata.favorite, completion: { (account, message, errorCode) in
+            
+            NCCommunication.sharedInstance.setFavorite(urlString: appDelegate.activeUrl, fileName: metadata.fileName, favorite: !metadata.favorite, account: metadata.account) { (account, errorCode, errorDescription) in
                 if errorCode == 0 {
                     NCManageDatabase.sharedInstance.setMetadataFavorite(ocId: metadata.ocId, favorite: !metadata.favorite)
                     if !metadata.favorite {
@@ -280,7 +282,7 @@ class NCShareHeaderView: UIView {
                     self.appDelegate.activeMain?.reloadDatasource(self.appDelegate.activeMain?.serverUrl, ocId: nil, action: Int(k_action_NULL))
                     self.appDelegate.activeFavorites?.reloadDatasource(nil, action: Int(k_action_NULL))
                 }
-            })
+            }
         }
     }
 }

BIN
iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/pl.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/sl.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/sv.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/tr.lproj/Localizable.strings


+ 2 - 0
iOSClient/Utility/CCUtility.h

@@ -241,6 +241,8 @@
 
 + (void)selectFileNameFrom:(UITextField *)textField;
 
++ (NSString *)getTimeIntervalSince197;
+
 // ===== E2E Encrypted =====
 
 + (NSString *)generateRandomIdentifier;

+ 5 - 0
iOSClient/Utility/CCUtility.m

@@ -1361,6 +1361,11 @@
     textField.selectedTextRange = textRange;
 }
 
++ (NSString *)getTimeIntervalSince197
+{
+    return [NSString stringWithFormat:@"%f", [[NSDate date] timeIntervalSince1970]];
+}
+
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark ===== E2E Encrypted =====
 #pragma --------------------------------------------------------------------------------------------

+ 0 - 5
iOSClient/Viewer/NCViewerRichdocument.swift

@@ -180,11 +180,6 @@ class NCViewerRichdocument: WKWebView, WKNavigationDelegate, WKScriptMessageHand
             if message.body as? String == "paste" {
                 self.paste(self)
             }
-
-	    // Javascript cannot do this by itself, so help out.
-            if message.body as! String == "paste" {
-                self.paste(self)
-            }
         }
     }