Browse Source

improved pagination file provider extension

marinofaggiana 5 years ago
parent
commit
7592c0a038

+ 1 - 4
File Provider Extension/FileProviderData.swift

@@ -37,10 +37,7 @@ class fileProviderData: NSObject {
     var homeServerUrl = ""
         
     // Max item for page
-    let itemForPage = 20
-
-    // List of etag for serverUrl
-    var listServerUrlEtag = [String:String]()
+    let itemForPage = 100
     
     // Anchor
     var currentAnchor: UInt64 = 0

+ 75 - 101
File Provider Extension/FileProviderEnumerator.swift

@@ -56,7 +56,6 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
     func enumerateItems(for observer: NSFileProviderEnumerationObserver, startingAt page: NSFileProviderPage) {
         
         var items: [NSFileProviderItemProtocol] = []
-        var metadatasFromDB: [tableMetadata]?
         
         /*** WorkingSet ***/
         if enumeratedItemIdentifier == .workingSet {
@@ -101,82 +100,24 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
                 return
             }
             
-            // Select items from database
-            metadatasFromDB = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), 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)!)!
+            if (page == NSFileProviderPage.initialPageSortedByDate as NSFileProviderPage || page == NSFileProviderPage.initialPageSortedByName as NSFileProviderPage) {
                 
-                if (metadatasFromDB != nil) {
-                    items = self.selectItems(numPage: numPage, account: fileProviderData.sharedInstance.account, metadatas: metadatasFromDB!)
-                    observer.didEnumerate(items)
-                }
-                if (items.count == fileProviderData.sharedInstance.itemForPage) {
-                    numPage += 1
-                    let providerPage = NSFileProviderPage("\(numPage)".data(using: .utf8)!)
-                    observer.finishEnumerating(upTo: providerPage)
-                } else {
-                    observer.finishEnumerating(upTo: nil)
+                readFileOrFolder(serverUrl: serverUrl) {
+                    let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), page: 1, limit: fileProviderData.sharedInstance.itemForPage, sorted: "fileName", ascending: true)
+                    
+                    self.completeObserver(observer, numPage: 1, metadatas: metadatas)
                 }
-                return
-            }
-            
-            // Update the WorkingSet -> Favorite
-            fileProviderData.sharedInstance.updateFavoriteForWorkingSet()
-            
-            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 }
+                // Update the WorkingSet -> Favorite
+                fileProviderData.sharedInstance.updateFavoriteForWorkingSet()
                 
-                if etag != etagServerUrl {
-                                
-                    NCCommunication.sharedInstance.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", account: fileProviderData.sharedInstance.account, completionHandler: { (account, files, errorCode, errorDescription) in
-                        
-                        if errorCode == 0 && files != nil  && files!.count >= 1 {
-                            
-                            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))
-                                
-                            NCManageDatabase.sharedInstance.setDateReadDirectory(serverUrl: serverUrl, account: account)
-                                
-                            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!)
-                            }
-                            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)
-                }
-            })
+            } else {
+                
+                let numPage = Int(String(data: page.rawValue, encoding: .utf8)!)!
+                let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), page: numPage, limit: fileProviderData.sharedInstance.itemForPage, sorted: "fileName", ascending: true)
+                
+                completeObserver(observer, numPage: numPage, metadatas: metadatas)
+            }
         }
     }
     
@@ -226,51 +167,84 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
     }
     
     // --------------------------------------------------------------------------------------------
-    //  MARK: - User Function
+    //  MARK: - User Function + Network
     // --------------------------------------------------------------------------------------------
 
-    func selectFirstPageItems(_ metadatas: [tableMetadata]?, observer: NSFileProviderEnumerationObserver) {
-        
+    func completeObserver(_ observer: NSFileProviderEnumerationObserver, numPage: Int, metadatas: [tableMetadata]?) {
+            
+        var numPage = numPage
         var items: [NSFileProviderItemProtocol] = []
-        
+
         if (metadatas != nil) {
-            items = self.selectItems(numPage: 0, account: fileProviderData.sharedInstance.account, metadatas: metadatas!)
+            
+            for metadata in metadatas! {
+                    
+                if metadata.e2eEncrypted || metadata.status == Int(k_metadataStatusHide) || (metadata.session != "" && metadata.session != k_upload_session_extension) { continue }
+                    
+                fileProviderUtility.sharedInstance.createocIdentifierOnFileSystem(metadata: metadata)
+                        
+                let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadata, homeServerUrl: fileProviderData.sharedInstance.homeServerUrl)
+                if parentItemIdentifier != nil {
+                    let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier!)
+                    items.append(item)
+                }
+            }
             observer.didEnumerate(items)
         }
+        
         if (items.count == fileProviderData.sharedInstance.itemForPage) {
-            let providerPage = NSFileProviderPage("1".data(using: .utf8)!)
+            numPage += 1
+            let providerPage = NSFileProviderPage("\(numPage)".data(using: .utf8)!)
             observer.finishEnumerating(upTo: providerPage)
         } else {
             observer.finishEnumerating(upTo: nil)
         }
     }
-    
-    func selectItems(numPage: Int, account: String, metadatas: [tableMetadata]) -> [NSFileProviderItemProtocol] {
         
-        var items: [NSFileProviderItemProtocol] = []
-        let start = numPage * fileProviderData.sharedInstance.itemForPage + 1
-        let stop = start + (fileProviderData.sharedInstance.itemForPage - 1)
-        var counter = 0
+    func readFileOrFolder(serverUrl: String, completionHandler: @escaping () -> Void) {
         
-        autoreleasepool {
+        NCCommunication.sharedInstance.readFileOrFolder(serverUrlFileName: serverUrl, depth: "0", account: fileProviderData.sharedInstance.account, completionHandler: { (account, files, errorCode, errorDescription) in
             
-            for metadata in metadatas {
-                
-                if metadata.e2eEncrypted || metadata.status == Int(k_metadataStatusHide) || (metadata.session != "" && metadata.session != k_upload_session_extension) { continue }
-                
-                counter += 1
-                if (counter >= start && counter <= stop) {
-                    
-                    fileProviderUtility.sharedInstance.createocIdentifierOnFileSystem(metadata: metadata)
-                    
-                    let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadata, homeServerUrl: fileProviderData.sharedInstance.homeServerUrl)
-                    if parentItemIdentifier != nil {
-                        let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier!)
-                        items.append(item)
+            var needReadFolder = true
+        
+            if let tableDirectory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl)) {
+                if errorCode == 0 && files != nil && files!.count == 1 {
+                    if tableDirectory.etag == files![0].etag {
+                        needReadFolder = false
                     }
                 }
             }
-        }
-        return items
+            
+            if needReadFolder {
+
+                NCCommunication.sharedInstance.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", account: fileProviderData.sharedInstance.account, completionHandler: { (account, files, errorCode, errorDescription) in
+                    
+                    if errorCode == 0 && files != nil  && files!.count >= 1 {
+                        
+                        // Update directory etag
+                        let directory = files![0]
+                        NCManageDatabase.sharedInstance.setDirectory(serverUrl: serverUrl, serverUrlTo: nil, etag: directory.etag, ocId: directory.ocId, encrypted: directory.e2eEncrypted, account: account)
+                                                
+                        // Update DB
+                        NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d)", account, serverUrl, k_metadataStatusNormal, k_metadataStatusHide))
+                        NCManageDatabase.sharedInstance.setDateReadDirectory(serverUrl: serverUrl, account: account)
+                        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!)
+                        }
+                        if metadatasInUpload != nil {
+                            _ = NCManageDatabase.sharedInstance.addMetadatas(metadatasInUpload!)
+                        }
+                    }
+                    completionHandler()
+                })
+            } else {
+                completionHandler()
+            }
+        })
     }
+    
 }

+ 5 - 1
iOSClient/Database/NCManageDatabase.swift

@@ -2114,7 +2114,11 @@ class NCManageDatabase: NSObject {
             var metadatas = [tableMetadata]()
             
             for n in nFrom...nTo {
-                metadatas.append(results[n])
+                if n == results.count {
+                    break
+                }
+                let metadata = tableMetadata.init(value: results[n])
+                metadatas.append(metadata)
             }
             
             return metadatas