Эх сурвалжийг харах

Dev improvements Files Extension Provider

Marino Faggiana 6 жил өмнө
parent
commit
d9900988dc

+ 9 - 13
Nextcloud.xcodeproj/project.pbxproj

@@ -208,7 +208,6 @@
 		F73D71641F2674A400E233EB /* NCText.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F73D71631F2674A400E233EB /* NCText.storyboard */; };
 		F73F537F1E929C8500F8678D /* CCMore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F73F537E1E929C8500F8678D /* CCMore.swift */; };
 		F74344171E1264EE001CC831 /* DocumentPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F74344161E1264EE001CC831 /* DocumentPickerViewController.swift */; };
-		F74344251E1264EE001CC831 /* FileProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F74344241E1264EE001CC831 /* FileProvider.swift */; };
 		F74344561E12784A001CC831 /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F70A63061D5B3467004E2AA5 /* libcrypto.a */; };
 		F74344591E12786C001CC831 /* libssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F70A63071D5B3467004E2AA5 /* libssl.a */; };
 		F74344631E127D79001CC831 /* CCBKPasscode.m in Sources */ = {isa = PBXBuildFile; fileRef = F7FE125D1BAC03FB0041924B /* CCBKPasscode.m */; };
@@ -232,6 +231,8 @@
 		F74E432720B5547700C2E54C /* NCNetworkingEndToEnd.m in Sources */ = {isa = PBXBuildFile; fileRef = F74E432520B5547700C2E54C /* NCNetworkingEndToEnd.m */; };
 		F74E432820B5547700C2E54C /* NCNetworkingEndToEnd.m in Sources */ = {isa = PBXBuildFile; fileRef = F74E432520B5547700C2E54C /* NCNetworkingEndToEnd.m */; };
 		F74E432920B5547700C2E54C /* NCNetworkingEndToEnd.m in Sources */ = {isa = PBXBuildFile; fileRef = F74E432520B5547700C2E54C /* NCNetworkingEndToEnd.m */; };
+		F74F9F5020BC3678009FB1AF /* FileProviderData.swift in Sources */ = {isa = PBXBuildFile; fileRef = F74F9F4F20BC3678009FB1AF /* FileProviderData.swift */; };
+		F74F9F5220BC3681009FB1AF /* FileProviderExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F74F9F5120BC3681009FB1AF /* FileProviderExtension.swift */; };
 		F750374D1DBFA91A008FB480 /* ALView+PureLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = F75037441DBFA91A008FB480 /* ALView+PureLayout.m */; };
 		F750374F1DBFA91A008FB480 /* NSArray+PureLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = F75037461DBFA91A008FB480 /* NSArray+PureLayout.m */; };
 		F75037511DBFA91A008FB480 /* NSLayoutConstraint+PureLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = F75037481DBFA91A008FB480 /* NSLayoutConstraint+PureLayout.m */; };
@@ -240,8 +241,6 @@
 		F75AC2431F1F62450073EC19 /* NCManageAutoUploadFileName.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75AC2421F1F62450073EC19 /* NCManageAutoUploadFileName.swift */; };
 		F75ADF451DC75FFE008A7347 /* CCLogin.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F75ADF441DC75FFE008A7347 /* CCLogin.storyboard */; };
 		F75AE3C71E9D12900088BB09 /* SwiftyAvatar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75AE3C61E9D12900088BB09 /* SwiftyAvatar.swift */; };
-		F75EAC4D20974B470071FF95 /* FileProviderEnumeratorWorkingSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75EAC4C20974B470071FF95 /* FileProviderEnumeratorWorkingSet.swift */; };
-		F75EAC4F20974B5E0071FF95 /* FileProviderEnumeratorFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75EAC4E20974B5E0071FF95 /* FileProviderEnumeratorFile.swift */; };
 		F75EDFBD1E8C112F00E6F369 /* libsqlite3.0.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = F75EDFBC1E8C112F00E6F369 /* libsqlite3.0.tbd */; };
 		F75EDFBF1E8C116D00E6F369 /* libstdc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = F75EDFBE1E8C116D00E6F369 /* libstdc++.tbd */; };
 		F762CAF71EACB66200B38484 /* XLFormBaseCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F762CAA41EACB66200B38484 /* XLFormBaseCell.m */; };
@@ -918,7 +917,6 @@
 		F73D71631F2674A400E233EB /* NCText.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = NCText.storyboard; sourceTree = "<group>"; };
 		F73F537E1E929C8500F8678D /* CCMore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CCMore.swift; sourceTree = "<group>"; };
 		F74344161E1264EE001CC831 /* DocumentPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentPickerViewController.swift; sourceTree = "<group>"; };
-		F74344241E1264EE001CC831 /* FileProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileProvider.swift; sourceTree = "<group>"; };
 		F74344901E128E8F001CC831 /* Picker.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = Picker.appex; sourceTree = BUILT_PRODUCTS_DIR; };
 		F74344911E128E96001CC831 /* PickerFileProvider.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = PickerFileProvider.appex; sourceTree = BUILT_PRODUCTS_DIR; };
 		F743B2C31C95BBE8006F5B4A /* CCShareInfoCMOC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCShareInfoCMOC.h; sourceTree = "<group>"; };
@@ -933,6 +931,8 @@
 		F74D3DBE1BAC1941000BAE4B /* OCNetworking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OCNetworking.m; sourceTree = "<group>"; };
 		F74E432420B5547700C2E54C /* NCNetworkingEndToEnd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NCNetworkingEndToEnd.h; sourceTree = "<group>"; };
 		F74E432520B5547700C2E54C /* NCNetworkingEndToEnd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NCNetworkingEndToEnd.m; sourceTree = "<group>"; };
+		F74F9F4F20BC3678009FB1AF /* FileProviderData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileProviderData.swift; sourceTree = "<group>"; };
+		F74F9F5120BC3681009FB1AF /* FileProviderExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileProviderExtension.swift; sourceTree = "<group>"; };
 		F75037431DBFA91A008FB480 /* ALView+PureLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ALView+PureLayout.h"; sourceTree = "<group>"; };
 		F75037441DBFA91A008FB480 /* ALView+PureLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ALView+PureLayout.m"; sourceTree = "<group>"; };
 		F75037451DBFA91A008FB480 /* NSArray+PureLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+PureLayout.h"; sourceTree = "<group>"; };
@@ -1039,8 +1039,6 @@
 		F75B923F1ECAE55F00199C96 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Intro.strings; sourceTree = "<group>"; };
 		F75B92401ECAE55F00199C96 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Error.strings; sourceTree = "<group>"; };
 		F75CDBF51DF063AD00116AD0 /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; name = .gitignore; path = ../.gitignore; sourceTree = "<group>"; };
-		F75EAC4C20974B470071FF95 /* FileProviderEnumeratorWorkingSet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileProviderEnumeratorWorkingSet.swift; sourceTree = "<group>"; };
-		F75EAC4E20974B5E0071FF95 /* FileProviderEnumeratorFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileProviderEnumeratorFile.swift; sourceTree = "<group>"; };
 		F75EDFBC1E8C112F00E6F369 /* libsqlite3.0.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.0.tbd; path = usr/lib/libsqlite3.0.tbd; sourceTree = SDKROOT; };
 		F75EDFBE1E8C116D00E6F369 /* libstdc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libstdc++.tbd"; path = "usr/lib/libstdc++.tbd"; sourceTree = SDKROOT; };
 		F762CAA31EACB66200B38484 /* XLFormBaseCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XLFormBaseCell.h; sourceTree = "<group>"; };
@@ -2162,12 +2160,11 @@
 		F74344211E1264EE001CC831 /* PickerFileProvider */ = {
 			isa = PBXGroup;
 			children = (
-				F7F54CAB1E5AFF1E00E19C62 /* PickerFileProvider-Bridging-Header.h */,
+				F74F9F5120BC3681009FB1AF /* FileProviderExtension.swift */,
+				F74F9F4F20BC3678009FB1AF /* FileProviderData.swift */,
 				F7496B7B208F548E004B299C /* FileProviderEnumerator.swift */,
-				F75EAC4C20974B470071FF95 /* FileProviderEnumeratorWorkingSet.swift */,
-				F75EAC4E20974B5E0071FF95 /* FileProviderEnumeratorFile.swift */,
 				F7496B7C208F548E004B299C /* FileProviderItem.swift */,
-				F74344241E1264EE001CC831 /* FileProvider.swift */,
+				F7F54CAB1E5AFF1E00E19C62 /* PickerFileProvider-Bridging-Header.h */,
 			);
 			path = PickerFileProvider;
 			sourceTree = "<group>";
@@ -3757,6 +3754,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				F7BB50D91F2238A300C47094 /* OCXMLParser.m in Sources */,
+				F74F9F5220BC3681009FB1AF /* FileProviderExtension.swift in Sources */,
 				F7BB50D11F22388900C47094 /* OCSharedDto.m in Sources */,
 				F7BB50CB1F22386900C47094 /* OCCommunication.m in Sources */,
 				F7BB50D31F22388E00C47094 /* OCUserProfile.m in Sources */,
@@ -3767,12 +3765,10 @@
 				F7BB50CC1F22387900C47094 /* OCExternalSites.m in Sources */,
 				F7BB50EA1F2238FB00C47094 /* UIScrollView+EmptyDataSet.m in Sources */,
 				F7F878B11FB9E3B900599E4F /* NCEndToEndMetadata.swift in Sources */,
-				F75EAC4D20974B470071FF95 /* FileProviderEnumeratorWorkingSet.swift in Sources */,
 				F7BB50F71F2239BF00C47094 /* BKPasscodeLockScreenManager.m in Sources */,
 				F7BB50DB1F2238A900C47094 /* OCXMLShareByLinkParser.m in Sources */,
 				F7BB50E21F2238D000C47094 /* AFURLRequestSerialization.m in Sources */,
 				F7BB50BC1F22375D00C47094 /* CCBKPasscode.m in Sources */,
-				F75EAC4F20974B5E0071FF95 /* FileProviderEnumeratorFile.swift in Sources */,
 				F7BB50D81F2238A000C47094 /* OCXMLListParser.m in Sources */,
 				F7BB50E41F2238D500C47094 /* AFURLSessionManager.m in Sources */,
 				F7BB50F91F2239C800C47094 /* BKShiftingView.m in Sources */,
@@ -3795,7 +3791,6 @@
 				F7BB50C01F22378B00C47094 /* CCError.m in Sources */,
 				F7BB50E01F2238CA00C47094 /* AFNetworkReachabilityManager.m in Sources */,
 				F7BB50F81F2239C400C47094 /* BKPasscodeViewController.m in Sources */,
-				F74344251E1264EE001CC831 /* FileProvider.swift in Sources */,
 				F7BB50BA1F22374A00C47094 /* CCNetworking.m in Sources */,
 				F7BB50DD1F2238B100C47094 /* NSString+Encode.m in Sources */,
 				F7BB50D51F22389600C47094 /* NSDate+RFC1123.m in Sources */,
@@ -3811,6 +3806,7 @@
 				F7BB50F41F2239B600C47094 /* BKPasscodeDummyViewController.m in Sources */,
 				F7BB50C41F22379800C47094 /* NSString+TruncateToWidth.m in Sources */,
 				F7BB50E31F2238D200C47094 /* AFURLResponseSerialization.m in Sources */,
+				F74F9F5020BC3678009FB1AF /* FileProviderData.swift in Sources */,
 				F782952F1F962EF900A572F5 /* NCEndToEndEncryption.m in Sources */,
 				F7BB50EB1F22391000C47094 /* MBProgressHUD.m in Sources */,
 				F7BB50D21F22388B00C47094 /* OCShareUser.m in Sources */,

+ 143 - 0
PickerFileProvider/FileProviderData.swift

@@ -0,0 +1,143 @@
+//
+//  FileProviderData.swift
+//  Files
+//
+//  Created by Marino Faggiana on 27/05/18.
+//  Copyright © 2018 TWS. All rights reserved.
+//
+//  Author Marino Faggiana <m.faggiana@twsweb.it>
+//
+//  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 FileProvider
+
+class FileProviderData: NSObject {
+    
+    var account = ""
+    var accountUser = ""
+    var accountUserID = ""
+    var accountPassword = ""
+    var accountUrl = ""
+    var homeServerUrl = ""
+    var directoryUser = ""
+    
+    // Directory
+    var groupURL: URL?
+    var fileProviderStorageURL: URL?
+    
+    //var listFavoriteIdentifierRank = [String:NSNumber]()
+    
+    func setupActiveAccount() -> Bool {
+        
+        groupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: NCBrandOptions.sharedInstance.capabilitiesGroups)
+        fileProviderStorageURL = groupURL!.appendingPathComponent(k_assetLocalIdentifierFileProviderStorage)
+        
+        // Create dir File Provider Storage
+        do {
+            try FileManager.default.createDirectory(atPath: fileProviderStorageURL!.path, withIntermediateDirectories: true, attributes: nil)
+        } catch let error as NSError {
+            NSLog("Unable to create directory \(error.debugDescription)")
+        }
+        
+        guard let activeAccount = NCManageDatabase.sharedInstance.getAccountActive() else {
+            return false
+        }
+        
+        account = activeAccount.account
+        accountUser = activeAccount.user
+        accountUserID = activeAccount.userID
+        accountPassword = activeAccount.password
+        accountUrl = activeAccount.url
+        homeServerUrl = CCUtility.getHomeServerUrlActiveUrl(activeAccount.url)
+        directoryUser = CCUtility.getDirectoryActiveUser(activeAccount.user, activeUrl: activeAccount.url)
+        
+        ocNetworking = OCnetworking.init(delegate: nil, metadataNet: nil, withUser: accountUser, withUserID: accountUserID, withPassword: accountPassword, withUrl: accountUrl)
+        
+        return true
+    }
+    
+    func getTableMetadataFromItemIdentifier(_ itemIdentifier: NSFileProviderItemIdentifier) -> tableMetadata? {
+        
+        let fileID = itemIdentifier.rawValue
+        return NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account = %@ AND fileID = %@", account, fileID))
+    }
+
+    func getItemIdentifier(metadata: tableMetadata) -> NSFileProviderItemIdentifier {
+        
+        return NSFileProviderItemIdentifier(metadata.fileID)
+    }
+    
+    func createFileIdentifierOnFileSystem(metadata: tableMetadata) {
+        
+        let itemIdentifier = getItemIdentifier(metadata: metadata)
+        let identifierPath = fileProviderStorageURL!.path + "/" + itemIdentifier.rawValue
+        let fileIdentifier = identifierPath + "/" + metadata.fileName
+        
+        do {
+            try FileManager.default.createDirectory(atPath: identifierPath, withIntermediateDirectories: true, attributes: nil)
+        } catch { }
+        
+        // If do not exists create file with size = 0
+        if FileManager.default.fileExists(atPath: fileIdentifier) == false {
+            FileManager.default.createFile(atPath: fileIdentifier, contents: nil, attributes: nil)
+        }
+    }
+    
+    func getParentItemIdentifier(metadata: tableMetadata) -> NSFileProviderItemIdentifier? {
+        
+        /* ONLY iOS 11*/
+        guard #available(iOS 11, *) else { return NSFileProviderItemIdentifier("") }
+        
+        if let directory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account = %@ AND directoryID = %@", account, metadata.directoryID))  {
+            if directory.serverUrl == homeServerUrl {
+                return NSFileProviderItemIdentifier(NSFileProviderItemIdentifier.rootContainer.rawValue)
+            } else {
+                // get the metadata.FileID of parent Directory
+                if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account = %@ AND fileID = %@", account, directory.fileID))  {
+                    let identifier = getItemIdentifier(metadata: metadata)
+                    return identifier
+                }
+            }
+        }
+        
+        return nil
+    }
+    
+    func getTableDirectoryFromParentItemIdentifier(_ parentItemIdentifier: NSFileProviderItemIdentifier) -> tableDirectory? {
+        
+        /* ONLY iOS 11*/
+        guard #available(iOS 11, *) else { return nil }
+        
+        var predicate: NSPredicate
+        
+        if parentItemIdentifier == .rootContainer {
+            
+            predicate = NSPredicate(format: "account = %@ AND serverUrl = %@", account, homeServerUrl)
+            
+        } else {
+            
+            guard let metadata = getTableMetadataFromItemIdentifier(parentItemIdentifier) else {
+                return nil
+            }
+            predicate = NSPredicate(format: "account = %@ AND fileID = %@", account, metadata.fileID)
+        }
+        
+        guard let directory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: predicate) else {
+            return nil
+        }
+        
+        return directory
+    }
+}

+ 109 - 69
PickerFileProvider/FileProviderEnumerator.swift

@@ -28,21 +28,23 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
     var enumeratedItemIdentifier: NSFileProviderItemIdentifier
     let recordForPage = 20
     var serverUrl: String?
+    var providerData: FileProviderData
     
-    init(enumeratedItemIdentifier: NSFileProviderItemIdentifier) {
+    init(enumeratedItemIdentifier: NSFileProviderItemIdentifier, providerData: FileProviderData) {
         
         self.enumeratedItemIdentifier = enumeratedItemIdentifier
+        self.providerData = providerData
         
         // Select ServerUrl
         if #available(iOSApplicationExtension 11.0, *) {
 
             if (enumeratedItemIdentifier == .rootContainer) {
-                serverUrl = homeServerUrl
+                serverUrl = providerData.homeServerUrl
             } else {
                 
-                let metadata = getTableMetadataFromItemIdentifier(enumeratedItemIdentifier)
+                let metadata = providerData.getTableMetadataFromItemIdentifier(enumeratedItemIdentifier)
                 if metadata != nil  {
-                    if let directorySource = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account = %@ AND directoryID = %@", account, metadata!.directoryID))  {
+                    if let directorySource = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account = %@ AND directoryID = %@", providerData.account, metadata!.directoryID))  {
                         serverUrl = directorySource.serverUrl + "/" + metadata!.fileName
                     }
                 }
@@ -61,87 +63,100 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
         var items: [NSFileProviderItemProtocol] = []
         var metadatas: [tableMetadata]?
 
-        // Check account
-        if setupActiveAccount() == false {
+        /* ONLY iOS 11*/
+        guard #available(iOS 11, *) else {
             observer.finishEnumerating(upTo: nil)
             return
         }
         
-        if #available(iOSApplicationExtension 11.0, *) {
-                        
-            guard let serverUrl = serverUrl else {
-                observer.finishEnumerating(upTo: nil)
-                return
-            }
+        if enumeratedItemIdentifier == .workingSet {
             
-            // Select items from database
-            if let directory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account = %@ AND serverUrl = %@", account, serverUrl))  {
-                metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account = %@ AND directoryID = %@", account, directory.directoryID), sorted: "fileName", ascending: true)
-            }
+            items = selectItemWorkingSet()
             
-            // Calculate current page
-            if (page != NSFileProviderPage.initialPageSortedByDate as NSFileProviderPage && page != NSFileProviderPage.initialPageSortedByName as NSFileProviderPage) {
+            observer.didEnumerate(items)
+            observer.finishEnumerating(upTo: nil)
+            return
+        }
+        
+        guard let serverUrl = serverUrl else {
+            observer.finishEnumerating(upTo: nil)
+            return
+        }
+            
+        // Select items from database
+        if let directory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account = %@ AND serverUrl = %@", providerData.account, serverUrl))  {
+            metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account = %@ AND directoryID = %@", providerData.account, directory.directoryID), sorted: "fileName", ascending: true)
+        }
+            
+        // Calculate current page
+        if (page != NSFileProviderPage.initialPageSortedByDate as NSFileProviderPage && page != NSFileProviderPage.initialPageSortedByName as NSFileProviderPage) {
                 
-                var numPage = Int(String(data: page.rawValue, encoding: .utf8)!)!
+            var numPage = Int(String(data: page.rawValue, encoding: .utf8)!)!
                 
-                if (metadatas != nil) {
-                    items = self.selectItems(numPage: numPage, account: account, serverUrl: serverUrl, metadatas: metadatas!)
-                    observer.didEnumerate(items)
-                }
-                if (items.count == self.recordForPage) {
-                    numPage += 1
-                    let providerPage = NSFileProviderPage("\(numPage)".data(using: .utf8)!)
-                    observer.finishEnumerating(upTo: providerPage)
-                } else {
-                    observer.finishEnumerating(upTo: nil)
-                }
-                return
+            if (metadatas != nil) {
+                items = self.selectItems(numPage: numPage, account: providerData.account, serverUrl: serverUrl, metadatas: metadatas!)
+                observer.didEnumerate(items)
+            }
+            if (items.count == self.recordForPage) {
+                numPage += 1
+                let providerPage = NSFileProviderPage("\(numPage)".data(using: .utf8)!)
+                observer.finishEnumerating(upTo: providerPage)
+            } else {
+                observer.finishEnumerating(upTo: nil)
             }
+            return
+        }
             
-            // Read Folder
-            ocNetworking?.readFolder(serverUrl, depth: "1", account: account, success: { (metadatas, metadataFolder, directoryID) in
+        // Read Folder
+        ocNetworking?.readFolder(serverUrl, depth: "1", account: providerData.account, success: { (metadatas, metadataFolder, directoryID) in
                 
-                if (metadatas != nil) {
-                    NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "account = %@ AND directoryID = %@ AND session = ''", account, directoryID!), clearDateReadDirectoryID: directoryID!)
-                    if let metadataDB = NCManageDatabase.sharedInstance.addMetadatas(metadatas as! [tableMetadata], serverUrl: serverUrl) {
-                        items = self.selectItems(numPage: 0, account: account, serverUrl: serverUrl, metadatas: metadataDB)
-                        if (items.count > 0) {
-                            observer.didEnumerate(items)
-                        }
+            if (metadatas != nil) {
+                NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "account = %@ AND directoryID = %@ AND session = ''", self.providerData.account, directoryID!), clearDateReadDirectoryID: directoryID!)
+                if let metadataDB = NCManageDatabase.sharedInstance.addMetadatas(metadatas as! [tableMetadata], serverUrl: serverUrl) {
+                    items = self.selectItems(numPage: 0, account: self.providerData.account, serverUrl: serverUrl, metadatas: metadataDB)
+                    if (items.count > 0) {
+                        observer.didEnumerate(items)
                     }
                 }
+            }
                 
-                if (items.count == self.recordForPage) {
-                    let providerPage = NSFileProviderPage("1".data(using: .utf8)!)
-                    observer.finishEnumerating(upTo: providerPage)
-                } else {
-                    observer.finishEnumerating(upTo: nil)
-                }
+            if (items.count == self.recordForPage) {
+                let providerPage = NSFileProviderPage("1".data(using: .utf8)!)
+                observer.finishEnumerating(upTo: providerPage)
+            } else {
+                observer.finishEnumerating(upTo: nil)
+            }
                 
-            }, failure: { (errorMessage, errorCode) in
+        }, failure: { (errorMessage, errorCode) in
                 
-                // select item from database
-                if (metadatas != nil) {
-                    items = self.selectItems(numPage: 0, account: account, serverUrl: serverUrl, metadatas: metadatas!)
-                    observer.didEnumerate(items)
-                }
-                if (items.count == self.recordForPage) {
-                    let providerPage = NSFileProviderPage("1".data(using: .utf8)!)
-                    observer.finishEnumerating(upTo: providerPage)
-                } else {
-                    observer.finishEnumerating(upTo: nil)
-                }
-            })
-            
-        } else {
-            // < iOS 11
-            observer.finishEnumerating(upTo: nil)
-        }
+            // select item from database
+            if (metadatas != nil) {
+                items = self.selectItems(numPage: 0, account: self.providerData.account, serverUrl: serverUrl, metadatas: metadatas!)
+                observer.didEnumerate(items)
+            }
+            if (items.count == self.recordForPage) {
+                let providerPage = NSFileProviderPage("1".data(using: .utf8)!)
+                observer.finishEnumerating(upTo: providerPage)
+            } else {
+                observer.finishEnumerating(upTo: nil)
+            }
+        })
     }
     
     func enumerateChanges(for observer: NSFileProviderChangeObserver, from anchor: NSFileProviderSyncAnchor) {
-        observer.didUpdate(listUpdateItems)
-        observer.finishEnumeratingChanges(upTo: anchor, moreComing: false)
+        
+        guard #available(iOS 11, *) else { return }
+    
+        // Report the trashed items since last signal
+        //
+        observer.didDeleteItems(withIdentifiers: fileProviderSignalDeleteItemIdentifier)
+        
+        // Report the updated items since last signal
+        //
+        observer.didUpdate(fileProviderSignalUpdateItem)
+        
+        let data = "\(currentAnchor)".data(using: .utf8)
+        observer.finishEnumeratingChanges(upTo: NSFileProviderSyncAnchor(data!), moreComing: false)        
     }
     
     func currentSyncAnchor(completionHandler: @escaping (NSFileProviderSyncAnchor?) -> Void) {
@@ -171,12 +186,12 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
             if (counter >= start && counter <= stop) {
                 
                 if metadata.directory == false {
-                    createFileIdentifierOnFileSystem(metadata: metadata)
+                    providerData.createFileIdentifierOnFileSystem(metadata: metadata)
                 }
 
-                let parentItemIdentifier = getParentItemIdentifier(metadata: metadata)
+                let parentItemIdentifier = providerData.getParentItemIdentifier(metadata: metadata)
                 if parentItemIdentifier != nil {
-                    let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier!)
+                    let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier!, providerData: providerData)
                     items.append(item)
                 }
             }
@@ -184,4 +199,29 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
         
         return items
     }
+    
+    func selectItemWorkingSet() -> [NSFileProviderItemProtocol] {
+        
+        var items: [NSFileProviderItemProtocol] = []
+
+        // Tag
+        let tags = NCManageDatabase.sharedInstance.getTags(predicate: NSPredicate(format: "account = %@", providerData.account))
+        for tag in tags {
+            
+            if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account = %@ AND fileID = %@", providerData.account, tag.fileID))  {
+                
+                if metadata.directory == false {
+                    providerData.createFileIdentifierOnFileSystem(metadata: metadata)
+                }
+                
+                let parentItemIdentifier = providerData.getParentItemIdentifier(metadata: metadata)
+                if parentItemIdentifier != nil {
+                    let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier!, providerData: providerData)
+                    items.append(item)
+                }
+            }
+        }
+        return items
+    }
+    
 }

+ 0 - 71
PickerFileProvider/FileProviderEnumeratorFile.swift

@@ -1,71 +0,0 @@
-//
-//  FileProviderEnumeratorFile.swift
-//  PickerFileProvider
-//
-//  Created by Marino Faggiana on 30/04/18.
-//  Copyright © 2018 TWS. All rights reserved.
-//
-//  Author Marino Faggiana <m.faggiana@twsweb.it>
-//
-//  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 FileProvider
-
-class FileProviderEnumeratorFile: NSObject, NSFileProviderEnumerator {
-    
-    var enumeratedItemIdentifier: NSFileProviderItemIdentifier
-    
-    init(enumeratedItemIdentifier: NSFileProviderItemIdentifier) {
-        self.enumeratedItemIdentifier = enumeratedItemIdentifier
-        super.init()
-    }
-    
-    func invalidate() {
-    }
-    
-    func enumerateItems(for observer: NSFileProviderEnumerationObserver, startingAt page: NSFileProviderPage) {
-        
-        var items: [NSFileProviderItemProtocol] = []
-        
-        guard let metadata = getTableMetadataFromItemIdentifier(enumeratedItemIdentifier) else {
-            observer.finishEnumerating(upTo: nil)
-            return
-        }
-        
-        if metadata.directory == false {
-            createFileIdentifierOnFileSystem(metadata: metadata)
-        }
-        
-        let parentItemIdentifier = getParentItemIdentifier(metadata: metadata)
-        if parentItemIdentifier != nil {
-            let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier!)
-            items.append(item)
-        }
-        
-        observer.didEnumerate(items)
-        observer.finishEnumerating(upTo: nil)
-    }
-    
-    func enumerateChanges(for observer: NSFileProviderChangeObserver, from anchor: NSFileProviderSyncAnchor) {
-        observer.didUpdate(listUpdateItems)
-        observer.finishEnumeratingChanges(upTo: anchor, moreComing: false)
-    }
-    
-    func currentSyncAnchor(completionHandler: @escaping (NSFileProviderSyncAnchor?) -> Void) {
-        let data = "\(currentAnchor)".data(using: .utf8)
-        completionHandler(NSFileProviderSyncAnchor(data!))
-    }
-}
-

+ 0 - 95
PickerFileProvider/FileProviderEnumeratorWorkingSet.swift

@@ -1,95 +0,0 @@
-//
-//  FileProviderEnumeratorWorkingSet.swift
-//  PickerFileProvider
-//
-//  Created by Marino Faggiana on 30/04/18.
-//  Copyright © 2018 TWS. All rights reserved.
-//
-//  Author Marino Faggiana <m.faggiana@twsweb.it>
-//
-//  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 FileProvider
-
-class FileProviderEnumeratorWorkingSet: NSObject, NSFileProviderEnumerator {
-    
-    var enumeratedItemIdentifier: NSFileProviderItemIdentifier
-    
-    init(enumeratedItemIdentifier: NSFileProviderItemIdentifier) {
-        self.enumeratedItemIdentifier = enumeratedItemIdentifier
-        super.init()
-    }
-    
-    func invalidate() {
-    }
-    
-    func enumerateItems(for observer: NSFileProviderEnumerationObserver, startingAt page: NSFileProviderPage) {
-        
-        var items: [NSFileProviderItemProtocol] = []
-        
-        // Tag
-        let tags = NCManageDatabase.sharedInstance.getTags(predicate: NSPredicate(format: "account = %@", account))
-        for tag in tags {
-            
-            if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account = %@ AND fileID = %@", account, tag.fileID))  {
-                
-                if metadata.directory == false {
-                    createFileIdentifierOnFileSystem(metadata: metadata)
-                }
-
-                let parentItemIdentifier = getParentItemIdentifier(metadata: metadata)
-                if parentItemIdentifier != nil {
-                    let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier!)
-                    items.append(item)
-                }
-            }
-        }
-        
-        // Favorite Directory
-        /*
-        listFavoriteIdentifierRank = NCManageDatabase.sharedInstance.getTableMetadatasDirectoryFavoriteIdentifierRank()
-        for (identifier, _) in listFavoriteIdentifierRank {
-            
-            guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account = %@ AND fileID = %@", account, identifier)) else {
-                continue
-            }
-            guard let serverUrl = NCManageDatabase.sharedInstance.getServerUrl(metadata.directoryID) else {
-                continue
-            }
-            // Create FS
-            createFileIdentifier(itemIdentifier: metadata.fileID, fileName: metadata.fileNameView)
-            let item = FileProviderItem(metadata: metadata, serverUrl: serverUrl)
-            items.append(item)
-        }
-        */
-        
-        observer.didEnumerate(items)
-        observer.finishEnumerating(upTo: nil)
-    }
-    
-    func enumerateChanges(for observer: NSFileProviderChangeObserver, from anchor: NSFileProviderSyncAnchor) {
-        
-        /* ONLY iOS 11*/
-        guard #available(iOS 11, *) else { return }
-        
-        observer.didUpdate(listUpdateItems)
-        observer.finishEnumeratingChanges(upTo: anchor, moreComing: false)
-    }
-    
-    func currentSyncAnchor(completionHandler: @escaping (NSFileProviderSyncAnchor?) -> Void) {
-        let data = "\(currentAnchor)".data(using: .utf8)
-        completionHandler(NSFileProviderSyncAnchor(data!))
-    }
-}

+ 131 - 227
PickerFileProvider/FileProvider.swift → PickerFileProvider/FileProviderExtension.swift

@@ -22,36 +22,17 @@
 //
 
 import FileProvider
-import UIKit
-import MobileCoreServices
-
-var ocNetworking: OCnetworking?
-var account = ""
-var accountUser = ""
-var accountUserID = ""
-var accountPassword = ""
-var accountUrl = ""
-var homeServerUrl = ""
-var directoryUser = ""
-
-// Directory
-var groupURL: URL?
-var fileProviderStorageURL: URL?
-
-// List
-var listUpdateItems = [NSFileProviderItem]()
-var listFavoriteIdentifierRank = [String:NSNumber]()
-var fileNamePathImport = [String]()
-
-// Anchor for enumerator
-var currentAnchor: UInt64 = 0
-
-// Metadata Temp for Import
-let FILEID_IMPORT_METADATA_TEMP = k_uploadSessionID + "FILE_PROVIDER_EXTENSION"
 
 // Timer for Upload (queue)
 var timerUpload: Timer?
 
+// Item for signalEnumerator
+var fileProviderSignalDeleteItemIdentifier = [NSFileProviderItemIdentifier]()
+var fileProviderSignalUpdateItem = [FileProviderItem]()
+
+var currentAnchor: UInt64 = 0
+var ocNetworking: OCnetworking?
+var fileNamePathImport = [String]()
 
 /* -----------------------------------------------------------------------------------------------------------------------------------------------
                                                             STRUCT item
@@ -78,21 +59,25 @@ var timerUpload: Timer?
  
    -------------------------------------------------------------------------------------------------------------------------------------------- */
 
-
-
-class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
+class FileProviderExtension: NSFileProviderExtension, CCNetworkingDelegate {
     
     var fileManager = FileManager()
+    var providerData = FileProviderData()
 
+    // Metadata Temp for Import
+    let FILEID_IMPORT_METADATA_TEMP = k_uploadSessionID + "FILE_PROVIDER_EXTENSION"
+    
     override init() {
         
         super.init()
         
+        _ = providerData.setupActiveAccount()
+        
         verifyUploadQueueInLock()
         
         if #available(iOSApplicationExtension 11.0, *) {
             
-            listFavoriteIdentifierRank = NCManageDatabase.sharedInstance.getTableMetadatasDirectoryFavoriteIdentifierRank()
+            //providerData.listFavoriteIdentifierRank = NCManageDatabase.sharedInstance.getTableMetadatasDirectoryFavoriteIdentifierRank()
             
             // Timer for upload
             if timerUpload == nil {
@@ -125,16 +110,16 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
         guard #available(iOS 11, *) else { throw NSError(domain: NSCocoaErrorDomain, code: NSFileNoSuchFileError, userInfo:[:]) }
         
         // Check account
-        if setupActiveAccount() == false {
+        if providerData.setupActiveAccount() == false {
             throw  NSError(domain: NSFileProviderErrorDomain, code: NSFileProviderError.notAuthenticated.rawValue, userInfo:[:])
         }
         
         var maybeEnumerator: NSFileProviderEnumerator? = nil
 
         if (containerItemIdentifier == NSFileProviderItemIdentifier.rootContainer) {
-            maybeEnumerator = FileProviderEnumerator(enumeratedItemIdentifier: containerItemIdentifier)
+            maybeEnumerator = FileProviderEnumerator(enumeratedItemIdentifier: containerItemIdentifier, providerData: providerData)
         } else if (containerItemIdentifier == NSFileProviderItemIdentifier.workingSet) {
-            maybeEnumerator = FileProviderEnumeratorWorkingSet(enumeratedItemIdentifier: containerItemIdentifier)
+            maybeEnumerator = FileProviderEnumerator(enumeratedItemIdentifier: containerItemIdentifier, providerData: providerData)
         } else {
             // determine if the item is a directory or a file
             // - for a directory, instantiate an enumerator of its subitems
@@ -142,9 +127,9 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
             let item = try self.item(for: containerItemIdentifier)
             
             if item.typeIdentifier == kUTTypeFolder as String {
-                maybeEnumerator = FileProviderEnumerator(enumeratedItemIdentifier: containerItemIdentifier)
+                maybeEnumerator = FileProviderEnumerator(enumeratedItemIdentifier: containerItemIdentifier, providerData: providerData)
             } else {
-                maybeEnumerator = FileProviderEnumeratorFile(enumeratedItemIdentifier: containerItemIdentifier)
+                maybeEnumerator = FileProviderEnumerator(enumeratedItemIdentifier: containerItemIdentifier, providerData: providerData)
             }
         }
         
@@ -155,27 +140,39 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
         return enumerator
     }
     
+    // Convinent method to signal the enumeration for containers.
+    //
+    func signalEnumerator(for containerItemIdentifiers: [NSFileProviderItemIdentifier]) {
+        
+        /* ONLY iOS 11*/
+        guard #available(iOS 11, *) else { return }
+        
+        currentAnchor += 1
+
+        for containerItemIdentifier in containerItemIdentifiers {
+            
+            NSFileProviderManager.default.signalEnumerator(for: containerItemIdentifier) { error in
+                if let error = error {
+                    print("SignalEnumerator for \(containerItemIdentifier) returned error: \(error)")
+                }
+            }
+        }
+    }
+    
     // MARK: - Item
 
     override func item(for identifier: NSFileProviderItemIdentifier) throws -> NSFileProviderItem {
         
         /* ONLY iOS 11*/
         guard #available(iOS 11, *) else { throw NSError(domain: NSCocoaErrorDomain, code: NSFileNoSuchFileError, userInfo:[:]) }
-
-        // Looking up the matched item; crash if nothing matched.
-        
-        // Check account
-        if setupActiveAccount() == false {
-            assert(false, "not account available return nil!")
-        }
         
         if identifier == .rootContainer {
             
-            if let directory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account = %@ AND serverUrl = %@", account, homeServerUrl)) {
+            if let directory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account = %@ AND serverUrl = %@", providerData.account, providerData.homeServerUrl)) {
                     
                 let metadata = tableMetadata()
                     
-                metadata.account = account
+                metadata.account = providerData.account
                 metadata.directory = true
                 metadata.directoryID = directory.directoryID
                 metadata.fileID = NSFileProviderItemIdentifier.rootContainer.rawValue
@@ -183,25 +180,18 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
                 metadata.fileNameView = NCBrandOptions.sharedInstance.brand
                 metadata.typeFile = k_metadataTypeFile_directory
                     
-                return FileProviderItem(metadata: metadata, parentItemIdentifier: NSFileProviderItemIdentifier(NSFileProviderItemIdentifier.rootContainer.rawValue))
-                
-            } else {
-                assert(false, "directory not found, item with \(identifier) return nil!")
+                return FileProviderItem(metadata: metadata, parentItemIdentifier: NSFileProviderItemIdentifier(NSFileProviderItemIdentifier.rootContainer.rawValue), providerData: providerData)
             }
             
         } else {
             
-            let metadata = getTableMetadataFromItemIdentifier(identifier)
+            let metadata = providerData.getTableMetadataFromItemIdentifier(identifier)
             if  metadata != nil {
-                let parentItemIdentifier = getParentItemIdentifier(metadata: metadata!)
+                let parentItemIdentifier = providerData.getParentItemIdentifier(metadata: metadata!)
                 if parentItemIdentifier != nil {
-                    let item = FileProviderItem(metadata: metadata!, parentItemIdentifier: parentItemIdentifier!)
+                    let item = FileProviderItem(metadata: metadata!, parentItemIdentifier: parentItemIdentifier!, providerData: providerData)
                     return item
-                } else {
-                    assert(false, "parentItemIdentifier not found, item with \(identifier) return nil!")
                 }
-            } else {
-                assert(false, "metadata not found, item with \(identifier) return nil!")
             }
         }
         
@@ -292,12 +282,12 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
             var localEtagFPE = ""
             
             // Check account
-            if setupActiveAccount() == false {
+            if providerData.setupActiveAccount() == false {
                 completionHandler(NSFileProviderError(.notAuthenticated))
                 return
             }
             
-            guard let metadata = getTableMetadataFromItemIdentifier(identifier) else {
+            guard let metadata = providerData.getTableMetadataFromItemIdentifier(identifier) else {
                 completionHandler(NSFileProviderError(.noSuchItem))
                 return
             }
@@ -308,7 +298,7 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
                 return
             }
             
-            let tableLocalFile = NCManageDatabase.sharedInstance.getTableLocalFile(predicate: NSPredicate(format: "account = %@ AND fileID = %@", account, metadata.fileID))
+            let tableLocalFile = NCManageDatabase.sharedInstance.getTableLocalFile(predicate: NSPredicate(format: "account = %@ AND fileID = %@", providerData.account, metadata.fileID))
             if tableLocalFile != nil {
                 localEtag = tableLocalFile!.etag
                 localEtagFPE = tableLocalFile!.etagFPE
@@ -318,7 +308,7 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
                 
                 // Verify last version on "Local Table"
                 if localEtag != localEtagFPE {
-                    if self.copyFile(directoryUser+"/"+metadata.fileID, toPath: url.path) == nil {
+                    if self.copyFile(providerData.directoryUser+"/"+metadata.fileID, toPath: url.path) == nil {
                         NCManageDatabase.sharedInstance.setLocalFile(fileID: metadata.fileID, date: nil, exifDate: nil, exifLatitude: nil, exifLongitude: nil, fileName: nil, etag: nil, etagFPE: localEtag)
                     }
                 }
@@ -342,13 +332,13 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
             }
             
             // delete prev file + ico on Directory User
-            _ = self.deleteFile("\(directoryUser)/\(metadata.fileID)")
-            _ = self.deleteFile("\(directoryUser)/\(metadata.fileID).ico")
+            _ = self.deleteFile("\(providerData.directoryUser)/\(metadata.fileID)")
+            _ = self.deleteFile("\(providerData.directoryUser)/\(metadata.fileID).ico")
 
-            let task = ocNetworking?.downloadFileNameServerUrl("\(serverUrl)/\(metadata.fileName)", fileNameLocalPath: "\(directoryUser)/\(metadata.fileID)", communication: CCNetworking.shared().sharedOCCommunicationExtensionDownload(metadata.fileName), success: { (lenght, etag, date) in
+            let task = ocNetworking?.downloadFileNameServerUrl("\(serverUrl)/\(metadata.fileName)", fileNameLocalPath: "\(providerData.directoryUser)/\(metadata.fileID)", communication: CCNetworking.shared().sharedOCCommunicationExtensionDownload(metadata.fileName), success: { (lenght, etag, date) in
                 
                 // copy download file to url
-                _ = self.copyFile("\(directoryUser)/\(metadata.fileID)", toPath: url.path)
+                _ = self.copyFile("\(self.providerData.directoryUser)/\(metadata.fileID)", toPath: url.path)
             
                 // update DB Local
                 metadata.date = date! as NSDate
@@ -396,7 +386,7 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
             assert(pathComponents.count > 2)
             let identifier = NSFileProviderItemIdentifier(pathComponents[pathComponents.count - 2])
             
-            guard let metadata = getTableMetadataFromItemIdentifier(identifier) else {
+            guard let metadata = providerData.getTableMetadataFromItemIdentifier(identifier) else {
                 return
             }
             
@@ -404,7 +394,7 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
                 return
             }
             
-            metadataNet.account = account
+            metadataNet.account = providerData.account
             metadataNet.assetLocalIdentifier = FILEID_IMPORT_METADATA_TEMP + metadata.directoryID + fileName
             metadataNet.fileName = fileName
             metadataNet.path = url.path
@@ -516,26 +506,26 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
         var counterProgress: Int64 = 0
         
         // Check account
-        if setupActiveAccount() == false {
+        if providerData.setupActiveAccount() == false {
             completionHandler(NSFileProviderError(.notAuthenticated))
             return Progress(totalUnitCount:0)
         }
         
         for itemIdentifier in itemIdentifiers {
             
-            let metadata = getTableMetadataFromItemIdentifier(itemIdentifier)
+            let metadata = providerData.getTableMetadataFromItemIdentifier(itemIdentifier)
             if metadata != nil {
                     
                 if (metadata!.typeFile == k_metadataTypeFile_image || metadata!.typeFile == k_metadataTypeFile_video) {
                         
                     let serverUrl = NCManageDatabase.sharedInstance.getServerUrl(metadata!.directoryID)
-                    let fileName = CCUtility.returnFileNamePath(fromFileName: metadata!.fileName, serverUrl: serverUrl, activeUrl: accountUrl)
+                    let fileName = CCUtility.returnFileNamePath(fromFileName: metadata!.fileName, serverUrl: serverUrl, activeUrl: providerData.accountUrl)
                     let fileNameLocal = metadata!.fileID
 
                     ocNetworking?.downloadThumbnail(withDimOfThumbnail: "m", fileName: fileName, fileNameLocal: fileNameLocal, success: {
 
                         do {
-                            let url = URL.init(fileURLWithPath: directoryUser+"/"+metadata!.fileID+".ico")
+                            let url = URL.init(fileURLWithPath: self.providerData.directoryUser+"/"+metadata!.fileID+".ico")
                             let data = try Data.init(contentsOf: url)
                             perThumbnailCompletionHandler(itemIdentifier, data, nil)
                         } catch let error {
@@ -584,23 +574,23 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
         guard #available(iOS 11, *) else { return }
         
         // Check account
-        if setupActiveAccount() == false {
+        if providerData.setupActiveAccount() == false {
             completionHandler(nil, NSFileProviderError(.notAuthenticated))
             return
         }
         
-        guard let tableDirectory = getTableDirectoryFromParentItemIdentifier(parentItemIdentifier) else {
+        guard let tableDirectory = providerData.getTableDirectoryFromParentItemIdentifier(parentItemIdentifier) else {
             completionHandler(nil, NSFileProviderError(.noSuchItem))
             return
         }
         
         let serverUrl = tableDirectory.serverUrl
         
-        ocNetworking?.createFolder(directoryName, serverUrl: serverUrl, account: account, success: { (fileID, date) in
+        ocNetworking?.createFolder(directoryName, serverUrl: serverUrl, account: providerData.account, success: { (fileID, date) in
     
             let metadata = tableMetadata()
                 
-            metadata.account = account
+            metadata.account = self.providerData.account
             metadata.directory = true
             metadata.directoryID = NCManageDatabase.sharedInstance.getDirectoryID(serverUrl)!
             metadata.fileID = fileID!
@@ -620,9 +610,9 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
                 return
             }
             
-            let parentItemIdentifier = getParentItemIdentifier(metadata: metadataDB)
+            let parentItemIdentifier = self.providerData.getParentItemIdentifier(metadata: metadataDB)
             if parentItemIdentifier != nil {
-                let item = FileProviderItem(metadata: metadataDB, parentItemIdentifier: parentItemIdentifier!)
+                let item = FileProviderItem(metadata: metadataDB, parentItemIdentifier: parentItemIdentifier!, providerData: self.providerData)
                 completionHandler(item, nil)
             } else {
                 completionHandler(nil, NSFileProviderError(.noSuchItem))
@@ -639,14 +629,14 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
         guard #available(iOS 11, *) else { return }
         
         // Check account
-        if setupActiveAccount() == false {
+        if providerData.setupActiveAccount() == false {
             completionHandler(NSFileProviderError(.notAuthenticated))
             return
         }
         
         DispatchQueue.main.async {
             
-            guard let metadata = getTableMetadataFromItemIdentifier(itemIdentifier) else {
+            guard let metadata = self.providerData.getTableMetadataFromItemIdentifier(itemIdentifier) else {
                 completionHandler(nil)
                 return
             }
@@ -658,7 +648,7 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
             
             ocNetworking?.deleteFileOrFolder(metadata.fileName, serverUrl: serverUrl, success: {
                 
-                let fileNamePath = directoryUser + "/" + metadata.fileID
+                let fileNamePath = self.providerData.directoryUser + "/" + metadata.fileID
                 do {
                     try self.fileManager.removeItem(atPath: fileNamePath)
                 } catch let error {
@@ -670,7 +660,7 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
                     print("error: \(error)")
                 }
                 do {
-                    try self.fileManager.removeItem(atPath: fileProviderStorageURL!.path + "/" + itemIdentifier.rawValue)
+                    try self.fileManager.removeItem(atPath: self.providerData.fileProviderStorageURL!.path + "/" + itemIdentifier.rawValue)
                 } catch let error {
                     print("error: \(error)")
                 }
@@ -702,7 +692,7 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
         guard #available(iOS 11, *) else { return }
         
         // Check account
-        if setupActiveAccount() == false {
+        if providerData.setupActiveAccount() == false {
             completionHandler(nil, NSFileProviderError(.notAuthenticated))
             return
         }
@@ -712,7 +702,7 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
             return
         }
         
-        guard let metadataFrom = getTableMetadataFromItemIdentifier(itemIdentifier) else {
+        guard let metadataFrom = providerData.getTableMetadataFromItemIdentifier(itemIdentifier) else {
             completionHandler(nil, NSFileProviderError(.noSuchItem))
             return
         }
@@ -726,7 +716,7 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
         
         let fileNameFrom = serverUrlFrom + "/" + itemFrom.filename
 
-        guard let tableDirectoryTo = getTableDirectoryFromParentItemIdentifier(parentItemIdentifier) else {
+        guard let tableDirectoryTo = providerData.getTableDirectoryFromParentItemIdentifier(parentItemIdentifier) else {
             completionHandler(nil, NSFileProviderError(.noSuchItem))
             return
         }
@@ -746,14 +736,14 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
                 NCManageDatabase.sharedInstance.moveMetadata(fileName: metadataFrom.fileName, directoryID: metadataFrom.directoryID, directoryIDTo: directoryIDTo)
             }
             
-            guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account = %@ AND fileID = %@", account, fileIDFrom)) else {
+            guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account = %@ AND fileID = %@", self.providerData.account, fileIDFrom)) else {
                 completionHandler(nil, NSFileProviderError(.noSuchItem))
                 return
             }
             
-            let parentItemIdentifier = getParentItemIdentifier(metadata: metadata)
+            let parentItemIdentifier = self.providerData.getParentItemIdentifier(metadata: metadata)
             if parentItemIdentifier != nil {
-                let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier!)
+                let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier!, providerData: self.providerData)
                 completionHandler(item, nil)
             } else {
                 completionHandler(nil, NSFileProviderError(.noSuchItem))
@@ -770,12 +760,12 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
         guard #available(iOS 11, *) else { return }
         
         // Check account
-        if setupActiveAccount() == false {
+        if providerData.setupActiveAccount() == false {
             completionHandler(nil, NSFileProviderError(.notAuthenticated))
             return
         }
         
-        guard let metadata = getTableMetadataFromItemIdentifier(itemIdentifier) else {
+        guard let metadata = providerData.getTableMetadataFromItemIdentifier(itemIdentifier) else {
             completionHandler(nil, NSFileProviderError(.noSuchItem))
             return
         }
@@ -808,16 +798,16 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
 
             } else {
                 
-                let itemIdentifier = getItemIdentifier(metadata: metadata)
+                let itemIdentifier = self.providerData.getItemIdentifier(metadata: metadata)
                 
-                _ = self.moveFile(fileProviderStorageURL!.path + "/" + itemIdentifier.rawValue + "/" + fileNameFrom, toPath: fileProviderStorageURL!.path + "/" + itemIdentifier.rawValue + "/" + itemName)
+                _ = self.moveFile(self.providerData.fileProviderStorageURL!.path + "/" + itemIdentifier.rawValue + "/" + fileNameFrom, toPath: self.providerData.fileProviderStorageURL!.path + "/" + itemIdentifier.rawValue + "/" + itemName)
                 
                 NCManageDatabase.sharedInstance.setLocalFile(fileID: metadata.fileID, date: nil, exifDate: nil, exifLatitude: nil, exifLongitude: nil, fileName: itemName, etag: nil, etagFPE: nil)
             }
                         
-            let parentItemIdentifier = getParentItemIdentifier(metadata: metadata)
+            let parentItemIdentifier = self.providerData.getParentItemIdentifier(metadata: metadata)
             if parentItemIdentifier != nil {
-                let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier!)
+                let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier!, providerData: self.providerData)
                 completionHandler(item, nil)
             } else {
                 completionHandler(nil, NSFileProviderError(.noSuchItem))
@@ -894,7 +884,7 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
         /* ONLY iOS 11*/
         guard #available(iOS 11, *) else { return }
         
-        guard let metadata = getTableMetadataFromItemIdentifier(itemIdentifier) else {
+        guard let metadata = providerData.getTableMetadataFromItemIdentifier(itemIdentifier) else {
             completionHandler(nil, NSFileProviderError(.noSuchItem))
             return
         }
@@ -902,17 +892,20 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
         // Add, Remove (nil)
         NCManageDatabase.sharedInstance.addTag(metadata.fileID, tagIOS: tagData)
         
-        let parentItemIdentifier = getParentItemIdentifier(metadata: metadata)
+        let parentItemIdentifier = providerData.getParentItemIdentifier(metadata: metadata)
         if parentItemIdentifier != nil {
-            let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier!)
+            
+            let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier!, providerData: providerData)
+            
+            fileProviderSignalUpdateItem.removeAll()
+            fileProviderSignalUpdateItem.append(item)
+            signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
+            
             completionHandler(item, nil)
+        
         } else {
             completionHandler(nil, NSFileProviderError(.noSuchItem))
         }
-        
-        NSFileProviderManager.default.signalEnumerator(for: .workingSet, completionHandler: { (error) in
-            print("send signal workingSet")
-        })
     }
     
     /*
@@ -939,7 +932,7 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
         
         DispatchQueue.main.async {
             
-            guard let tableDirectory = getTableDirectoryFromParentItemIdentifier(parentItemIdentifier) else {
+            guard let tableDirectory = self.providerData.getTableDirectoryFromParentItemIdentifier(parentItemIdentifier) else {
                 completionHandler(nil, NSFileProviderError(.noSuchItem))
                 return
             }
@@ -953,7 +946,7 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
             }
             
             let fileName = self.createFileName(fileURL.lastPathComponent, directoryID: tableDirectory.directoryID, serverUrl: serverUrl)
-            let fileNamePathDirectory = fileProviderStorageURL!.path + "/" + FILEID_IMPORT_METADATA_TEMP + tableDirectory.directoryID + fileName
+            let fileNamePathDirectory = self.providerData.fileProviderStorageURL!.path + "/" + self.FILEID_IMPORT_METADATA_TEMP + tableDirectory.directoryID + fileName
             
             do {
                 try FileManager.default.createDirectory(atPath: fileNamePathDirectory, withIntermediateDirectories: true, attributes: nil)
@@ -982,12 +975,12 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
             // ---------------------------------------------------------------------------------
             
             // Metadata TEMP
-            metadata.account = account
+            metadata.account = self.providerData.account
             metadata.date = NSDate()
             metadata.directory = false
             metadata.directoryID = tableDirectory.directoryID
             metadata.etag = ""
-            metadata.fileID = FILEID_IMPORT_METADATA_TEMP + tableDirectory.directoryID + fileName
+            metadata.fileID = self.FILEID_IMPORT_METADATA_TEMP + tableDirectory.directoryID + fileName
             metadata.size = size
             metadata.status = Double(k_metadataStatusHide)
             metadata.fileName = fileURL.lastPathComponent
@@ -998,8 +991,8 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
                 
                 let metadataNet = CCMetadataNet()
                 
-                metadataNet.account = account
-                metadataNet.assetLocalIdentifier = FILEID_IMPORT_METADATA_TEMP + tableDirectory.directoryID + fileName
+                metadataNet.account = self.providerData.account
+                metadataNet.assetLocalIdentifier = self.FILEID_IMPORT_METADATA_TEMP + tableDirectory.directoryID + fileName
                 metadataNet.fileName = fileName
                 metadataNet.path = fileNamePathDirectory + "/" + fileName
                 metadataNet.selector = selectorUploadFile
@@ -1018,7 +1011,7 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
                 return
             }
             
-            let item = FileProviderItem(metadata: metadataDB, parentItemIdentifier: parentItemIdentifier)
+            let item = FileProviderItem(metadata: metadataDB, parentItemIdentifier: parentItemIdentifier, providerData: self.providerData)
             completionHandler(item, nil)
         }
     }
@@ -1029,26 +1022,41 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
     
     func uploadFileSuccessFailure(_ fileName: String!, fileID: String!, identifier: String!, assetLocalIdentifier: String!, serverUrl: String!, selector: String!, selectorPost: String!, errorMessage: String!, errorCode: Int) {
         
+        /* ONLY iOS 11*/
+        guard #available(iOS 11, *) else { return }
+        
+        if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "fileID = %@", assetLocalIdentifier)) {
+            let parentItemIdentifier = providerData.getParentItemIdentifier(metadata: metadata)
+            let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier!, providerData: providerData)
+            
+            fileProviderSignalDeleteItemIdentifier.removeAll()
+            fileProviderSignalDeleteItemIdentifier.append(item.itemIdentifier)
+            signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
+        }
+        
         NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "fileID = %@", assetLocalIdentifier), clearDateReadDirectoryID: nil)
 
         if errorCode == 0 {
                 
             NCManageDatabase.sharedInstance.deleteQueueUpload(assetLocalIdentifier: assetLocalIdentifier, selector: selector)
             
-            if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account = %@ AND fileID = %@", account, fileID)) {
+            if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account = %@ AND fileID = %@", providerData.account, fileID)) {
                 
                 // Rename directory file
-                if fileManager.fileExists(atPath: fileProviderStorageURL!.path + "/" + assetLocalIdentifier) {
-                    let itemIdentifier = getItemIdentifier(metadata: metadata)
-                    _ = moveFile(fileProviderStorageURL!.path + "/" + assetLocalIdentifier, toPath: fileProviderStorageURL!.path + "/" + itemIdentifier.rawValue)
+                if fileManager.fileExists(atPath: providerData.fileProviderStorageURL!.path + "/" + assetLocalIdentifier) {
+                    let itemIdentifier = providerData.getItemIdentifier(metadata: metadata)
+                    _ = moveFile(providerData.fileProviderStorageURL!.path + "/" + assetLocalIdentifier, toPath: providerData.fileProviderStorageURL!.path + "/" + itemIdentifier.rawValue)
                 }
                 
                 NCManageDatabase.sharedInstance.setLocalFile(fileID: fileID, date: nil, exifDate: nil, exifLatitude: nil, exifLongitude: nil, fileName: nil, etag: metadata.etag, etagFPE: metadata.etag)
                 
-                let parentItemIdentifier = getParentItemIdentifier(metadata: metadata)
+                let parentItemIdentifier = providerData.getParentItemIdentifier(metadata: metadata)
                 if parentItemIdentifier != nil {
-                    let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier!)
-                    self.refreshEnumerator(identifier: item.itemIdentifier, serverUrl: serverUrl)
+                    let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier!, providerData: providerData)
+                    
+                    fileProviderSignalUpdateItem.removeAll()
+                    fileProviderSignalUpdateItem.append(item)
+                    signalEnumerator(for: [item.parentItemIdentifier, .workingSet])
                 } 
             }
             
@@ -1068,7 +1076,7 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
             let metadataNetQueue = NCManageDatabase.sharedInstance.lockQueueUpload(selector: selectorUploadFile, withPath: true)
             if  metadataNetQueue != nil {
                 
-                if self.copyFile(metadataNetQueue!.path, toPath: directoryUser + "/" + metadataNetQueue!.fileName) == nil {
+                if self.copyFile(metadataNetQueue!.path, toPath: providerData.directoryUser + "/" + metadataNetQueue!.fileName) == nil {
                     
                     CCNetworking.shared().uploadFile(metadataNetQueue!.fileName, serverUrl: metadataNetQueue!.serverUrl, identifier: metadataNetQueue!.identifier, assetLocalIdentifier: metadataNetQueue!.assetLocalIdentifier ,session: metadataNetQueue!.session, taskStatus: metadataNetQueue!.taskStatus, selector: metadataNetQueue!.selector, selectorPost: metadataNetQueue!.selectorPost, errorCode: 0, delegate: self)
                     
@@ -1084,7 +1092,7 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
         
         let tasks = CCNetworking.shared().getUploadTasksExtensionSession()
         if tasks!.count == 0 {
-            let records = NCManageDatabase.sharedInstance.getQueueUpload(predicate: NSPredicate(format: "account = %@ AND selector = %@ AND lock == true AND path != nil", account, selectorUploadFile))
+            let records = NCManageDatabase.sharedInstance.getQueueUpload(predicate: NSPredicate(format: "account = %@ AND selector = %@ AND lock == true AND path != nil", providerData.account, selectorUploadFile))
             if records != nil && records!.count > 0 {
                 NCManageDatabase.sharedInstance.unlockAllQueueUploadWithPath()
             }
@@ -1095,6 +1103,7 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
     //  MARK: - User Function
     // --------------------------------------------------------------------------------------------
     
+    /*
     func refreshEnumerator(identifier: NSFileProviderItemIdentifier, serverUrl: String) {
         
         /* ONLY iOS 11*/
@@ -1103,24 +1112,24 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
         let item = try? self.item(for: identifier)
         if item != nil {
             var found = false
-            for updateItem in listUpdateItems {
+            for updateItem in providerData.listUpdateItems {
                 if updateItem.itemIdentifier.rawValue == identifier.rawValue {
                     found = true
                 }
             }
             if !found {
-                listUpdateItems.append(item!)
+                providerData.listUpdateItems.append(item!)
             }
         }
         
-        if serverUrl == homeServerUrl {
+        if serverUrl == providerData.homeServerUrl {
             NSFileProviderManager.default.signalEnumerator(for: .rootContainer, completionHandler: { (error) in
                 print("send signal rootContainer")
             })
         } else {
-            if let directory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account = %@ AND serverUrl = %@", account, serverUrl)) {
-                if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account = %@ AND fileID = %@", account, directory.fileID)) {
-                    let itemIdentifier = getItemIdentifier(metadata: metadata)
+            if let directory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account = %@ AND serverUrl = %@", providerData.account, serverUrl)) {
+                if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account = %@ AND fileID = %@", providerData.account, directory.fileID)) {
+                    let itemIdentifier = providerData.getItemIdentifier(metadata: metadata)
                     NSFileProviderManager.default.signalEnumerator(for: itemIdentifier, completionHandler: { (error) in
                         print("send signal")
                     })
@@ -1128,6 +1137,7 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
             }
         }
     }
+    */
     
     func copyFile(_ atPath: String, toPath: String) -> Error? {
         
@@ -1189,7 +1199,7 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
             
             while exitLoop == false {
                 
-                if NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account = %@ AND fileNameView = %@ AND directoryID = %@", account, resultFileName, directoryID)) != nil || fileNamePathImport.contains(serverUrl+"/"+resultFileName) {
+                if NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account = %@ AND fileNameView = %@ AND directoryID = %@", providerData.account, resultFileName, directoryID)) != nil || fileNamePathImport.contains(serverUrl+"/"+resultFileName) {
                     
                     var name = NSString(string: resultFileName).deletingPathExtension
                     let ext = NSString(string: resultFileName).pathExtension
@@ -1223,109 +1233,3 @@ class FileProvider: NSFileProviderExtension, CCNetworkingDelegate {
         return resultFileName
     }
 }
-
-// --------------------------------------------------------------------------------------------
-//  MARK: -
-// --------------------------------------------------------------------------------------------
-
-func setupActiveAccount() -> Bool {
-    
-    groupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: NCBrandOptions.sharedInstance.capabilitiesGroups)
-    fileProviderStorageURL = groupURL!.appendingPathComponent(k_assetLocalIdentifierFileProviderStorage)
-    
-    // Create dir File Provider Storage
-    do {
-        try FileManager.default.createDirectory(atPath: fileProviderStorageURL!.path, withIntermediateDirectories: true, attributes: nil)
-    } catch let error as NSError {
-        NSLog("Unable to create directory \(error.debugDescription)")
-    }
-    
-    guard let activeAccount = NCManageDatabase.sharedInstance.getAccountActive() else {
-        return false
-    }
-    
-    account = activeAccount.account
-    accountUser = activeAccount.user
-    accountUserID = activeAccount.userID
-    accountPassword = activeAccount.password
-    accountUrl = activeAccount.url
-    homeServerUrl = CCUtility.getHomeServerUrlActiveUrl(activeAccount.url)
-    directoryUser = CCUtility.getDirectoryActiveUser(activeAccount.user, activeUrl: activeAccount.url)
-    
-    ocNetworking = OCnetworking.init(delegate: nil, metadataNet: nil, withUser: accountUser, withUserID: accountUserID, withPassword: accountPassword, withUrl: accountUrl)
-    
-    return true
-}
-
-func getTableMetadataFromItemIdentifier(_ itemIdentifier: NSFileProviderItemIdentifier) -> tableMetadata? {
-    
-    let fileID = itemIdentifier.rawValue
-    return NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account = %@ AND fileID = %@", account, fileID))
-}
-
-func getItemIdentifier(metadata: tableMetadata) -> NSFileProviderItemIdentifier {
-        
-    return NSFileProviderItemIdentifier(metadata.fileID)
-}
-
-func createFileIdentifierOnFileSystem(metadata: tableMetadata) {
-    
-    let itemIdentifier = getItemIdentifier(metadata: metadata)
-    let identifierPath = fileProviderStorageURL!.path + "/" + itemIdentifier.rawValue
-    let fileIdentifier = identifierPath + "/" + metadata.fileName
-    
-    do {
-        try FileManager.default.createDirectory(atPath: identifierPath, withIntermediateDirectories: true, attributes: nil)
-    } catch { }
-    
-    // If do not exists create file with size = 0
-    if FileManager.default.fileExists(atPath: fileIdentifier) == false {
-        FileManager.default.createFile(atPath: fileIdentifier, contents: nil, attributes: nil)
-    }
-}
-
-func getParentItemIdentifier(metadata: tableMetadata) -> NSFileProviderItemIdentifier? {
-    
-    /* ONLY iOS 11*/
-    guard #available(iOS 11, *) else { return NSFileProviderItemIdentifier("") }
-    
-    if let directory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account = %@ AND directoryID = %@", account, metadata.directoryID))  {
-        if directory.serverUrl == homeServerUrl {
-            return NSFileProviderItemIdentifier(NSFileProviderItemIdentifier.rootContainer.rawValue)
-        } else {
-            // get the metadata.FileID of parent Directory
-            if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account = %@ AND fileID = %@", account, directory.fileID))  {
-                let identifier = getItemIdentifier(metadata: metadata)
-                return identifier
-            }
-        }
-    }
-    
-    return nil
-}
-
-func getTableDirectoryFromParentItemIdentifier(_ parentItemIdentifier: NSFileProviderItemIdentifier) -> tableDirectory? {
-    
-    /* ONLY iOS 11*/
-    guard #available(iOS 11, *) else { return nil }
-    
-    var predicate: NSPredicate
-
-    if parentItemIdentifier == .rootContainer {
-        predicate = NSPredicate(format: "account = %@ AND serverUrl = %@", account, homeServerUrl)
-    } else {
-
-        guard let metadata = getTableMetadataFromItemIdentifier(parentItemIdentifier) else {
-            return nil
-        }
-        predicate = NSPredicate(format: "account = %@ AND fileID = %@", account, metadata.fileID)
-    }
-    
-    guard let directory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: predicate) else {
-        return nil
-    }
-    
-    return directory
-}
-    
-

+ 11 - 25
PickerFileProvider/FileProviderItem.swift

@@ -23,17 +23,6 @@
 
 import FileProvider
 
-// Unenumerated changes. Record the changes that have not be enumerated
-//
-struct UnenumChanges: OptionSet, Codable {
-    let rawValue: Int
-    
-    static let containerUpdate = UnenumChanges(rawValue: 1 << 0)
-    static let containerDelete = UnenumChanges(rawValue: 1 << 1)
-    static let workingSetUpdate = UnenumChanges(rawValue: 1 << 2)
-    static let workingSetDelete = UnenumChanges(rawValue: 1 << 3)
-}
-
 class FileProviderItem: NSObject, NSFileProviderItem {
 
     // Providing Required Properties
@@ -79,12 +68,11 @@ class FileProviderItem: NSObject, NSFileProviderItem {
     var favoriteRank: NSNumber?                                     // Favorite
     
     var isDirectory = false
-    var unenumChanges: UnenumChanges = []
 
-    init(metadata: tableMetadata, parentItemIdentifier: NSFileProviderItemIdentifier) {
+    init(metadata: tableMetadata, parentItemIdentifier: NSFileProviderItemIdentifier, providerData: FileProviderData) {
         
         self.parentItemIdentifier = parentItemIdentifier
-        self.itemIdentifier = getItemIdentifier(metadata: metadata)
+        self.itemIdentifier = providerData.getItemIdentifier(metadata: metadata)
         
         self.contentModificationDate = metadata.date as Date
         self.creationDate = metadata.date as Date
@@ -97,7 +85,7 @@ class FileProviderItem: NSObject, NSFileProviderItem {
         // This is a file
         if (!metadata.directory) {
             
-            let fileIdentifier = fileProviderStorageURL!.path + "/" + self.itemIdentifier.rawValue + "/" + metadata.fileNameView
+            let fileIdentifier = providerData.fileProviderStorageURL!.path + "/" + self.itemIdentifier.rawValue + "/" + metadata.fileNameView
             var fileSize = 0 as Double
          
             do {
@@ -117,6 +105,14 @@ class FileProviderItem: NSObject, NSFileProviderItem {
                 self.isMostRecentVersionDownloaded = true
             }
             
+            // Upload
+            if metadata.fileID.contains(k_uploadSessionID) {
+                self.isDownloaded = true
+                self.isMostRecentVersionDownloaded = true
+                self.isUploading = true
+                self.isUploaded = false
+            }
+            
         } else {
             
             /*
@@ -135,15 +131,5 @@ class FileProviderItem: NSObject, NSFileProviderItem {
         if let tableTag = NCManageDatabase.sharedInstance.getTag(predicate: NSPredicate(format: "account = %@ AND fileID = %@", metadata.account, metadata.fileID)) {
             tagData = tableTag.tagIOS
         }
-        
-        // Removed (if exists) this Item from listUpdate
-        var counter = 0
-        for updateItem in listUpdateItems {
-            if updateItem.itemIdentifier.rawValue == itemIdentifier.rawValue {
-                listUpdateItems.remove(at: counter)
-                break;
-            }
-            counter += 1
-        }
     }
 }

+ 1 - 1
iOSClient/Brand/Picker.plist

@@ -19,7 +19,7 @@
 	<key>CFBundleShortVersionString</key>
 	<string>2.21.0</string>
 	<key>CFBundleVersion</key>
-	<string>00013</string>
+	<string>00014</string>
 	<key>NSAppTransportSecurity</key>
 	<dict>
 		<key>NSAllowsArbitraryLoads</key>

+ 2 - 2
iOSClient/Brand/PickerFileProvider.plist

@@ -19,7 +19,7 @@
 	<key>CFBundleShortVersionString</key>
 	<string>2.21.0</string>
 	<key>CFBundleVersion</key>
-	<string>00013</string>
+	<string>00014</string>
 	<key>NSExtension</key>
 	<dict>
 		<key>NSExtensionFileProviderDocumentGroup</key>
@@ -29,7 +29,7 @@
 		<key>NSExtensionPointIdentifier</key>
 		<string>com.apple.fileprovider-nonui</string>
 		<key>NSExtensionPrincipalClass</key>
-		<string>$(PRODUCT_MODULE_NAME).FileProvider</string>
+		<string>$(PRODUCT_MODULE_NAME).FileProviderExtension</string>
 	</dict>
 </dict>
 </plist>

+ 1 - 1
iOSClient/Brand/Share.plist

@@ -19,7 +19,7 @@
 	<key>CFBundleShortVersionString</key>
 	<string>2.21.0</string>
 	<key>CFBundleVersion</key>
-	<string>00013</string>
+	<string>00014</string>
 	<key>NSAppTransportSecurity</key>
 	<dict>
 		<key>NSAllowsArbitraryLoads</key>

+ 1 - 1
iOSClient/Brand/iOSClient.plist

@@ -69,7 +69,7 @@
 		</dict>
 	</array>
 	<key>CFBundleVersion</key>
-	<string>00013</string>
+	<string>00014</string>
 	<key>FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED</key>
 	<true/>
 	<key>Fabric</key>