Browse Source

Merge branch 'develop' of https://github.com/nextcloud/ios into media-view-fix

Signed-off-by: Milen Pivchev <milen.pivchev@gmail.com>

# Conflicts:
#	iOSClient/Main/Collection Common/NCCollectionViewCommon.swift
Milen Pivchev 1 year ago
parent
commit
214ca57b13
28 changed files with 1161 additions and 936 deletions
  1. 1 16
      .swiftlint.yml
  2. 1 1
      Brand/Database.swift
  3. 4 4
      Nextcloud.xcodeproj/project.pbxproj
  4. 3 0
      Share/NCShareExtension+NCDelegate.swift
  5. 23 24
      iOSClient/Data/NCDataSource.swift
  6. 91 94
      iOSClient/Data/NCManageDatabase+Account.swift
  7. 65 46
      iOSClient/Data/NCManageDatabase+Activity.swift
  8. 24 24
      iOSClient/Data/NCManageDatabase+Avatar.swift
  9. 17 14
      iOSClient/Data/NCManageDatabase+Capabilities.swift
  10. 24 24
      iOSClient/Data/NCManageDatabase+DashboardWidget.swift
  11. 32 46
      iOSClient/Data/NCManageDatabase+Directory.swift
  12. 63 74
      iOSClient/Data/NCManageDatabase+E2EE.swift
  13. 1 5
      iOSClient/Data/NCManageDatabase+Groupfolders.swift
  14. 16 13
      iOSClient/Data/NCManageDatabase+LayoutForView.swift
  15. 198 173
      iOSClient/Data/NCManageDatabase+Metadata.swift
  16. 64 60
      iOSClient/Data/NCManageDatabase+Share.swift
  17. 12 17
      iOSClient/Data/NCManageDatabase+Video.swift
  18. 204 195
      iOSClient/Data/NCManageDatabase.swift
  19. 10 35
      iOSClient/Main/Collection Common/NCCollectionViewCommon.swift
  20. 10 11
      iOSClient/NCGlobal.swift
  21. 277 36
      iOSClient/Networking/E2EE/NCEndToEndEncryption.m
  22. 0 7
      iOSClient/Networking/E2EE/NCNetworkingE2EEUpload.swift
  23. 21 17
      iOSClient/Networking/NCNetworkingProcessUpload.swift
  24. BIN
      iOSClient/Supporting Files/ar.lproj/Localizable.strings
  25. BIN
      iOSClient/Supporting Files/el.lproj/Localizable.strings
  26. BIN
      iOSClient/Supporting Files/fa.lproj/Localizable.strings
  27. BIN
      iOSClient/Supporting Files/gl.lproj/Localizable.strings
  28. BIN
      iOSClient/Supporting Files/uk.lproj/Localizable.strings

+ 1 - 16
.swiftlint.yml

@@ -37,7 +37,7 @@ disabled_rules:
   - cyclomatic_complexity
   - nesting
   - shorthand_operator
-  - force_try
+  - type_name
     
 excluded:
   - Carthage
@@ -70,21 +70,6 @@ excluded:
   - iOSClient/AppDelegate.swift
   - iOSClient/BackgroundImageColor/NCBackgroundImageColor.swift
   - iOSClient/BrowserWeb/NCBrowserWeb.swift
-  - iOSClient/Data/NCDataSource.swift
-  - iOSClient/Data/NCDatabase.swift
-  - iOSClient/Data/NCElementsJSON.swift
-  - iOSClient/Data/NCManageDatabase+Capabilities.swift
-  - iOSClient/Data/NCManageDatabase+Account.swift
-  - iOSClient/Data/NCManageDatabase+Activity.swift
-  - iOSClient/Data/NCManageDatabase+Avatar.swift
-  - iOSClient/Data/NCManageDatabase+E2EE.swift
-  - iOSClient/Data/NCManageDatabase.swift
-  - iOSClient/Data/NCManageDatabase+Metadata.swift
-  - iOSClient/Data/NCManageDatabase+Directory.swift
-  - iOSClient/Data/NCManageDatabase+Share.swift
-  - iOSClient/Data/NCManageDatabase+Video.swift
-  - iOSClient/Data/NCManageDatabase+LayoutForView.swift
-  - iOSClient/Data/NCManageDatabase+DashboardWidget.swift
   - iOSClient/Diagnostics/NCCapabilitiesViewController.swift
   - iOSClient/EmptyView/NCEmptyDataSet.swift
   - iOSClient/Extensions/UIColor+Extensions.swift

+ 1 - 1
Brand/Database.swift

@@ -26,4 +26,4 @@ import Foundation
 // Database Realm
 //
 let databaseName                    = "nextcloud.realm"
-let databaseSchemaVersion: UInt64   = 297
+let databaseSchemaVersion: UInt64   = 298

+ 4 - 4
Nextcloud.xcodeproj/project.pbxproj

@@ -4566,7 +4566,7 @@
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				COPY_PHASE_STRIP = NO;
-				CURRENT_PROJECT_VERSION = 3;
+				CURRENT_PROJECT_VERSION = 0;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				DEVELOPMENT_TEAM = NKUJUXUJ3B;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
@@ -4592,7 +4592,7 @@
 					"@executable_path/Frameworks",
 					"@executable_path/../../Frameworks",
 				);
-				MARKETING_VERSION = 4.8.4;
+				MARKETING_VERSION = 4.8.5;
 				ONLY_ACTIVE_ARCH = YES;
 				OTHER_LDFLAGS = "";
 				SDKROOT = iphoneos;
@@ -4631,7 +4631,7 @@
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				COPY_PHASE_STRIP = NO;
-				CURRENT_PROJECT_VERSION = 3;
+				CURRENT_PROJECT_VERSION = 0;
 				DEVELOPMENT_TEAM = NKUJUXUJ3B;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				ENABLE_TESTABILITY = YES;
@@ -4654,7 +4654,7 @@
 					"@executable_path/Frameworks",
 					"@executable_path/../../Frameworks",
 				);
-				MARKETING_VERSION = 4.8.4;
+				MARKETING_VERSION = 4.8.5;
 				ONLY_ACTIVE_ARCH = YES;
 				OTHER_LDFLAGS = "";
 				SDKROOT = iphoneos;

+ 3 - 0
Share/NCShareExtension+NCDelegate.swift

@@ -76,6 +76,9 @@ extension NCShareExtension: NCEmptyDataSetDelegate, NCAccountRequestDelegate {
         }
         self.activeAccount = activeAccount
 
+        // CAPABILITIES
+        NCManageDatabase.shared.setCapabilities(account: account)
+
         // COLORS
         NCBrandColor.shared.settingThemingColor(account: activeAccount.account)
         NCBrandColor.shared.createUserColors()

+ 23 - 24
iOSClient/Data/NCDataSource.swift

@@ -124,14 +124,14 @@ class NCDataSource: NSObject {
 
         // Unified search
         if let providers = self.providers, !providers.isEmpty {
-            let sectionsDictionary = ThreadSafeDictionary<String,Int>()
+            let sectionsDictionary = ThreadSafeDictionary<String, Int>()
             for section in self.sectionsValue {
                 if let provider = providers.filter({ $0.id == section}).first {
                     sectionsDictionary[section] = provider.order
                 }
             }
             self.sectionsValue.removeAll()
-            let sectionsDictionarySorted = sectionsDictionary.sorted(by: { $0.value < $1.value } )
+            let sectionsDictionarySorted = sectionsDictionary.sorted(by: {$0.value < $1.value })
             for section in sectionsDictionarySorted {
                 if section.key == NCGlobal.shared.appName {
                     self.sectionsValue.insert(section.key, at: 0)
@@ -173,15 +173,15 @@ class NCDataSource: NSObject {
             searchResult = searchResults.filter({ $0.id == sectionValue}).first
         }
         let metadatas = self.metadatas.filter({ getSectionValue(metadata: $0) == sectionValue})
-        let metadataForSection = NCMetadataForSection.init(sectionValue: sectionValue,
-                                                            metadatas: metadatas,
-                                                            localFiles: self.localFiles,
-                                                            lastSearchResult: searchResult,
-                                                            sort: self.sort,
-                                                            ascending: self.ascending,
-                                                            directoryOnTop: self.directoryOnTop,
-                                                            favoriteOnTop: self.favoriteOnTop,
-                                                            filterLivePhoto: self.filterLivePhoto)
+        let metadataForSection = NCMetadataForSection(sectionValue: sectionValue,
+                                                      metadatas: metadatas,
+                                                      localFiles: self.localFiles,
+                                                      lastSearchResult: searchResult,
+                                                      sort: self.sort,
+                                                      ascending: self.ascending,
+                                                      directoryOnTop: self.directoryOnTop,
+                                                      favoriteOnTop: self.favoriteOnTop,
+                                                      filterLivePhoto: self.filterLivePhoto)
         metadatasForSection.append(metadataForSection)
     }
 
@@ -200,8 +200,8 @@ class NCDataSource: NSObject {
 
     @discardableResult
     func appendMetadatasToSection(_ metadatas: [tableMetadata], metadataForSection: NCMetadataForSection, lastSearchResult: NKSearchResult) -> [IndexPath] {
-        
-        guard let sectionIndex =  getSectionIndex(metadataForSection.sectionValue) else { return [] }
+
+        guard let sectionIndex = getSectionIndex(metadataForSection.sectionValue) else { return [] }
         var indexPaths: [IndexPath] = []
 
         self.metadatas.append(contentsOf: metadatas)
@@ -268,7 +268,7 @@ class NCDataSource: NSObject {
         let (indexPath, metadataForSection) = self.getIndexPathMetadata(ocId: ocId)
         if let indexPath = indexPath, let metadataForSection = metadataForSection, indexPath.row < metadataForSection.metadatas.count {
             metadataForSection.metadatas.remove(at: indexPath.row)
-            if metadataForSection.metadatas.count == 0 {
+            if metadataForSection.metadatas.isEmpty {
                 // REMOVE sectionsValue / metadatasForSection
                 sectionValue = metadataForSection.sectionValue
                 if let sectionIndex = getSectionIndex(sectionValue) {
@@ -329,32 +329,32 @@ class NCDataSource: NSObject {
     }
 
     func isSameNumbersOfSections(numberOfSections: Int) -> Bool {
-        guard self.metadatasForSection.count > 0 else { return false }
+        guard !self.metadatasForSection.isEmpty else { return false }
         return numberOfSections == self.numberOfSections()
     }
 
     func numberOfSections() -> Int {
-        guard self.sectionsValue.count > 0 else { return 1 }
+        guard !self.sectionsValue.isEmpty else { return 1 }
         return self.sectionsValue.count
     }
-    
+
     func numberOfItemsInSection(_ section: Int) -> Int {
-        guard self.sectionsValue.count > 0 && self.metadatas.count > 0, let metadataForSection = getMetadataForSection(section) else { return 0}
+        guard !self.sectionsValue.isEmpty && !self.metadatas.isEmpty, let metadataForSection = getMetadataForSection(section) else { return 0}
         return metadataForSection.metadatas.count
     }
 
     func cellForItemAt(indexPath: IndexPath) -> tableMetadata? {
-        guard metadatasForSection.count > 0 && indexPath.section < metadatasForSection.count, let metadataForSection = getMetadataForSection(indexPath.section), indexPath.row < metadataForSection.metadatas.count else { return nil }
+        guard !metadatasForSection.isEmpty && indexPath.section < metadatasForSection.count, let metadataForSection = getMetadataForSection(indexPath.section), indexPath.row < metadataForSection.metadatas.count else { return nil }
         return metadataForSection.metadatas[indexPath.row]
     }
 
     func getSectionValue(indexPath: IndexPath) -> String {
-        guard metadatasForSection.count > 0 , let metadataForSection = self.getMetadataForSection(indexPath.section) else { return ""}
+        guard !metadatasForSection.isEmpty, let metadataForSection = self.getMetadataForSection(indexPath.section) else { return ""}
         return metadataForSection.sectionValue
     }
 
     func getSectionValueLocalization(indexPath: IndexPath) -> String {
-        guard metadatasForSection.count > 0 , let metadataForSection = self.getMetadataForSection(indexPath.section) else { return ""}
+        guard !metadatasForSection.isEmpty, let metadataForSection = self.getMetadataForSection(indexPath.section) else { return ""}
         if let searchResults = self.searchResults, let searchResult = searchResults.filter({ $0.id == metadataForSection.sectionValue}).first {
             return searchResult.name
         }
@@ -423,7 +423,7 @@ class NCMetadataForSection: NSObject {
     var lastSearchResult: NKSearchResult?
     var unifiedSearchInProgress: Bool = false
 
-    private var sort : String
+    private var sort: String
     private var ascending: Bool
     private var directoryOnTop: Bool
     private var favoriteOnTop: Bool
@@ -478,7 +478,7 @@ class NCMetadataForSection: NSObject {
 
         // Metadata order
         //
-        if sort != "none" && sort != "" {
+        if sort != "none" && !sort.isEmpty {
             metadatasSorted = metadatas.sorted {
 
                 switch sort {
@@ -543,7 +543,6 @@ class NCMetadataForSection: NSObject {
                 metadatasFile.append(metadata)
             }
 
-            //Info
             if metadata.directory {
                 ocIds.append(metadata.ocId)
                 numDirectory += 1

+ 91 - 94
iOSClient/Data/NCManageDatabase+Account.swift

@@ -81,19 +81,6 @@ class tableAccount: Object, NCUserBaseUrl {
     @objc dynamic var website = ""
     @objc dynamic var zip = ""
 
-    // HC
-    @objc dynamic var hcIsTrial: Bool = false
-    @objc dynamic var hcTrialExpired: Bool = false
-    @objc dynamic var hcTrialRemainingSec: Int64 = 0
-    @objc dynamic var hcTrialEndTime: NSDate?
-    @objc dynamic var hcAccountRemoveExpired: Bool = false
-    @objc dynamic var hcAccountRemoveRemainingSec: Int64 = 0
-    @objc dynamic var hcAccountRemoveTime: NSDate?
-    @objc dynamic var hcNextGroupExpirationGroup = ""
-    @objc dynamic var hcNextGroupExpirationGroupExpired: Bool = false
-    @objc dynamic var hcNextGroupExpirationExpiresTime: NSDate?
-    @objc dynamic var hcNextGroupExpirationExpires = ""
-
     override static func primaryKey() -> String {
         return "account"
     }
@@ -103,9 +90,8 @@ extension NCManageDatabase {
 
     @objc func addAccount(_ account: String, urlBase: String, user: String, password: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let addObject = tableAccount()
 
@@ -135,9 +121,8 @@ extension NCManageDatabase {
 
     @objc func updateAccount(_ account: tableAccount) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 realm.add(account, update: .all)
             }
@@ -148,9 +133,8 @@ extension NCManageDatabase {
 
     @objc func deleteAccount(_ account: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let result = realm.objects(tableAccount.self).filter("account == %@", account)
                 realm.delete(result)
@@ -162,23 +146,27 @@ extension NCManageDatabase {
 
     @objc func getActiveAccount() -> tableAccount? {
 
-        let realm = try! Realm()
-
-        guard let result = realm.objects(tableAccount.self).filter("active == true").first else {
-            return nil
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableAccount.self).filter("active == true").first else { return nil }
+            return tableAccount.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return tableAccount.init(value: result)
+        return nil
     }
 
     @objc func getAccounts() -> [String]? {
 
-        let realm = try! Realm()
-
-        let results = realm.objects(tableAccount.self).sorted(byKeyPath: "account", ascending: true)
-
-        if results.count > 0 {
-            return Array(results.map { $0.account })
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableAccount.self).sorted(byKeyPath: "account", ascending: true)
+            if !results.isEmpty {
+                return Array(results.map { $0.account })
+            }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
         return nil
@@ -186,68 +174,82 @@ extension NCManageDatabase {
 
     @objc func getAccount(predicate: NSPredicate) -> tableAccount? {
 
-        let realm = try! Realm()
-
-        guard let result = realm.objects(tableAccount.self).filter(predicate).first else {
-            return nil
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableAccount.self).filter(predicate).first else { return nil }
+            return tableAccount.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return tableAccount.init(value: result)
+        return nil
     }
 
     @objc func getAllAccount() -> [tableAccount] {
 
-        let realm = try! Realm()
-
-        let sorted = [SortDescriptor(keyPath: "active", ascending: false), SortDescriptor(keyPath: "user", ascending: true)]
-        let results = realm.objects(tableAccount.self).sorted(by: sorted)
+        do {
+            let realm = try Realm()
+            let sorted = [SortDescriptor(keyPath: "active", ascending: false), SortDescriptor(keyPath: "user", ascending: true)]
+            let results = realm.objects(tableAccount.self).sorted(by: sorted)
+            return Array(results.map { tableAccount.init(value: $0) })
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        return Array(results.map { tableAccount.init(value: $0) })
+        return []
     }
 
     @objc func getAllAccountOrderAlias() -> [tableAccount] {
 
-        let realm = try! Realm()
-
-        let sorted = [SortDescriptor(keyPath: "active", ascending: false), SortDescriptor(keyPath: "alias", ascending: true), SortDescriptor(keyPath: "user", ascending: true)]
-        let results = realm.objects(tableAccount.self).sorted(by: sorted)
+        do {
+            let realm = try Realm()
+            let sorted = [SortDescriptor(keyPath: "active", ascending: false), SortDescriptor(keyPath: "alias", ascending: true), SortDescriptor(keyPath: "user", ascending: true)]
+            let results = realm.objects(tableAccount.self).sorted(by: sorted)
+            return Array(results.map { tableAccount.init(value: $0) })
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        return Array(results.map { tableAccount.init(value: $0) })
+        return []
     }
 
     @objc func getAccountAutoUploadFileName() -> String {
 
-        let realm = try! Realm()
-
-        guard let result = realm.objects(tableAccount.self).filter("active == true").first else {
-            return ""
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableAccount.self).filter("active == true").first else { return "" }
+            if result.autoUploadFileName.isEmpty {
+                return NCBrandOptions.shared.folderDefaultAutoUpload
+            } else {
+                return result.autoUploadFileName
+            }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        if result.autoUploadFileName.count > 0 {
-            return result.autoUploadFileName
-        } else {
-            return NCBrandOptions.shared.folderDefaultAutoUpload
-        }
+        return ""
     }
 
     @objc func getAccountAutoUploadDirectory(urlBase: String, userId: String, account: String) -> String {
 
-        let realm = try! Realm()
-
-        guard let result = realm.objects(tableAccount.self).filter("active == true").first else {
-            return ""
-        }
-
-        if result.autoUploadDirectory.count > 0 {
-            // FIX change webdav -> /dav/files/
-            if result.autoUploadDirectory.contains("/webdav") {
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableAccount.self).filter("active == true").first else { return "" }
+            if result.autoUploadDirectory.isEmpty {
                 return NCUtilityFileSystem.shared.getHomeServer(urlBase: urlBase, userId: userId)
             } else {
-                return result.autoUploadDirectory
+                // FIX change webdav -> /dav/files/
+                if result.autoUploadDirectory.contains("/webdav") {
+                    return NCUtilityFileSystem.shared.getHomeServer(urlBase: urlBase, userId: userId)
+                } else {
+                    return result.autoUploadDirectory
+                }
             }
-        } else {
-            return NCUtilityFileSystem.shared.getHomeServer(urlBase: urlBase, userId: userId)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
+
+        return ""
     }
 
     @objc func getAccountAutoUploadPath(urlBase: String, userId: String, account: String) -> String {
@@ -262,22 +264,24 @@ extension NCManageDatabase {
 
     @objc func getAccountAutoUploadSubfolderGranularity() -> Int64 {
 
-        let realm = try! Realm()
-
-        guard let result = realm.objects(tableAccount.self).filter("active == true").first else {
-            return 1
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableAccount.self).filter("active == true").first else { return 1 }
+            return result.autoUploadSubfolderGranularity
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return result.autoUploadSubfolderGranularity
+        return 1
     }
-    
+
     @discardableResult
     @objc func setAccountActive(_ account: String) -> tableAccount? {
 
-        let realm = try! Realm()
         var accountReturn = tableAccount()
 
         do {
+            let realm = try Realm()
             try realm.write {
 
                 let results = realm.objects(tableAccount.self)
@@ -300,9 +304,8 @@ extension NCManageDatabase {
 
     @objc func removePasswordAccount(_ account: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
 
                 if let result = realm.objects(tableAccount.self).filter("account == %@", account).first {
@@ -316,9 +319,8 @@ extension NCManageDatabase {
 
     @objc func setAccountAutoUploadProperty(_ property: String, state: Bool) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 if let result = realm.objects(tableAccount.self).filter("active == true").first {
                     if (tableAccount().objectSchema.properties.contains { $0.name == property }) {
@@ -333,9 +335,8 @@ extension NCManageDatabase {
 
     @objc func setAccountAutoUploadGranularity(_ property: String, state: Int64) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 if let result = realm.objects(tableAccount.self).filter("active == true").first {
                     result.autoUploadSubfolderGranularity = state
@@ -345,12 +346,11 @@ extension NCManageDatabase {
             NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
     }
-    
-    @objc func setAccountAutoUploadFileName(_ fileName: String?) {
 
-        let realm = try! Realm()
+    @objc func setAccountAutoUploadFileName(_ fileName: String?) {
 
         do {
+            let realm = try Realm()
             try realm.write {
                 if let result = realm.objects(tableAccount.self).filter("active == true").first {
                     if let fileName = fileName {
@@ -367,9 +367,8 @@ extension NCManageDatabase {
 
     @objc func setAccountAutoUploadDirectory(_ serverUrl: String?, urlBase: String, userId: String, account: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 if let result = realm.objects(tableAccount.self).filter("active == true").first {
                     if let serverUrl = serverUrl {
@@ -386,9 +385,8 @@ extension NCManageDatabase {
 
     @objc func setAccountUserProfile(account: String, userProfile: NKUserProfile) -> tableAccount? {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 if let result = realm.objects(tableAccount.self).filter("account == %@", account).first {
                     result.address = userProfile.address
@@ -416,21 +414,20 @@ extension NCManageDatabase {
                     result.website = userProfile.website
                 }
             }
+            if let result = realm.objects(tableAccount.self).filter("account == %@", account).first {
+                return tableAccount.init(value: result)
+            }
         } catch let error {
             NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        if let result = realm.objects(tableAccount.self).filter("account == %@", account).first {
-            return tableAccount.init(value: result)
-        } else {
-            return nil
-        }
+        return nil
     }
 
     @objc func setAccountMediaPath(_ path: String, account: String) {
 
-        let realm = try! Realm()
         do {
+            let realm = try Realm()
             try realm.write {
                 if let result = realm.objects(tableAccount.self).filter("account == %@", account).first {
                     result.mediaPath = path
@@ -443,8 +440,8 @@ extension NCManageDatabase {
 
     @objc func setAccountUserStatus(userStatusClearAt: NSDate?, userStatusIcon: String?, userStatusMessage: String?, userStatusMessageId: String?, userStatusMessageIsPredefined: Bool, userStatusStatus: String?, userStatusStatusIsUserDefined: Bool, account: String) {
 
-        let realm = try! Realm()
         do {
+            let realm = try Realm()
             try realm.write {
                 if let result = realm.objects(tableAccount.self).filter("account == %@", account).first {
                     result.userStatusClearAt = userStatusClearAt
@@ -463,10 +460,10 @@ extension NCManageDatabase {
 
     @objc func setAccountAlias(_ alias: String?) {
 
-        let realm = try! Realm()
         let alias = alias?.trimmingCharacters(in: .whitespacesAndNewlines)
 
         do {
+            let realm = try Realm()
             try realm.write {
                 if let result = realm.objects(tableAccount.self).filter("active == true").first {
                     if let alias = alias {

+ 65 - 46
iOSClient/Data/NCManageDatabase+Activity.swift

@@ -102,12 +102,11 @@ class tableActivitySubjectRich: Object {
 }
 
 extension NCManageDatabase {
-    
-    func addActivity(_ activities: [NKActivity], account: String) {
 
-        let realm = try! Realm()
+    func addActivity(_ activities: [NKActivity], account: String) {
 
         do {
+            let realm = try Realm()
             try realm.write {
 
                 for activity in activities {
@@ -195,64 +194,80 @@ extension NCManageDatabase {
 
     func getActivity(predicate: NSPredicate, filterFileId: String?) -> (all: [tableActivity], filter: [tableActivity]) {
 
-        let realm = try! Realm()
-
-        let results = realm.objects(tableActivity.self).filter(predicate).sorted(byKeyPath: "idActivity", ascending: false)
-        let allActivity = Array(results.map(tableActivity.init))
-        guard let filterFileId = filterFileId else {
-            return (all: allActivity, filter: allActivity)
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableActivity.self).filter(predicate).sorted(byKeyPath: "idActivity", ascending: false)
+            let allActivity = Array(results.map(tableActivity.init))
+            guard let filterFileId = filterFileId else {
+                return (all: allActivity, filter: allActivity)
+            }
+            // comments are loaded seperately, see NCManageDatabase.getComments
+            let filtered = allActivity.filter({ String($0.objectId) == filterFileId && $0.type != "comments" })
+            return (all: allActivity, filter: filtered)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        // comments are loaded seperately, see NCManageDatabase.getComments
-        let filtered = allActivity.filter({ String($0.objectId) == filterFileId && $0.type != "comments" })
-        return (all: allActivity, filter: filtered)
+        return([], [])
     }
 
     func getActivitySubjectRich(account: String, idActivity: Int, key: String) -> tableActivitySubjectRich? {
 
-        let realm = try! Realm()
-
-        let results = realm.objects(tableActivitySubjectRich.self).filter("account == %@ && idActivity == %d && key == %@", account, idActivity, key).first
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableActivitySubjectRich.self).filter("account == %@ && idActivity == %d && key == %@", account, idActivity, key).first
+            return results.map { tableActivitySubjectRich.init(value: $0) }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        return results.map { tableActivitySubjectRich.init(value: $0) }
+        return nil
     }
 
     func getActivitySubjectRich(account: String, idActivity: Int, id: String) -> tableActivitySubjectRich? {
 
-        let realm = try! Realm()
-
-        let results = realm.objects(tableActivitySubjectRich.self).filter("account == %@ && idActivity == %d && id == %@", account, idActivity, id)
-        var activitySubjectRich = results.first
-        if results.count == 2 {
-            for result in results {
-                if result.key == "newfile" {
-                    activitySubjectRich = result
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableActivitySubjectRich.self).filter("account == %@ && idActivity == %d && id == %@", account, idActivity, id)
+            var activitySubjectRich = results.first
+            if results.count == 2 {
+                for result in results {
+                    if result.key == "newfile" {
+                        activitySubjectRich = result
+                    }
                 }
             }
+            return activitySubjectRich.map { tableActivitySubjectRich.init(value: $0) }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return activitySubjectRich.map { tableActivitySubjectRich.init(value: $0) }
+        return nil
     }
 
     func getActivityPreview(account: String, idActivity: Int, orderKeysId: [String]) -> [tableActivityPreview] {
 
-        let realm = try! Realm()
-
         var results: [tableActivityPreview] = []
 
-        for id in orderKeysId {
-            if let result = realm.objects(tableActivityPreview.self).filter("account == %@ && idActivity == %d && fileId == %d", account, idActivity, Int(id) ?? 0).first {
-                results.append(result)
+        do {
+            let realm = try Realm()
+            for id in orderKeysId {
+                if let result = realm.objects(tableActivityPreview.self).filter("account == %@ && idActivity == %d && fileId == %d", account, idActivity, Int(id) ?? 0).first {
+                    results.append(result)
+                }
             }
+            return results
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return results
+        return []
     }
 
    func updateLatestActivityId(activityFirstKnown: Int, activityLastGiven: Int, account: String) {
-        let realm = try! Realm()
 
         do {
+            let realm = try Realm()
             try realm.write {
                 let newRecentActivity = tableActivityLatestId()
                 newRecentActivity.activityFirstKnown = activityFirstKnown
@@ -267,27 +282,28 @@ extension NCManageDatabase {
 
     func getLatestActivityId(account: String) -> tableActivityLatestId? {
 
-        let realm = try! Realm()
-        return realm.objects(tableActivityLatestId.self).filter("account == %@", account).first
+        do {
+            let realm = try Realm()
+            return realm.objects(tableActivityLatestId.self).filter("account == %@", account).first
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
+
+        return nil
     }
-    
+
     // MARK: -
     // MARK: Table Comments
 
     func addComments(_ comments: [NKComments], account: String, objectId: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
-
                 let results = realm.objects(tableComments.self).filter("account == %@ AND objectId == %@", account, objectId)
                 realm.delete(results)
-
                 for comment in comments {
-
                     let object = tableComments()
-
                     object.account = account
                     object.actorDisplayName = comment.actorDisplayName
                     object.actorId = comment.actorId
@@ -300,7 +316,6 @@ extension NCManageDatabase {
                     object.objectType = comment.objectType
                     object.path = comment.path
                     object.verb = comment.verb
-
                     realm.add(object, update: .all)
                 }
             }
@@ -311,10 +326,14 @@ extension NCManageDatabase {
 
     func getComments(account: String, objectId: String) -> [tableComments] {
 
-        let realm = try! Realm()
-
-        let results = realm.objects(tableComments.self).filter("account == %@ AND objectId == %@", account, objectId).sorted(byKeyPath: "creationDateTime", ascending: false)
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableComments.self).filter("account == %@ AND objectId == %@", account, objectId).sorted(byKeyPath: "creationDateTime", ascending: false)
+            return Array(results.map(tableComments.init))
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        return Array(results.map(tableComments.init))
+        return []
     }
 }

+ 24 - 24
iOSClient/Data/NCManageDatabase+Avatar.swift

@@ -41,19 +41,14 @@ extension NCManageDatabase {
 
     func addAvatar(fileName: String, etag: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
-
-                // Add new
                 let addObject = tableAvatar()
-
                 addObject.date = NSDate()
                 addObject.etag = etag
                 addObject.fileName = fileName
                 addObject.loaded = true
-
                 realm.add(addObject, update: .all)
             }
         } catch let error {
@@ -63,22 +58,22 @@ extension NCManageDatabase {
 
     func getTableAvatar(fileName: String) -> tableAvatar? {
 
-        let realm = try! Realm()
-
-        guard let result = realm.objects(tableAvatar.self).filter("fileName == %@", fileName).first else {
-            return nil
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableAvatar.self).filter("fileName == %@", fileName).first else { return nil }
+            return tableAvatar.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return tableAvatar.init(value: result)
+        return nil
     }
 
     func clearAllAvatarLoaded() {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
-
                 let results = realm.objects(tableAvatar.self)
                 for result in results {
                     result.loaded = false
@@ -93,11 +88,11 @@ extension NCManageDatabase {
     @discardableResult
     func setAvatarLoaded(fileName: String) -> UIImage? {
 
-        let realm = try! Realm()
         let fileNameLocalPath = String(CCUtility.getDirectoryUserData()) + "/" + fileName
         var image: UIImage?
 
         do {
+            let realm = try Realm()
             try realm.write {
                 if let result = realm.objects(tableAvatar.self).filter("fileName == %@", fileName).first {
                     if let imageAvatar = UIImage(contentsOfFile: fileNameLocalPath) {
@@ -117,18 +112,23 @@ extension NCManageDatabase {
 
     func getImageAvatarLoaded(fileName: String) -> UIImage? {
 
-        let realm = try! Realm()
         let fileNameLocalPath = String(CCUtility.getDirectoryUserData()) + "/" + fileName
 
-        let result = realm.objects(tableAvatar.self).filter("fileName == %@", fileName).first
-        if result == nil {
-            NCUtilityFileSystem.shared.deleteFile(filePath: fileNameLocalPath)
-            return nil
-        } else if result?.loaded == false {
-            return nil
+        do {
+            let realm = try Realm()
+            let result = realm.objects(tableAvatar.self).filter("fileName == %@", fileName).first
+            if result == nil {
+                NCUtilityFileSystem.shared.deleteFile(filePath: fileNameLocalPath)
+                return nil
+            } else if result?.loaded == false {
+                return nil
+            }
+            return UIImage(contentsOfFile: fileNameLocalPath)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return UIImage(contentsOfFile: fileNameLocalPath)
+        NCUtilityFileSystem.shared.deleteFile(filePath: fileNameLocalPath)
+        return nil
     }
-
 }

+ 17 - 14
iOSClient/Data/NCManageDatabase+Capabilities.swift

@@ -40,15 +40,12 @@ extension NCManageDatabase {
 
     func addCapabilitiesJSon(_ data: Data, account: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let addObject = tableCapabilities()
-
                 addObject.account = account
                 addObject.jsondata = data
-
                 realm.add(addObject, update: .all)
             }
         } catch let error {
@@ -58,28 +55,35 @@ extension NCManageDatabase {
 
     func getCapabilities(account: String) -> Data? {
 
-        let realm = try! Realm()
-
-        guard let result = realm.objects(tableCapabilities.self).filter("account == %@", account).first else {
-            return nil
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableCapabilities.self).filter("account == %@", account).first else { return nil }
+            return result.jsondata
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return result.jsondata
+        return nil
     }
 
     func setCapabilities(account: String, data: Data? = nil) {
 
-        let realm = try! Realm()
         let json: JSON?
 
         if let data = data {
             json = JSON(data)
         } else {
-            guard let result = realm.objects(tableCapabilities.self).filter("account == %@", account).first,
-                  let data = result.jsondata else {
+            do {
+                let realm = try Realm()
+                guard let result = realm.objects(tableCapabilities.self).filter("account == %@", account).first,
+                      let data = result.jsondata else {
+                    return
+                }
+                json = JSON(data)
+            } catch let error as NSError {
+                NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
                 return
             }
-            json = JSON(data)
         }
 
         guard let json = json else { return }
@@ -106,7 +110,6 @@ extension NCManageDatabase {
         NCGlobal.shared.capabilityE2EEEnabled = json["ocs", "data", "capabilities", "end-to-end-encryption", "enabled"].boolValue
         NCGlobal.shared.capabilityE2EEApiVersion = json["ocs", "data", "capabilities", "end-to-end-encryption", "api-version"].stringValue
 
-
         NCGlobal.shared.capabilityRichdocumentsMimetypes.removeAll()
         let mimetypes = json["ocs", "data", "capabilities", "richdocuments", "mimetypes"].arrayValue
         for mimetype in mimetypes {

+ 24 - 24
iOSClient/Data/NCManageDatabase+DashboardWidget.swift

@@ -51,42 +51,47 @@ class tableDashboardWidgetButton: Object {
 extension NCManageDatabase {
 
     func getDashboardWidget(account: String, id: String) -> (tableDashboardWidget?, [tableDashboardWidgetButton]?) {
-     
-        let realm = try! Realm()
-        guard let resultDashboard = realm.objects(tableDashboardWidget.self).filter("account == %@ AND id == %@", account, id).first else {
-            return (nil, nil)
+
+        do {
+            let realm = try Realm()
+            guard let resultDashboard = realm.objects(tableDashboardWidget.self).filter("account == %@ AND id == %@", account, id).first else { return (nil, nil) }
+            let resultsButton = realm.objects(tableDashboardWidgetButton.self).filter("account == %@ AND id == %@", account, id).sorted(byKeyPath: "type", ascending: true)
+            return (tableDashboardWidget.init(value: resultDashboard), Array(resultsButton.map { tableDashboardWidgetButton.init(value: $0) }))
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
-        let resultsButton = realm.objects(tableDashboardWidgetButton.self).filter("account == %@ AND id == %@", account, id).sorted(byKeyPath: "type", ascending: true)
-        
-        return (tableDashboardWidget.init(value: resultDashboard), Array(resultsButton.map { tableDashboardWidgetButton.init(value: $0) }))
+
+        return (nil, nil)
     }
 
     func getDashboardWidgetApplications(account: String) -> [tableDashboardWidget] {
 
-        let realm = try! Realm()
-        let sortProperties = [SortDescriptor(keyPath: "order", ascending: true), SortDescriptor(keyPath: "title", ascending: true)]
-        let results = realm.objects(tableDashboardWidget.self).filter("account == %@", account).sorted(by: sortProperties)
+        do {
+            let realm = try Realm()
+            let sortProperties = [SortDescriptor(keyPath: "order", ascending: true), SortDescriptor(keyPath: "title", ascending: true)]
+            let results = realm.objects(tableDashboardWidget.self).filter("account == %@", account).sorted(by: sortProperties)
+            return Array(results.map { tableDashboardWidget.init(value: $0) })
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        return Array(results.map { tableDashboardWidget.init(value: $0) })
+        return []
     }
-    
+
     func addDashboardWidget(account: String, dashboardWidgets: [NCCDashboardWidget]) {
-        
-        let realm = try! Realm()
 
         do {
+            let realm = try Realm()
             try realm.write {
-                
+
                 let resultDashboard = realm.objects(tableDashboardWidget.self).filter("account == %@", account)
                 realm.delete(resultDashboard)
-                
+
                 let resultDashboardButton = realm.objects(tableDashboardWidgetButton.self).filter("account == %@", account)
                 realm.delete(resultDashboardButton)
-                
+
                 for widget in dashboardWidgets {
-                    
                     let addObject = tableDashboardWidget()
-                    
                     addObject.index = account + " " + widget.id
                     addObject.account = account
                     addObject.id = widget.id
@@ -96,23 +101,18 @@ extension NCManageDatabase {
                     addObject.iconUrl = widget.iconUrl
                     addObject.widgetUrl = widget.widgetUrl
                     addObject.itemIconsRound = widget.itemIconsRound
-
                     if let buttons = widget.button {
                         for button in buttons {
-                            
                             let addObject = tableDashboardWidgetButton()
-                            
                             addObject.account = account
                             addObject.id = widget.id
                             addObject.type = button.type
                             addObject.text = button.text
                             addObject.link = button.link
                             addObject.index = account + " " + widget.id + " " + button.type
-                            
                             realm.add(addObject, update: .all)
                         }
                     }
-                    
                     realm.add(addObject, update: .all)
                 }
             }

+ 32 - 46
iOSClient/Data/NCManageDatabase+Directory.swift

@@ -48,19 +48,16 @@ extension NCManageDatabase {
 
     func addDirectory(encrypted: Bool, favorite: Bool, ocId: String, fileId: String, etag: String? = nil, permissions: String? = nil, serverUrl: String, account: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 var addObject = tableDirectory()
                 let result = realm.objects(tableDirectory.self).filter("ocId == %@", ocId).first
-
                 if result != nil {
                     addObject = result!
                 } else {
                     addObject.ocId = ocId
                 }
-
                 addObject.account = account
                 addObject.e2eEncrypted = encrypted
                 addObject.favorite = favorite
@@ -72,7 +69,6 @@ extension NCManageDatabase {
                     addObject.permissions = permissions
                 }
                 addObject.serverUrl = serverUrl
-
                 realm.add(addObject, update: .all)
             }
         } catch let error {
@@ -82,19 +78,13 @@ extension NCManageDatabase {
 
     func deleteDirectoryAndSubDirectory(serverUrl: String, account: String) {
 
-        let realm = try! Realm()
-
-        let results = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl BEGINSWITH %@", account, serverUrl)
-
-        // Delete table Metadata & LocalFile
-        for result in results {
-
-            self.deleteMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", result.account, result.serverUrl))
-            self.deleteLocalFile(predicate: NSPredicate(format: "ocId == %@", result.ocId))
-        }
-
-        // Delete table Dirrectory
         do {
+            let realm = try Realm()
+            let results = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl BEGINSWITH %@", account, serverUrl)
+            for result in results {
+                self.deleteMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", result.account, result.serverUrl))
+                self.deleteLocalFile(predicate: NSPredicate(format: "ocId == %@", result.ocId))
+            }
             try realm.write {
                 realm.delete(results)
             }
@@ -105,19 +95,12 @@ extension NCManageDatabase {
 
     func setDirectory(serverUrl: String, serverUrlTo: String? = nil, etag: String? = nil, ocId: String? = nil, fileId: String? = nil, encrypted: Bool, richWorkspace: String? = nil, account: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
-
-                guard let result = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first else {
-                    return
-                }
-
+                guard let result = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first else { return }
                 let directory = tableDirectory.init(value: result)
-
                 realm.delete(result)
-
                 directory.e2eEncrypted = encrypted
                 if let etag = etag {
                     directory.etag = etag
@@ -134,7 +117,6 @@ extension NCManageDatabase {
                 if let richWorkspace = richWorkspace {
                     directory.richWorkspace = richWorkspace
                 }
-
                 realm.add(directory, update: .all)
             }
         } catch let error {
@@ -144,33 +126,38 @@ extension NCManageDatabase {
 
     func getTableDirectory(predicate: NSPredicate) -> tableDirectory? {
 
-        let realm = try! Realm()
-
-        guard let result = realm.objects(tableDirectory.self).filter(predicate).first else {
-            return nil
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableDirectory.self).filter(predicate).first else { return nil }
+            return tableDirectory.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return tableDirectory.init(value: result)
+        return nil
     }
 
     func getTablesDirectory(predicate: NSPredicate, sorted: String, ascending: Bool) -> [tableDirectory]? {
 
-        let realm = try! Realm()
-
-        let results = realm.objects(tableDirectory.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
-
-        if results.count > 0 {
-            return Array(results.map { tableDirectory.init(value: $0) })
-        } else {
-            return nil
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableDirectory.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
+            if results.isEmpty {
+                return nil
+            } else {
+                return Array(results.map { tableDirectory.init(value: $0) })
+            }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
+
+        return nil
     }
 
     func renameDirectory(ocId: String, serverUrl: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let result = realm.objects(tableDirectory.self).filter("ocId == %@", ocId).first
                 result?.serverUrl = serverUrl
@@ -182,9 +169,8 @@ extension NCManageDatabase {
 
     func setDirectory(serverUrl: String, offline: Bool, account: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let result = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first
                 result?.offline = offline
@@ -197,10 +183,10 @@ extension NCManageDatabase {
     @discardableResult
     func setDirectory(serverUrl: String, richWorkspace: String?, account: String) -> tableDirectory? {
 
-        let realm = try! Realm()
         var result: tableDirectory?
 
         do {
+            let realm = try Realm()
             try realm.write {
                 result = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first
                 result?.richWorkspace = richWorkspace
@@ -219,10 +205,10 @@ extension NCManageDatabase {
     @discardableResult
     func setDirectory(serverUrl: String, colorFolder: String?, account: String) -> tableDirectory? {
 
-        let realm = try! Realm()
         var result: tableDirectory?
 
         do {
+            let realm = try Realm()
             try realm.write {
                 result = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first
                 result?.colorFolder = colorFolder

+ 63 - 74
iOSClient/Data/NCManageDatabase+E2EE.swift

@@ -76,9 +76,8 @@ extension NCManageDatabase {
 
     @objc func addE2eEncryption(_ e2e: tableE2eEncryption) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 realm.add(e2e, update: .all)
             }
@@ -89,11 +88,9 @@ extension NCManageDatabase {
 
     @objc func deleteE2eEncryption(predicate: NSPredicate) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
-
                 let results = realm.objects(tableE2eEncryption.self).filter(predicate)
                 realm.delete(results)
             }
@@ -104,61 +101,52 @@ extension NCManageDatabase {
 
     @objc func getE2eEncryption(predicate: NSPredicate) -> tableE2eEncryption? {
 
-        let realm = try! Realm()
-
-        guard let result = realm.objects(tableE2eEncryption.self).filter(predicate).sorted(byKeyPath: "metadataKeyIndex", ascending: false).first else {
-            return nil
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableE2eEncryption.self).filter(predicate).sorted(byKeyPath: "metadataKeyIndex", ascending: false).first else { return nil }
+            return tableE2eEncryption.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return tableE2eEncryption.init(value: result)
+        return nil
     }
 
     @objc func getE2eEncryptions(predicate: NSPredicate) -> [tableE2eEncryption]? {
 
-        guard self.getActiveAccount() != nil else {
-            return nil
-        }
-
-        let realm = try! Realm()
-
-        let results: Results<tableE2eEncryption>
+        guard self.getActiveAccount() != nil else { return nil }
 
-        results = realm.objects(tableE2eEncryption.self).filter(predicate)
-
-        if results.count > 0 {
-            return Array(results.map { tableE2eEncryption.init(value: $0) })
-        } else {
-            return nil
+        do {
+            let realm = try Realm()
+            let results: Results<tableE2eEncryption>
+            results = realm.objects(tableE2eEncryption.self).filter(predicate)
+            if results.isEmpty {
+                return nil
+            } else {
+                return Array(results.map { tableE2eEncryption.init(value: $0) })
+            }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
+
+        return nil
     }
 
     @objc func renameFileE2eEncryption(serverUrl: String, fileNameIdentifier: String, newFileName: String, newFileNamePath: String) {
 
-        guard let activeAccount = self.getActiveAccount() else {
-            return
-        }
-
-        let realm = try! Realm()
-
-        realm.beginWrite()
-
-        guard let result = realm.objects(tableE2eEncryption.self).filter("account == %@ AND serverUrl == %@ AND fileNameIdentifier == %@", activeAccount.account, serverUrl, fileNameIdentifier).first else {
-            realm.cancelWrite()
-            return
-        }
-
-        let object = tableE2eEncryption.init(value: result)
-
-        realm.delete(result)
-
-        object.fileName = newFileName
-        object.fileNamePath = newFileNamePath
-
-        realm.add(object)
+        guard let activeAccount = self.getActiveAccount() else { return }
 
         do {
-            try realm.commitWrite()
-        } catch let error {
+            let realm = try Realm()
+            try realm.write {
+                guard let result = realm.objects(tableE2eEncryption.self).filter("account == %@ AND serverUrl == %@ AND fileNameIdentifier == %@", activeAccount.account, serverUrl, fileNameIdentifier).first else { return }
+                let object = tableE2eEncryption.init(value: result)
+                realm.delete(result)
+                object.fileName = newFileName
+                object.fileNamePath = newFileNamePath
+                realm.add(object)
+            }
+        } catch let error as NSError {
             NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
     }
@@ -168,41 +156,44 @@ extension NCManageDatabase {
 
     @objc func getE2ETokenLock(account: String, serverUrl: String) -> tableE2eEncryptionLock? {
 
-        let realm = try! Realm()
-
-        guard let result = realm.objects(tableE2eEncryptionLock.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first else {
-            return nil
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableE2eEncryptionLock.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first else { return nil }
+            return tableE2eEncryptionLock.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return tableE2eEncryptionLock.init(value: result)
+        return nil
     }
 
     @objc func getE2EAllTokenLock(account: String) -> [tableE2eEncryptionLock] {
 
-        let realm = try! Realm()
-
-        let results = realm.objects(tableE2eEncryptionLock.self).filter("account == %@", account)
-
-        if results.count > 0 {
-            return Array(results.map { tableE2eEncryptionLock.init(value: $0) })
-        } else {
-            return []
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableE2eEncryptionLock.self).filter("account == %@", account)
+            if results.isEmpty {
+                return []
+            } else {
+                return Array(results.map { tableE2eEncryptionLock.init(value: $0) })
+            }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
+
+        return []
     }
 
     @objc func setE2ETokenLock(account: String, serverUrl: String, fileId: String, e2eToken: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let addObject = tableE2eEncryptionLock()
-
                 addObject.account = account
                 addObject.fileId = fileId
                 addObject.serverUrl = serverUrl
                 addObject.e2eToken = e2eToken
-
                 realm.add(addObject, update: .all)
             }
         } catch let error {
@@ -212,9 +203,8 @@ extension NCManageDatabase {
 
     @objc func deleteE2ETokenLock(account: String, serverUrl: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 if let result = realm.objects(tableE2eEncryptionLock.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first {
                     realm.delete(result)
@@ -230,28 +220,27 @@ extension NCManageDatabase {
 
     func getE2eMetadata(account: String, serverUrl: String) -> tableE2eMetadata? {
 
-        let realm = try! Realm()
-
-        guard let result = realm.objects(tableE2eMetadata.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first else {
-            return nil
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableE2eMetadata.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first else { return nil }
+            return tableE2eMetadata.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return tableE2eMetadata.init(value: result)
+        return nil
     }
 
     func setE2eMetadata(account: String, serverUrl: String, metadataKey: String, version: Double) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let addObject = tableE2eMetadata()
-
                 addObject.account = account
                 addObject.metadataKey = metadataKey
                 addObject.serverUrl = serverUrl
                 addObject.version = version
-
                 realm.add(addObject, update: .all)
             }
         } catch let error {

+ 1 - 5
iOSClient/Data/NCManageDatabase+Groupfolders.swift

@@ -57,9 +57,8 @@ extension NCManageDatabase {
 
     func addGroupfolders(account: String, groupfolders: [NKGroupfolders]) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
 
                 let tableGroupfolders = realm.objects(TableGroupfolders.self).filter("account == %@", account)
@@ -69,9 +68,7 @@ extension NCManageDatabase {
                 realm.delete(tableGroupfoldersGroups)
 
                 for groupfolder in groupfolders {
-
                     let obj = TableGroupfolders()
-
                     obj.account = account
                     obj.acl = groupfolder.acl
                     for group in groupfolder.groups ?? [:] {
@@ -83,7 +80,6 @@ extension NCManageDatabase {
                     obj.mountPoint = groupfolder.mountPoint
                     obj.quota = groupfolder.quota
                     obj.size = groupfolder.size
-
                     realm.add(obj)
                 }
             }

+ 16 - 13
iOSClient/Data/NCManageDatabase+LayoutForView.swift

@@ -44,15 +44,13 @@ extension NCManageDatabase {
     @discardableResult
     func setLayoutForView(account: String, key: String, serverUrl: String, layout: String? = nil, sort: String? = nil, ascending: Bool? = nil, groupBy: String? = nil, directoryOnTop: Bool? = nil, titleButtonHeader: String? = nil, itemForLine: Int? = nil) -> NCDBLayoutForView? {
 
-        let realm = try! Realm()
-
         var keyStore = key
         if !serverUrl.isEmpty { keyStore = serverUrl}
         let index = account + " " + keyStore
-
         var addObject = NCDBLayoutForView()
 
         do {
+            let realm = try Realm()
             try realm.write {
                 if let result = realm.objects(NCDBLayoutForView.self).filter("index == %@", index).first {
                     addObject = result
@@ -91,16 +89,16 @@ extension NCManageDatabase {
             NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return NCDBLayoutForView.init(value: addObject)
+        return NCDBLayoutForView(value: addObject)
     }
 
     @discardableResult
     func setLayoutForView(layoutForView: NCDBLayoutForView) -> NCDBLayoutForView? {
 
-        let realm = try! Realm()
-        let result = NCDBLayoutForView.init(value: layoutForView)
+        let result = NCDBLayoutForView(value: layoutForView)
 
         do {
+            let realm = try Realm()
             try realm.write {
                 realm.add(result, update: .all)
             }
@@ -108,21 +106,26 @@ extension NCManageDatabase {
             NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
             return nil
         }
-        return NCDBLayoutForView.init(value: result)
+        return NCDBLayoutForView(value: result)
     }
 
     func getLayoutForView(account: String, key: String, serverUrl: String) -> NCDBLayoutForView? {
 
-        let realm = try! Realm()
-
         var keyStore = key
         if !serverUrl.isEmpty { keyStore = serverUrl}
         let index = account + " " + keyStore
 
-        if let result = realm.objects(NCDBLayoutForView.self).filter("index == %@", index).first {
-            return NCDBLayoutForView.init(value: result)
-        } else {
-            return setLayoutForView(account: account, key: key, serverUrl: serverUrl)
+        do {
+            let realm = try Realm()
+            if let result = realm.objects(NCDBLayoutForView.self).filter("index == %@", index).first {
+                return NCDBLayoutForView(value: result)
+            } else {
+                return setLayoutForView(account: account, key: key, serverUrl: serverUrl)
+            }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
+
+        return setLayoutForView(account: account, key: key, serverUrl: serverUrl)
     }
 }

+ 198 - 173
iOSClient/Data/NCManageDatabase+Metadata.swift

@@ -125,7 +125,7 @@ extension tableMetadata {
         }
         return true
     }
-    
+
     var isPrintable: Bool {
         if isDocumentViewableOnly {
             return false
@@ -206,10 +206,8 @@ extension tableMetadata {
         if isDocumentViewableOnly {
             return false
         }
-
         let editors = NCUtility.shared.isDirectEditing(account: account, contentType: contentType)
         let isRichDocument = NCUtility.shared.isRichDocument(self)
-
         return classFile == NKCommon.TypeClassFile.document.rawValue && editors.contains(NCGlobal.shared.editorText) && ((editors.contains(NCGlobal.shared.editorOnlyoffice) || isRichDocument))
     }
 
@@ -234,7 +232,7 @@ extension tableMetadata {
         return !lock || (lockOwner == user && lockOwnerType == 0)
     }
 
-    /// Return if is sharable (temp)
+    // Return if is sharable (temp)
     // TODO: modifify for E2EE 2.0
     func isSharable() -> Bool {
         guard NCGlobal.shared.capabilityFileSharingApiEnabled else { return false }
@@ -309,7 +307,7 @@ extension NCManageDatabase {
         }
         metadata.size = file.size
         metadata.classFile = file.classFile
-        //FIXME: iOS 12.0,* don't detect UTI text/markdown, text/x-markdown
+        // iOS 12.0,* don't detect UTI text/markdown, text/x-markdown
         if (metadata.contentType == "text/markdown" || metadata.contentType == "text/x-markdown") && metadata.classFile == NKCommon.TypeClassFile.unknow.rawValue {
             metadata.classFile = NKCommon.TypeClassFile.document.rawValue
         }
@@ -340,7 +338,7 @@ extension NCManageDatabase {
 
         var counter: Int = 0
         var isDirectoryE2EE: Bool = false
-        let listServerUrl = ThreadSafeDictionary<String,Bool>()
+        let listServerUrl = ThreadSafeDictionary<String, Bool>()
 
         var metadataFolder = tableMetadata()
         var metadataFolders: [tableMetadata] = []
@@ -378,10 +376,10 @@ extension NCManageDatabase {
         for index in metadatas.indices {
             let metadata = metadatas[index]
             if index < metadatas.count - 1,
-                metadata.fileNoExtension == metadatas[index+1].fileNoExtension,
-                ((metadata.classFile == NKCommon.TypeClassFile.image.rawValue && metadatas[index+1].classFile == NKCommon.TypeClassFile.video.rawValue) || (metadata.classFile == NKCommon.TypeClassFile.video.rawValue && metadatas[index+1].classFile == NKCommon.TypeClassFile.image.rawValue)){
+                metadata.fileNoExtension == metadatas[index + 1].fileNoExtension,
+                ((metadata.classFile == NKCommon.TypeClassFile.image.rawValue && metadatas[index + 1].classFile == NKCommon.TypeClassFile.video.rawValue) || (metadata.classFile == NKCommon.TypeClassFile.video.rawValue && metadatas[index + 1].classFile == NKCommon.TypeClassFile.image.rawValue)) {
                 metadata.livePhoto = true
-                metadatas[index+1].livePhoto = true
+                metadatas[index + 1].livePhoto = true
             }
             metadataOutput.append(metadata)
         }
@@ -405,7 +403,7 @@ extension NCManageDatabase {
             metadata.contentType = mimeType
             metadata.iconName = iconName
             metadata.classFile = classFile
-            //FIXME: iOS 12.0,* don't detect UTI text/markdown, text/x-markdown
+            // iOS 12.0,* don't detect UTI text/markdown, text/x-markdown
             if classFile == NKCommon.TypeClassFile.unknow.rawValue && (mimeType == "text/x-markdown" || mimeType == "text/markdown") {
                 metadata.iconName = NKCommon.TypeIconFile.txt.rawValue
                 metadata.classFile = NKCommon.TypeClassFile.document.rawValue
@@ -436,7 +434,7 @@ extension NCManageDatabase {
         metadata.urlBase = urlBase
         metadata.user = user
         metadata.userId = userId
-        
+
         if !metadata.urlBase.isEmpty, metadata.serverUrl.hasPrefix(metadata.urlBase) {
             metadata.path = String(metadata.serverUrl.dropFirst(metadata.urlBase.count)) + "/"
         }
@@ -447,10 +445,10 @@ extension NCManageDatabase {
     @discardableResult
     func addMetadata(_ metadata: tableMetadata) -> tableMetadata? {
 
-        let realm = try! Realm()
         let result = tableMetadata.init(value: metadata)
 
         do {
+            let realm = try Realm()
             try realm.write {
                 realm.add(result, update: .all)
             }
@@ -463,9 +461,8 @@ extension NCManageDatabase {
 
     func addMetadatas(_ metadatas: [tableMetadata]) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 for metadata in metadatas {
                     realm.add(metadata, update: .all)
@@ -478,9 +475,8 @@ extension NCManageDatabase {
 
     func deleteMetadata(predicate: NSPredicate) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let results = realm.objects(tableMetadata.self).filter(predicate)
                 realm.delete(results)
@@ -492,9 +488,8 @@ extension NCManageDatabase {
 
     func moveMetadata(ocId: String, serverUrlTo: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 if let result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first {
                     result.serverUrl = serverUrlTo
@@ -507,9 +502,8 @@ extension NCManageDatabase {
 
     func renameMetadata(fileNameTo: String, ocId: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 if let result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first {
                     let resultsType = NextcloudKit.shared.nkCommonInstance.getInternalType(fileName: fileNameTo, mimeType: "", directory: result.directory)
@@ -528,7 +522,6 @@ extension NCManageDatabase {
     @discardableResult
     func updateMetadatas(_ metadatas: [tableMetadata], metadatasResult: [tableMetadata], addCompareLivePhoto: Bool = true, addExistsInLocal: Bool = false, addCompareEtagLocal: Bool = false, addDirectorySynchronized: Bool = false) -> (metadatasUpdate: [tableMetadata], metadatasLocalUpdate: [tableMetadata], metadatasDelete: [tableMetadata]) {
 
-        let realm = try! Realm()
         var ocIdsUdate: [String] = []
         var ocIdsLocalUdate: [String] = []
         var metadatasDelete: [tableMetadata] = []
@@ -536,6 +529,7 @@ extension NCManageDatabase {
         var metadatasLocalUpdate: [tableMetadata] = []
 
         do {
+            let realm = try Realm()
             try realm.write {
 
                 // DELETE
@@ -599,30 +593,31 @@ extension NCManageDatabase {
                     }
                 }
             }
-        } catch let error {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
-        }
 
-        for ocId in ocIdsUdate {
-            if let result = realm.objects(tableMetadata.self).filter(NSPredicate(format: "ocId == %@", ocId)).first {
-                metadatasUpdate.append(tableMetadata.init(value: result))
+            for ocId in ocIdsUdate {
+                if let result = realm.objects(tableMetadata.self).filter(NSPredicate(format: "ocId == %@", ocId)).first {
+                    metadatasUpdate.append(tableMetadata.init(value: result))
+                }
             }
-        }
 
-        for ocId in ocIdsLocalUdate {
-            if let result = realm.objects(tableMetadata.self).filter(NSPredicate(format: "ocId == %@", ocId)).first {
-                metadatasLocalUpdate.append(tableMetadata.init(value: result))
+            for ocId in ocIdsLocalUdate {
+                if let result = realm.objects(tableMetadata.self).filter(NSPredicate(format: "ocId == %@", ocId)).first {
+                    metadatasLocalUpdate.append(tableMetadata.init(value: result))
+                }
             }
+
+            return (metadatasUpdate, metadatasLocalUpdate, metadatasDelete)
+        } catch let error {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return (metadatasUpdate, metadatasLocalUpdate, metadatasDelete)
+        return ([], [], [])
     }
 
     func setMetadataSession(ocId: String, newFileName: String? = nil, session: String? = nil, sessionError: String? = nil, sessionSelector: String? = nil, sessionTaskIdentifier: Int? = nil, status: Int? = nil, etag: String? = nil) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first
                 if let newFileName = newFileName {
@@ -656,10 +651,10 @@ extension NCManageDatabase {
     @discardableResult
     func setMetadataStatus(ocId: String, status: Int) -> tableMetadata? {
 
-        let realm = try! Realm()
         var result: tableMetadata?
 
         do {
+            let realm = try Realm()
             try realm.write {
                 result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first
                 result?.status = status
@@ -677,13 +672,12 @@ extension NCManageDatabase {
 
     func setMetadataEtagResource(ocId: String, etagResource: String?) {
 
-        let realm = try! Realm()
-        var result: tableMetadata?
         guard let etagResource = etagResource else { return }
 
         do {
+            let realm = try Realm()
             try realm.write {
-                result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first
+                let result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first
                 result?.etagResource = etagResource
             }
         } catch let error {
@@ -693,9 +687,8 @@ extension NCManageDatabase {
 
     func setMetadataFavorite(ocId: String, favorite: Bool) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first
                 result?.favorite = favorite
@@ -707,9 +700,8 @@ extension NCManageDatabase {
 
     func updateMetadatasFavorite(account: String, metadatas: [tableMetadata]) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let results = realm.objects(tableMetadata.self).filter("account == %@ AND favorite == true", account)
                 for result in results {
@@ -726,9 +718,8 @@ extension NCManageDatabase {
 
     func setMetadataEncrypted(ocId: String, encrypted: Bool) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first
                 result?.e2eEncrypted = encrypted
@@ -740,9 +731,8 @@ extension NCManageDatabase {
 
     func setMetadataFileNameView(serverUrl: String, fileName: String, newFileNameView: String, account: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let result = realm.objects(tableMetadata.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@", account, serverUrl, fileName).first
                 result?.fileNameView = newFileNameView
@@ -754,144 +744,159 @@ extension NCManageDatabase {
 
     func getMetadata(predicate: NSPredicate) -> tableMetadata? {
 
-        let realm = try! Realm()
-        realm.refresh()
-
-        guard let result = realm.objects(tableMetadata.self).filter(predicate).first else {
-            return nil
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableMetadata.self).filter(predicate).first else { return nil }
+            return tableMetadata.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return tableMetadata.init(value: result)
+        return nil
     }
 
     func getMetadata(predicate: NSPredicate, sorted: String, ascending: Bool) -> tableMetadata? {
 
-        let realm = try! Realm()
-        realm.refresh()
-
-        guard let result = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending).first else {
-            return nil
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending).first else { return nil }
+            return tableMetadata.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return tableMetadata.init(value: result)
+        return nil
     }
 
     func getMetadatasViewer(predicate: NSPredicate, sorted: String, ascending: Bool) -> [tableMetadata]? {
 
-        let realm = try! Realm()
-        realm.refresh()
-
         let results: Results<tableMetadata>
         var finals: [tableMetadata] = []
 
-        if (tableMetadata().objectSchema.properties.contains { $0.name == sorted }) {
-            results = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
-        } else {
-            results = realm.objects(tableMetadata.self).filter(predicate)
-        }
+        do {
+            let realm = try Realm()
+            if (tableMetadata().objectSchema.properties.contains { $0.name == sorted }) {
+                results = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
+            } else {
+                results = realm.objects(tableMetadata.self).filter(predicate)
+            }
 
-        // For Live Photo
-        var fileNameImages: [String] = []
-        let filtered = results.filter { $0.classFile.contains(NKCommon.TypeClassFile.image.rawValue) }
-        filtered.forEach { print($0)
-            let fileName = ($0.fileNameView as NSString).deletingPathExtension
-            fileNameImages.append(fileName)
-        }
+            // For Live Photo
+            var fileNameImages: [String] = []
+            let filtered = results.filter { $0.classFile.contains(NKCommon.TypeClassFile.image.rawValue) }
+            filtered.forEach { print($0)
+                let fileName = ($0.fileNameView as NSString).deletingPathExtension
+                fileNameImages.append(fileName)
+            }
 
-        for result in results {
+            for result in results {
 
-            let ext = (result.fileNameView as NSString).pathExtension.uppercased()
-            let fileName = (result.fileNameView as NSString).deletingPathExtension
+                let ext = (result.fileNameView as NSString).pathExtension.uppercased()
+                let fileName = (result.fileNameView as NSString).deletingPathExtension
 
-            if !(ext == "MOV" && fileNameImages.contains(fileName)) {
-                finals.append(result)
+                if !(ext == "MOV" && fileNameImages.contains(fileName)) {
+                    finals.append(result)
+                }
             }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        if finals.count > 0 {
-            return Array(finals.map { tableMetadata.init(value: $0) })
-        } else {
+        if finals.isEmpty {
             return nil
+        } else {
+            return Array(finals.map { tableMetadata.init(value: $0) })
         }
     }
 
     func getMetadatas(predicate: NSPredicate) -> [tableMetadata] {
 
-        let realm = try! Realm()
-        realm.refresh()
-
-        let results = realm.objects(tableMetadata.self).filter(predicate)
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableMetadata.self).filter(predicate)
+            return Array(results.map { tableMetadata.init(value: $0) })
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        return Array(results.map { tableMetadata.init(value: $0) })
+        return []
     }
 
     func getAdvancedMetadatas(predicate: NSPredicate, page: Int = 0, limit: Int = 0, sorted: String, ascending: Bool) -> [tableMetadata] {
 
-        let realm = try! Realm()
-        realm.refresh()
         var metadatas: [tableMetadata] = []
 
-        let results = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
-
-        if results.count > 0 {
-            if page == 0 || limit == 0 {
-                return Array(results.map { tableMetadata.init(value: $0) })
-            } else {
-
-                let nFrom = (page - 1) * limit
-                let nTo = nFrom + (limit - 1)
-
-                for n in nFrom...nTo {
-                    if n == results.count {
-                        break
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
+            if !results.isEmpty {
+                if page == 0 || limit == 0 {
+                    return Array(results.map { tableMetadata.init(value: $0) })
+                } else {
+                    let nFrom = (page - 1) * limit
+                    let nTo = nFrom + (limit - 1)
+                    for n in nFrom...nTo {
+                        if n == results.count {
+                            break
+                        }
+                        metadatas.append(tableMetadata.init(value: results[n]))
                     }
-                    metadatas.append(tableMetadata.init(value: results[n]))
                 }
             }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
+
         return metadatas
     }
 
     func getMetadataAtIndex(predicate: NSPredicate, sorted: String, ascending: Bool, index: Int) -> tableMetadata? {
 
-        let realm = try! Realm()
-        realm.refresh()
-
-        let results = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
-
-        if results.count > 0  && results.count > index {
-            return tableMetadata.init(value: results[index])
-        } else {
-            return nil
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
+            if results.isEmpty {
+                return nil
+            } else {
+                return tableMetadata.init(value: results[index])
+            }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
+
+        return nil
     }
 
     func getMetadataFromOcId(_ ocId: String?) -> tableMetadata? {
 
-        let realm = try! Realm()
-        realm.refresh()
-
-        guard let ocId = ocId else { return nil }
-        guard let result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first else { return nil }
+        do {
+            let realm = try Realm()
+            guard let ocId = ocId else { return nil }
+            guard let result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first else { return nil }
+            return tableMetadata.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        return tableMetadata.init(value: result)
+        return nil
     }
 
     func getMetadataFromFileId(_ fileId: String?) -> tableMetadata? {
 
-        let realm = try! Realm()
-        realm.refresh()
-
-        guard let fileId = fileId else { return nil }
-        guard let result = realm.objects(tableMetadata.self).filter("fileId == %@", fileId).first else { return nil }
+        do {
+            let realm = try Realm()
+            guard let fileId = fileId else { return nil }
+            guard let result = realm.objects(tableMetadata.self).filter("fileId == %@", fileId).first else { return nil }
+            return tableMetadata.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        return tableMetadata.init(value: result)
+        return nil
     }
 
     func getMetadataFolder(account: String, urlBase: String, userId: String, serverUrl: String) -> tableMetadata? {
 
-        let realm = try! Realm()
-        realm.refresh()
         var serverUrl = serverUrl
         var fileName = ""
 
@@ -906,22 +911,31 @@ extension NCManageDatabase {
             }
         }
 
-        guard let result = realm.objects(tableMetadata.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@", account, serverUrl, fileName).first else { return nil }
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableMetadata.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@", account, serverUrl, fileName).first else { return nil }
+            return tableMetadata.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        return tableMetadata.init(value: result)
+        return nil
     }
 
     func getTableMetadatasDirectoryFavoriteIdentifierRank(account: String) -> [String: NSNumber] {
 
         var listIdentifierRank: [String: NSNumber] = [:]
-        let realm = try! Realm()
         var counter = 10 as Int64
 
-        let results = realm.objects(tableMetadata.self).filter("account == %@ AND directory == true AND favorite == true", account).sorted(byKeyPath: "fileNameView", ascending: true)
-
-        for result in results {
-            counter += 1
-            listIdentifierRank[result.ocId] = NSNumber(value: Int64(counter))
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableMetadata.self).filter("account == %@ AND directory == true AND favorite == true", account).sorted(byKeyPath: "fileNameView", ascending: true)
+            for result in results {
+                counter += 1
+                listIdentifierRank[result.ocId] = NSNumber(value: Int64(counter))
+            }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
         return listIdentifierRank
@@ -929,12 +943,9 @@ extension NCManageDatabase {
 
     @objc func clearMetadatasUpload(account: String) {
 
-        let realm = try! Realm()
-        realm.refresh()
-
         do {
+            let realm = try Realm()
             try realm.write {
-
                 let results = realm.objects(tableMetadata.self).filter("account == %@ AND (status == %d OR status == %@)", account, NCGlobal.shared.metadataStatusWaitUpload, NCGlobal.shared.metadataStatusUploadError)
                 realm.delete(results)
             }
@@ -945,9 +956,8 @@ extension NCManageDatabase {
 
     func readMarkerMetadata(account: String, fileId: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let results = realm.objects(tableMetadata.self).filter("account == %@ AND fileId == %@", account, fileId)
                 for result in results {
@@ -961,14 +971,16 @@ extension NCManageDatabase {
 
     func getAssetLocalIdentifiersUploaded(account: String) -> [String] {
 
-        let realm = try! Realm()
-        realm.refresh()
-
         var assetLocalIdentifiers: [String] = []
 
-        let results = realm.objects(tableMetadata.self).filter("account == %@ AND assetLocalIdentifier != '' AND deleteAssetLocalIdentifier == true", account)
-        for result in results {
-            assetLocalIdentifiers.append(result.assetLocalIdentifier)
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableMetadata.self).filter("account == %@ AND assetLocalIdentifier != '' AND deleteAssetLocalIdentifier == true", account)
+            for result in results {
+                assetLocalIdentifiers.append(result.assetLocalIdentifier)
+            }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
         return assetLocalIdentifiers
@@ -976,9 +988,8 @@ extension NCManageDatabase {
 
     func clearAssetLocalIdentifiers(_ assetLocalIdentifiers: [String], account: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let results = realm.objects(tableMetadata.self).filter("account == %@ AND assetLocalIdentifier IN %@", account, assetLocalIdentifiers)
                 for result in results {
@@ -993,7 +1004,6 @@ extension NCManageDatabase {
 
     func getMetadataLivePhoto(metadata: tableMetadata) -> tableMetadata? {
 
-        let realm = try! Realm()
         var classFile = metadata.classFile
         var fileName = (metadata.fileNameView as NSString).deletingPathExtension
 
@@ -1009,31 +1019,35 @@ extension NCManageDatabase {
             fileName = fileName + ".jpg"
         }
 
-        guard let result = realm.objects(tableMetadata.self).filter(NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameView CONTAINS[cd] %@ AND ocId != %@ AND classFile == %@", metadata.account, metadata.serverUrl, fileName, metadata.ocId, classFile)).first else {
-            return nil
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableMetadata.self).filter(NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameView CONTAINS[cd] %@ AND ocId != %@ AND classFile == %@", metadata.account, metadata.serverUrl, fileName, metadata.ocId, classFile)).first else { return nil }
+            return tableMetadata.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return tableMetadata.init(value: result)
+        return nil
     }
 
     func getMetadatasMedia(predicate: NSPredicate, livePhoto: Bool) -> [tableMetadata] {
 
-        let realm = try! Realm()
         var metadatas: [tableMetadata] = []
 
         do {
+            let realm = try Realm()
             try realm.write {
-                let sortProperties = [SortDescriptor(keyPath: "serverUrl", ascending: false), SortDescriptor(keyPath:  "fileNameView", ascending: false)]
+                let sortProperties = [SortDescriptor(keyPath: "serverUrl", ascending: false), SortDescriptor(keyPath: "fileNameView", ascending: false)]
                 let results = realm.objects(tableMetadata.self).filter(predicate).sorted(by: sortProperties)
                 if livePhoto {
                     for index in results.indices {
                         let metadata = results[index]
-                        if index < results.count - 1, metadata.fileNoExtension == results[index+1].fileNoExtension {
+                        if index < results.count - 1, metadata.fileNoExtension == results[index + 1].fileNoExtension {
                             if !metadata.livePhoto {
                                 metadata.livePhoto = true
                             }
-                            if !results[index+1].livePhoto {
-                                results[index+1].livePhoto = true
+                            if !results[index + 1].livePhoto {
+                                results[index + 1].livePhoto = true
                             }
                         }
                         if metadata.livePhoto {
@@ -1104,37 +1118,48 @@ extension NCManageDatabase {
 
     func getNumMetadatasInUpload() -> Int {
 
-        let realm = try! Realm()
-
-        let num = realm.objects(tableMetadata.self).filter(NSPredicate(format: "status == %i || status == %i",  NCGlobal.shared.metadataStatusInUpload, NCGlobal.shared.metadataStatusUploading)).count
+        do {
+            let realm = try Realm()
+            return realm.objects(tableMetadata.self).filter(NSPredicate(format: "status == %i || status == %i", NCGlobal.shared.metadataStatusInUpload, NCGlobal.shared.metadataStatusUploading)).count
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        return num
+        return 0
     }
 
     func getMetadataFromDirectory(account: String, serverUrl: String) -> tableMetadata? {
 
-        let realm = try! Realm()
-
-        guard let directory = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first else { return nil }
-        guard let result = realm.objects(tableMetadata.self).filter("ocId == %@", directory.ocId).first else { return nil }
+        do {
+            let realm = try Realm()
+            guard let directory = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first else { return nil }
+            guard let result = realm.objects(tableMetadata.self).filter("ocId == %@", directory.ocId).first else { return nil }
+            return tableMetadata.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        return tableMetadata.init(value: result)
+        return nil
     }
 
     func getMetadatasFromGroupfolders(account: String, urlBase: String, userId: String) -> [tableMetadata] {
 
-        let realm = try! Realm()
         var metadatas: [tableMetadata] = []
         let homeServerUrl = NCUtilityFileSystem.shared.getHomeServer(urlBase: urlBase, userId: userId)
 
-        let groupfolders = realm.objects(TableGroupfolders.self).filter("account == %@", account)
-        for groupfolder in groupfolders {
-            let mountPoint = groupfolder.mountPoint.hasPrefix("/") ? groupfolder.mountPoint : "/" + groupfolder.mountPoint
-            let serverUrlFileName = homeServerUrl + mountPoint
-            if let directory = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl == %@", account, serverUrlFileName).first,
-               let metadata = realm.objects(tableMetadata.self).filter("ocId == %@", directory.ocId).first {
-                metadatas.append(tableMetadata(value: metadata))
+        do {
+            let realm = try Realm()
+            let groupfolders = realm.objects(TableGroupfolders.self).filter("account == %@", account)
+            for groupfolder in groupfolders {
+                let mountPoint = groupfolder.mountPoint.hasPrefix("/") ? groupfolder.mountPoint : "/" + groupfolder.mountPoint
+                let serverUrlFileName = homeServerUrl + mountPoint
+                if let directory = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl == %@", account, serverUrlFileName).first,
+                   let metadata = realm.objects(tableMetadata.self).filter("ocId == %@", directory.ocId).first {
+                    metadatas.append(tableMetadata(value: metadata))
+                }
             }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
         return metadatas

+ 64 - 60
iOSClient/Data/NCManageDatabase+Share.swift

@@ -77,26 +77,18 @@ extension NCManageDatabase {
 
     func addShare(account: String, home: String, shares: [NKShare]) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
-
                 for share in shares {
-
                     let serverUrlPath = home + share.path
-                    guard let serverUrl = NCUtilityFileSystem.shared.deleteLastPath(serverUrlPath: serverUrlPath, home: home) else {
-                        continue
-                    }
-
+                    guard let serverUrl = NCUtilityFileSystem.shared.deleteLastPath(serverUrlPath: serverUrlPath, home: home) else { continue }
                     let object = tableShare()
-
                     object.account = account
                     if let fileName = share.path.components(separatedBy: "/").last {
                         object.fileName = fileName
                     }
                     object.serverUrl = serverUrl
-
                     object.canEdit = share.canEdit
                     object.canDelete = share.canDelete
                     object.date = share.date
@@ -133,7 +125,6 @@ extension NCManageDatabase {
                     object.userIcon = share.userIcon
                     object.userMessage = share.userMessage
                     object.userStatus = share.userStatus
-
                     realm.add(object, update: .all)
                 }
             }
@@ -144,89 +135,102 @@ extension NCManageDatabase {
 
     func getTableShares(account: String) -> [tableShare] {
 
-        let realm = try! Realm()
-
-        let sortProperties = [SortDescriptor(keyPath: "shareType", ascending: false), SortDescriptor(keyPath: "idShare", ascending: false)]
-        let results = realm.objects(tableShare.self).filter("account == %@", account).sorted(by: sortProperties)
+        do {
+            let realm = try Realm()
+            let sortProperties = [SortDescriptor(keyPath: "shareType", ascending: false), SortDescriptor(keyPath: "idShare", ascending: false)]
+            let results = realm.objects(tableShare.self).filter("account == %@", account).sorted(by: sortProperties)
+            return Array(results.map { tableShare.init(value: $0) })
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        return Array(results.map { tableShare.init(value: $0) })
+        return []
     }
 
     func getTableShares(metadata: tableMetadata) -> (firstShareLink: tableShare?, share: [tableShare]?) {
 
-        let realm = try! Realm()
-
-        let sortProperties = [SortDescriptor(keyPath: "shareType", ascending: false), SortDescriptor(keyPath: "idShare", ascending: false)]
-        let firstShareLink = realm.objects(tableShare.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@ AND shareType == 3", metadata.account, metadata.serverUrl, metadata.fileName).first
-
-        if let firstShareLink = firstShareLink {
-            let results = realm.objects(tableShare.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@ AND idShare != %d", metadata.account, metadata.serverUrl, metadata.fileName, firstShareLink.idShare).sorted(by: sortProperties)
-            return(firstShareLink: tableShare.init(value: firstShareLink), share: Array(results.map { tableShare.init(value: $0) }))
-        } else {
-            let results = realm.objects(tableShare.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@", metadata.account, metadata.serverUrl, metadata.fileName).sorted(by: sortProperties)
-            return(firstShareLink: firstShareLink, share: Array(results.map { tableShare.init(value: $0) }))
+        do {
+            let realm = try Realm()
+            let sortProperties = [SortDescriptor(keyPath: "shareType", ascending: false), SortDescriptor(keyPath: "idShare", ascending: false)]
+            let firstShareLink = realm.objects(tableShare.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@ AND shareType == 3", metadata.account, metadata.serverUrl, metadata.fileName).first
+            if let firstShareLink = firstShareLink {
+                let results = realm.objects(tableShare.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@ AND idShare != %d", metadata.account, metadata.serverUrl, metadata.fileName, firstShareLink.idShare).sorted(by: sortProperties)
+                return(firstShareLink: tableShare.init(value: firstShareLink), share: Array(results.map { tableShare.init(value: $0) }))
+            } else {
+                let results = realm.objects(tableShare.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@", metadata.account, metadata.serverUrl, metadata.fileName).sorted(by: sortProperties)
+                return(firstShareLink: firstShareLink, share: Array(results.map { tableShare.init(value: $0) }))
+            }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
+
+        return (nil, nil)
     }
 
     func getTableShare(account: String, idShare: Int) -> tableShare? {
 
-        let realm = try! Realm()
-
-        guard let result = realm.objects(tableShare.self).filter("account = %@ AND idShare = %d", account, idShare).first else {
-            return nil
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableShare.self).filter("account = %@ AND idShare = %d", account, idShare).first else { return nil }
+            return tableShare.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return tableShare.init(value: result)
+        return nil
     }
 
     func getTableShares(account: String, serverUrl: String) -> [tableShare] {
 
-        let realm = try! Realm()
-
-        let sortProperties = [SortDescriptor(keyPath: "shareType", ascending: false), SortDescriptor(keyPath: "idShare", ascending: false)]
-        let results = realm.objects(tableShare.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).sorted(by: sortProperties)
+        do {
+            let realm = try Realm()
+            let sortProperties = [SortDescriptor(keyPath: "shareType", ascending: false), SortDescriptor(keyPath: "idShare", ascending: false)]
+            let results = realm.objects(tableShare.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).sorted(by: sortProperties)
+            return Array(results.map { tableShare.init(value: $0) })
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        return Array(results.map { tableShare.init(value: $0) })
+        return []
     }
 
     func getTableShares(account: String, serverUrl: String, fileName: String) -> [tableShare] {
 
-        let realm = try! Realm()
-
-        let sortProperties = [SortDescriptor(keyPath: "shareType", ascending: false), SortDescriptor(keyPath: "idShare", ascending: false)]
-        let results = realm.objects(tableShare.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@", account, serverUrl, fileName).sorted(by: sortProperties)
+        do {
+            let realm = try Realm()
+            let sortProperties = [SortDescriptor(keyPath: "shareType", ascending: false), SortDescriptor(keyPath: "idShare", ascending: false)]
+            let results = realm.objects(tableShare.self).filter("account == %@ AND serverUrl == %@ AND fileName == %@", account, serverUrl, fileName).sorted(by: sortProperties)
+            return Array(results.map { tableShare.init(value: $0) })
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        return Array(results.map { tableShare.init(value: $0) })
+        return []
     }
 
     func deleteTableShare(account: String, idShare: Int) {
 
-        let realm = try! Realm()
-
-        realm.beginWrite()
-
-        let result = realm.objects(tableShare.self).filter("account == %@ AND idShare == %d", account, idShare)
-        realm.delete(result)
-
         do {
-            try realm.commitWrite()
-        } catch let error {
+            let realm = try Realm()
+            try realm.write {
+                let result = realm.objects(tableShare.self).filter("account == %@ AND idShare == %d", account, idShare)
+                realm.delete(result)
+            }
+        } catch let error as NSError {
             NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
     }
 
     func deleteTableShare(account: String) {
 
-        let realm = try! Realm()
-
-        realm.beginWrite()
-
-        let result = realm.objects(tableShare.self).filter("account == %@", account)
-        realm.delete(result)
-
         do {
-            try realm.commitWrite()
-        } catch let error {
+            let realm = try Realm()
+
+            try realm.write {
+                let result = realm.objects(tableShare.self).filter("account == %@", account)
+                realm.delete(result)
+            }
+        } catch let error as NSError {
             NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
     }

+ 12 - 17
iOSClient/Data/NCManageDatabase+Video.swift

@@ -49,12 +49,11 @@ extension NCManageDatabase {
     func addVideo(metadata: tableMetadata, position: Float? = nil, width: Int? = nil, height: Int? = nil, length: Int? = nil, currentAudioTrackIndex: Int? = nil, currentVideoSubTitleIndex: Int? = nil) {
 
         if metadata.livePhoto { return }
-        let realm = try! Realm()
 
         do {
+            let realm = try Realm()
             try realm.write {
                 if let result = realm.objects(tableVideo.self).filter("account == %@ AND ocId == %@", metadata.account, metadata.ocId).first {
-
                     if let position = position {
                         result.position = position
                     }
@@ -73,16 +72,11 @@ extension NCManageDatabase {
                     if let currentVideoSubTitleIndex = currentVideoSubTitleIndex {
                         result.currentVideoSubTitleIndex = currentVideoSubTitleIndex
                     }
-
                     realm.add(result, update: .all)
-
                 } else {
-
                     let result = tableVideo()
-
                     result.account = metadata.account
                     result.ocId = metadata.ocId
-
                     if let position = position {
                         result.position = position
                     }
@@ -101,7 +95,6 @@ extension NCManageDatabase {
                     if let currentVideoSubTitleIndex = currentVideoSubTitleIndex {
                         result.currentVideoSubTitleIndex = currentVideoSubTitleIndex
                     }
-                    
                     realm.add(result, update: .all)
                 }
             }
@@ -112,9 +105,8 @@ extension NCManageDatabase {
 
     func addVideoCodec(metadata: tableMetadata, codecNameVideo: String?, codecNameAudio: String?, codecAudioChannelLayout: String?, codecAudioLanguage: String?, codecMaxCompatibility: Bool, codecQuality: String?) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 if let result = realm.objects(tableVideo.self).filter("account == %@ AND ocId == %@", metadata.account, metadata.ocId).first {
                     if let codecNameVideo = codecNameVideo { result.codecNameVideo = codecNameVideo }
@@ -143,21 +135,24 @@ extension NCManageDatabase {
     }
 
     func getVideo(metadata: tableMetadata?) -> tableVideo? {
+
         guard let metadata = metadata else { return nil }
 
-        let realm = try! Realm()
-        guard let result = realm.objects(tableVideo.self).filter("account == %@ AND ocId == %@", metadata.account, metadata.ocId).first else {
-            return nil
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableVideo.self).filter("account == %@ AND ocId == %@", metadata.account, metadata.ocId).first else { return nil }
+            return tableVideo.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return tableVideo.init(value: result)
+        return nil
     }
-    
-    func deleteVideo(metadata: tableMetadata) {
 
-        let realm = try! Realm()
+    func deleteVideo(metadata: tableMetadata) {
 
         do {
+            let realm = try Realm()
             try realm.write {
                 let result = realm.objects(tableVideo.self).filter("account == %@ AND ocId == %@", metadata.account, metadata.ocId)
                 realm.delete(result)

+ 204 - 195
iOSClient/Data/NCManageDatabase.swift

@@ -149,7 +149,11 @@ class NCManageDatabase: NSObject {
         }
 
         // Open Real
-        _ = try! Realm()
+        do {
+            _ = try Realm()
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not open database: \(error)")
+        }
     }
 
     // MARK: -
@@ -157,9 +161,8 @@ class NCManageDatabase: NSObject {
 
     @objc func clearTable(_ table: Object.Type, account: String? = nil) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 var results: Results<Object>
 
@@ -232,21 +235,24 @@ class NCManageDatabase: NSObject {
         }
     }
 
-    @objc func getThreadConfined(_ object: Object) -> Any {
+    func getThreadConfined(_ object: Object) -> Any {
 
-        // id tradeReference = [[NCManageDatabase shared] getThreadConfined:metadata];
         return ThreadSafeReference(to: object)
     }
 
-    @objc func putThreadConfined(_ tableRef: Any) -> Object? {
+    func putThreadConfined(_ tableRef: ThreadSafeReference<Object>) -> Object? {
 
-        // tableMetadata *metadataThread = (tableMetadata *)[[NCManageDatabase shared] putThreadConfined:tradeReference];
-        let realm = try! Realm()
+        do {
+            let realm = try Realm()
+            return realm.resolve(tableRef)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        return realm.resolve(tableRef as! ThreadSafeReference<Object>)
+        return nil
     }
 
-    @objc func isTableInvalidated(_ object: Object) -> Bool {
+    func isTableInvalidated(_ object: Object) -> Bool {
 
         return object.isInvalidated
     }
@@ -256,10 +262,12 @@ class NCManageDatabase: NSObject {
 
     func getChunkFolder(account: String, ocId: String) -> String {
 
-        let realm = try! Realm()
-
-        if let result = realm.objects(tableChunk.self).filter("account == %@ AND ocId == %@", account, ocId).first {
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableChunk.self).filter("account == %@ AND ocId == %@", account, ocId).first else { return NSUUID().uuidString }
             return result.chunkFolder
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
         return NSUUID().uuidString
@@ -267,12 +275,17 @@ class NCManageDatabase: NSObject {
 
     func getChunks(account: String, ocId: String) -> [String] {
 
-        let realm = try! Realm()
         var filesNames: [String] = []
 
-        let results = realm.objects(tableChunk.self).filter("account == %@ AND ocId == %@", account, ocId).sorted(byKeyPath: "fileName", ascending: true)
-        for result in results {
-            filesNames.append(result.fileName)
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableChunk.self).filter("account == %@ AND ocId == %@", account, ocId).sorted(byKeyPath: "fileName", ascending: true)
+            for result in results {
+                filesNames.append(result.fileName)
+            }
+            return filesNames
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
         return filesNames
@@ -280,10 +293,10 @@ class NCManageDatabase: NSObject {
 
     func addChunks(account: String, ocId: String, chunkFolder: String, fileNames: [String]) {
 
-        let realm = try! Realm()
         var size: Int64 = 0
 
         do {
+            let realm = try Realm()
             try realm.write {
 
                 for fileName in fileNames {
@@ -308,22 +321,22 @@ class NCManageDatabase: NSObject {
 
     func getChunk(account: String, fileName: String) -> tableChunk? {
 
-        let realm = try! Realm()
-
-        if let result = realm.objects(tableChunk.self).filter("account == %@ AND fileName == %@", account, fileName).first {
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableChunk.self).filter("account == %@ AND fileName == %@", account, fileName).first else { return nil }
             return tableChunk.init(value: result)
-        } else {
-            return nil
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
+
+        return nil
     }
 
     func deleteChunk(account: String, ocId: String, fileName: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
-
                 let result = realm.objects(tableChunk.self).filter(NSPredicate(format: "account == %@ AND ocId == %@ AND fileName == %@", account, ocId, fileName))
                 realm.delete(result)
             }
@@ -334,9 +347,8 @@ class NCManageDatabase: NSObject {
 
     func deleteChunks(account: String, ocId: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
 
                 let result = realm.objects(tableChunk.self).filter(NSPredicate(format: "account == %@ AND ocId == %@", account, ocId))
@@ -352,9 +364,8 @@ class NCManageDatabase: NSObject {
 
     func addDirectEditing(account: String, editors: [NKEditorDetailsEditors], creators: [NKEditorDetailsCreators]) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
 
                 let resultsCreators = realm.objects(tableDirectEditingCreators.self).filter("account == %@", account)
@@ -407,39 +418,53 @@ class NCManageDatabase: NSObject {
 
     func getDirectEditingCreators(account: String) -> [tableDirectEditingCreators]? {
 
-        let realm = try! Realm()
-        let results = realm.objects(tableDirectEditingCreators.self).filter("account == %@", account)
-
-        if results.count > 0 {
-            return Array(results.map { tableDirectEditingCreators.init(value: $0) })
-        } else {
-            return nil
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableDirectEditingCreators.self).filter("account == %@", account)
+            if results.isEmpty {
+                return nil
+            } else {
+                return Array(results.map { tableDirectEditingCreators.init(value: $0) })
+            }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
+
+        return nil
     }
 
     func getDirectEditingCreators(predicate: NSPredicate) -> [tableDirectEditingCreators]? {
 
-        let realm = try! Realm()
-
-        let results = realm.objects(tableDirectEditingCreators.self).filter(predicate)
-
-        if results.count > 0 {
-            return Array(results.map { tableDirectEditingCreators.init(value: $0) })
-        } else {
-            return nil
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableDirectEditingCreators.self).filter(predicate)
+            if results.isEmpty {
+                return nil
+            } else {
+                return Array(results.map { tableDirectEditingCreators.init(value: $0) })
+            }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
+
+        return nil
     }
 
     func getDirectEditingEditors(account: String) -> [tableDirectEditingEditors]? {
 
-        let realm = try! Realm()
-        let results = realm.objects(tableDirectEditingEditors.self).filter("account == %@", account)
-
-        if results.count > 0 {
-            return Array(results.map { tableDirectEditingEditors.init(value: $0) })
-        } else {
-            return nil
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableDirectEditingEditors.self).filter("account == %@", account)
+            if results.isEmpty {
+                return nil
+            } else {
+                return Array(results.map { tableDirectEditingEditors.init(value: $0) })
+            }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
+
+        return nil
     }
 
     // MARK: -
@@ -447,9 +472,8 @@ class NCManageDatabase: NSObject {
 
     func addExternalSites(_ externalSite: NKExternalSite, account: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let addObject = tableExternalSites()
 
@@ -470,9 +494,8 @@ class NCManageDatabase: NSObject {
 
     func deleteExternalSites(account: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let results = realm.objects(tableExternalSites.self).filter("account == %@", account)
                 realm.delete(results)
@@ -484,15 +507,19 @@ class NCManageDatabase: NSObject {
 
     func getAllExternalSites(account: String) -> [tableExternalSites]? {
 
-        let realm = try! Realm()
-
-        let results = realm.objects(tableExternalSites.self).filter("account == %@", account).sorted(byKeyPath: "idExternalSite", ascending: true)
-
-        if results.count > 0 {
-            return Array(results.map { tableExternalSites.init(value: $0) })
-        } else {
-            return nil
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableExternalSites.self).filter("account == %@", account).sorted(byKeyPath: "idExternalSite", ascending: true)
+            if results.isEmpty {
+                return nil
+            } else {
+                return Array(results.map { tableExternalSites.init(value: $0) })
+            }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
+
+        return nil
     }
 
     // MARK: -
@@ -500,43 +527,37 @@ class NCManageDatabase: NSObject {
 
     @objc func addGeocoderLocation(_ location: String, placemarkAdministrativeArea: String, placemarkCountry: String, placemarkLocality: String, placemarkPostalCode: String, placemarkThoroughfare: String, latitude: String, longitude: String) {
 
-        let realm = try! Realm()
-
-        realm.beginWrite()
-
-        // Verify if exists
-        guard realm.objects(tableGPS.self).filter("latitude == %@ AND longitude == %@", latitude, longitude).first == nil else {
-            realm.cancelWrite()
-            return
-        }
-
-        // Add new GPS
-        let addObject = tableGPS()
-
-        addObject.latitude = latitude
-        addObject.location = location
-        addObject.longitude = longitude
-        addObject.placemarkAdministrativeArea = placemarkAdministrativeArea
-        addObject.placemarkCountry = placemarkCountry
-        addObject.placemarkLocality = placemarkLocality
-        addObject.placemarkPostalCode = placemarkPostalCode
-        addObject.placemarkThoroughfare = placemarkThoroughfare
-
-        realm.add(addObject)
-
         do {
-            try realm.commitWrite()
-        } catch let error {
+            let realm = try Realm()
+            guard realm.objects(tableGPS.self).filter("latitude == %@ AND longitude == %@", latitude, longitude).first == nil else { return }
+            try realm.write {
+                let addObject = tableGPS()
+                addObject.latitude = latitude
+                addObject.location = location
+                addObject.longitude = longitude
+                addObject.placemarkAdministrativeArea = placemarkAdministrativeArea
+                addObject.placemarkCountry = placemarkCountry
+                addObject.placemarkLocality = placemarkLocality
+                addObject.placemarkPostalCode = placemarkPostalCode
+                addObject.placemarkThoroughfare = placemarkThoroughfare
+                realm.add(addObject)
+            }
+        } catch let error as NSError {
             NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
     }
 
     @objc func getLocationFromGeoLatitude(_ latitude: String, longitude: String) -> String? {
 
-        let realm = try! Realm()
+        do {
+            let realm = try Realm()
+            let result = realm.objects(tableGPS.self).filter("latitude == %@ AND longitude == %@", latitude, longitude).first
+            return result?.location
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        let result = realm.objects(tableGPS.self).filter("latitude == %@ AND longitude == %@", latitude, longitude).first
-        return result?.location
+        return nil
     }
 
     // MARK: -
@@ -544,13 +565,10 @@ class NCManageDatabase: NSObject {
 
     func addLocalFile(metadata: tableMetadata) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
-
                 let addObject = getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) ?? tableLocalFile()
-
                 addObject.account = metadata.account
                 addObject.etag = metadata.etag
                 addObject.exifDate = NSDate()
@@ -558,7 +576,6 @@ class NCManageDatabase: NSObject {
                 addObject.exifLongitude = "-1"
                 addObject.ocId = metadata.ocId
                 addObject.fileName = metadata.fileName
-
                 realm.add(addObject, update: .all)
             }
         } catch let error {
@@ -568,13 +585,10 @@ class NCManageDatabase: NSObject {
 
     func addLocalFile(account: String, etag: String, ocId: String, fileName: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
-
                 let addObject = tableLocalFile()
-
                 addObject.account = account
                 addObject.etag = etag
                 addObject.exifDate = NSDate()
@@ -582,7 +596,6 @@ class NCManageDatabase: NSObject {
                 addObject.exifLongitude = "-1"
                 addObject.ocId = ocId
                 addObject.fileName = fileName
-
                 realm.add(addObject, update: .all)
             }
         } catch let error {
@@ -592,9 +605,8 @@ class NCManageDatabase: NSObject {
 
     func deleteLocalFile(predicate: NSPredicate) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let results = realm.objects(tableLocalFile.self).filter(predicate)
                 realm.delete(results)
@@ -606,9 +618,8 @@ class NCManageDatabase: NSObject {
 
     func setLocalFile(ocId: String, fileName: String?, etag: String?) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let result = realm.objects(tableLocalFile.self).filter("ocId == %@", ocId).first
                 if let fileName = fileName {
@@ -625,9 +636,8 @@ class NCManageDatabase: NSObject {
 
     @objc func setLocalFile(ocId: String, exifDate: NSDate?, exifLatitude: String, exifLongitude: String, exifLensModel: String?) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 if let result = realm.objects(tableLocalFile.self).filter("ocId == %@", ocId).first {
                     result.exifDate = exifDate
@@ -645,36 +655,47 @@ class NCManageDatabase: NSObject {
 
     func getTableLocalFile(account: String) -> [tableLocalFile] {
 
-        let realm = try! Realm()
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableLocalFile.self).filter("account == %@", account)
+            return Array(results.map { tableLocalFile.init(value: $0) })
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        let results = realm.objects(tableLocalFile.self).filter("account == %@", account)
-        return Array(results.map { tableLocalFile.init(value: $0) })
+        return []
     }
 
     func getTableLocalFile(predicate: NSPredicate) -> tableLocalFile? {
 
-        let realm = try! Realm()
-
-        guard let result = realm.objects(tableLocalFile.self).filter(predicate).first else {
-            return nil
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableLocalFile.self).filter(predicate).first else { return nil }
+            return tableLocalFile.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return tableLocalFile.init(value: result)
+        return nil
     }
 
     func getTableLocalFiles(predicate: NSPredicate, sorted: String, ascending: Bool) -> [tableLocalFile] {
 
-        let realm = try! Realm()
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableLocalFile.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
+            return Array(results.map { tableLocalFile.init(value: $0) })
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        let results = realm.objects(tableLocalFile.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
-        return Array(results.map { tableLocalFile.init(value: $0) })
+        return []
     }
 
     func setLocalFile(ocId: String, offline: Bool) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let result = realm.objects(tableLocalFile.self).filter("ocId == %@", ocId).first
                 result?.offline = offline
@@ -690,16 +711,12 @@ class NCManageDatabase: NSObject {
     @discardableResult
     func addPhotoLibrary(_ assets: [PHAsset], account: String) -> Bool {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
-
                 for asset in assets {
-
                     var creationDateString = ""
                     let addObject = tablePhotoLibrary()
-
                     addObject.account = account
                     addObject.assetLocalIdentifier = asset.localIdentifier
                     addObject.mediaType = asset.mediaType.rawValue
@@ -711,7 +728,6 @@ class NCManageDatabase: NSObject {
                         addObject.modificationDate = modificationDate as NSDate
                     }
                     addObject.idAsset = account + asset.localIdentifier + creationDateString
-
                     realm.add(addObject, update: .all)
                 }
             }
@@ -725,46 +741,40 @@ class NCManageDatabase: NSObject {
 
     func getPhotoLibraryIdAsset(image: Bool, video: Bool, account: String) -> [String]? {
 
-        let realm = try! Realm()
         var predicate = NSPredicate()
 
         if image && video {
-
             predicate = NSPredicate(format: "account == %@ AND (mediaType == %d OR mediaType == %d)", account, PHAssetMediaType.image.rawValue, PHAssetMediaType.video.rawValue)
-
         } else if image {
-
             predicate = NSPredicate(format: "account == %@ AND mediaType == %d", account, PHAssetMediaType.image.rawValue)
-
         } else if video {
-
             predicate = NSPredicate(format: "account == %@ AND mediaType == %d", account, PHAssetMediaType.video.rawValue)
         }
 
-        let results = realm.objects(tablePhotoLibrary.self).filter(predicate)
-
-        let idsAsset = results.map { $0.idAsset }
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tablePhotoLibrary.self).filter(predicate)
+            let idsAsset = results.map { $0.idAsset }
+            return Array(idsAsset)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        return Array(idsAsset)
+        return nil
     }
-    
+
     // MARK: -
     // MARK: Table Tag
 
     func addTag(_ ocId: String, tagIOS: Data?, account: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
-
-                // Add new
                 let addObject = tableTag()
-
                 addObject.account = account
                 addObject.ocId = ocId
                 addObject.tagIOS = tagIOS
-
                 realm.add(addObject, update: .all)
             }
         } catch let error {
@@ -774,15 +784,12 @@ class NCManageDatabase: NSObject {
 
     func deleteTag(_ ocId: String) {
 
-        let realm = try! Realm()
-
-        realm.beginWrite()
-
-        let result = realm.objects(tableTag.self).filter("ocId == %@", ocId)
-        realm.delete(result)
-
         do {
-            try realm.commitWrite()
+            let realm = try Realm()
+            try realm.write {
+                let results = realm.objects(tableTag.self).filter("ocId == %@", ocId)
+                realm.delete(results)
+            }
         } catch let error {
             NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
@@ -790,22 +797,28 @@ class NCManageDatabase: NSObject {
 
     func getTags(predicate: NSPredicate) -> [tableTag] {
 
-        let realm = try! Realm()
-
-        let results = realm.objects(tableTag.self).filter(predicate)
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableTag.self).filter(predicate)
+            return Array(results.map { tableTag.init(value: $0) })
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        return Array(results.map { tableTag.init(value: $0) })
+        return []
     }
 
     func getTag(predicate: NSPredicate) -> tableTag? {
 
-        let realm = try! Realm()
-
-        guard let result = realm.objects(tableTag.self).filter(predicate).first else {
-            return nil
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableTag.self).filter(predicate).first else { return nil }
+            return tableTag.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return tableTag.init(value: result)
+        return nil
     }
 
     // MARK: -
@@ -813,12 +826,15 @@ class NCManageDatabase: NSObject {
 
     func tipExists(_ tipName: String) -> Bool {
 
-        let realm = try! Realm()
-
-        guard (realm.objects(tableTip.self).where {
-            $0.tipName == tipName
-        }.first) == nil else {
-            return true
+        do {
+            let realm = try Realm()
+            guard (realm.objects(tableTip.self).where {
+                $0.tipName == tipName
+            }.first) == nil else {
+                return true
+            }
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
         return false
@@ -826,9 +842,8 @@ class NCManageDatabase: NSObject {
 
     func addTip(_ tipName: String) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 let addObject = tableTip()
                 addObject.tipName = tipName
@@ -844,13 +859,11 @@ class NCManageDatabase: NSObject {
 
     func addTrash(account: String, items: [NKTrash]) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
                 for trash in items {
                     let object = tableTrash()
-
                     object.account = account
                     object.contentType = trash.contentType
                     object.date = trash.date
@@ -865,7 +878,6 @@ class NCManageDatabase: NSObject {
                     object.trashbinFileName = trash.trashbinFileName
                     object.trashbinOriginalLocation = trash.trashbinOriginalLocation
                     object.classFile = trash.classFile
-
                     realm.add(object, update: .all)
                 }
             }
@@ -876,18 +888,16 @@ class NCManageDatabase: NSObject {
 
     func deleteTrash(filePath: String?, account: String) {
 
-        let realm = try! Realm()
         var predicate = NSPredicate()
 
         do {
+            let realm = try Realm()
             try realm.write {
-
                 if filePath == nil {
                     predicate = NSPredicate(format: "account == %@", account)
                 } else {
                     predicate = NSPredicate(format: "account == %@ AND filePath == %@", account, filePath!)
                 }
-
                 let result = realm.objects(tableTrash.self).filter(predicate)
                 realm.delete(result)
             }
@@ -898,18 +908,16 @@ class NCManageDatabase: NSObject {
 
     func deleteTrash(fileId: String?, account: String) {
 
-        let realm = try! Realm()
         var predicate = NSPredicate()
 
         do {
+            let realm = try Realm()
             try realm.write {
-
                 if fileId == nil {
                     predicate = NSPredicate(format: "account == %@", account)
                 } else {
                     predicate = NSPredicate(format: "account == %@ AND fileId == %@", account, fileId!)
                 }
-
                 let result = realm.objects(tableTrash.self).filter(predicate)
                 realm.delete(result)
             }
@@ -920,24 +928,31 @@ class NCManageDatabase: NSObject {
 
     func getTrash(filePath: String, sort: String?, ascending: Bool?, account: String) -> [tableTrash]? {
 
-        let realm = try! Realm()
         let sort = sort ?? "date"
         let ascending = ascending ?? false
 
-        let results = realm.objects(tableTrash.self).filter("account == %@ AND filePath == %@", account, filePath).sorted(byKeyPath: sort, ascending: ascending)
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableTrash.self).filter("account == %@ AND filePath == %@", account, filePath).sorted(byKeyPath: sort, ascending: ascending)
+            return Array(results.map { tableTrash.init(value: $0) })
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
 
-        return Array(results.map { tableTrash.init(value: $0) })
+        return nil
     }
 
     func getTrashItem(fileId: String, account: String) -> tableTrash? {
 
-        let realm = try! Realm()
-
-        guard let result = realm.objects(tableTrash.self).filter("account == %@ AND fileId == %@", account, fileId).first else {
-            return nil
+        do {
+            let realm = try Realm()
+            guard let result = realm.objects(tableTrash.self).filter("account == %@ AND fileId == %@", account, fileId).first else { return nil }
+            return tableTrash.init(value: result)
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
 
-        return tableTrash.init(value: result)
+        return nil
     }
 
     // MARK: -
@@ -945,18 +960,13 @@ class NCManageDatabase: NSObject {
 
     func addUserStatus(_ userStatuses: [NKUserStatus], account: String, predefined: Bool) {
 
-        let realm = try! Realm()
-
         do {
+            let realm = try Realm()
             try realm.write {
-
                 let results = realm.objects(tableUserStatus.self).filter("account == %@ AND predefined == %@", account, predefined)
                 realm.delete(results)
-
                 for userStatus in userStatuses {
-
                     let object = tableUserStatus()
-
                     object.account = account
                     object.clearAt = userStatus.clearAt
                     object.clearAtTime = userStatus.clearAtTime
@@ -967,7 +977,6 @@ class NCManageDatabase: NSObject {
                     object.predefined = userStatus.predefined
                     object.status = userStatus.status
                     object.userId = userStatus.userId
-
                     realm.add(object)
                 }
             }

+ 10 - 35
iOSClient/Main/Collection Common/NCCollectionViewCommon.swift

@@ -433,23 +433,13 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
     @objc func downloadStartFile(_ notification: NSNotification) {
 
         guard let userInfo = notification.userInfo as NSDictionary?,
-              let ocId = userInfo["ocId"] as? String,
               let serverUrl = userInfo["serverUrl"] as? String,
               serverUrl == self.serverUrl,
               let account = userInfo["account"] as? String,
               account == appDelegate.account
         else { return }
 
-        let (indexPath, sameSections) = dataSource.reloadMetadata(ocId: ocId)
-        if let indexPath = indexPath {
-            if sameSections && (indexPath.section < collectionView.numberOfSections && indexPath.row < collectionView.numberOfItems(inSection: indexPath.section)) {
-                collectionView?.reloadItems(at: [indexPath])
-            } else {
-                self.collectionView?.reloadData()
-            }
-        } else {
-            reloadDataSource()
-        }
+        reloadDataSource()
     }
 
     @objc func downloadedFile(_ notification: NSNotification) {
@@ -514,34 +504,13 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
     @objc func uploadedFile(_ notification: NSNotification) {
 
         guard let userInfo = notification.userInfo as NSDictionary?,
-              let ocId = userInfo["ocId"] as? String,
-              let ocIdTemp = userInfo["ocIdTemp"] as? String,
               let serverUrl = userInfo["serverUrl"] as? String,
               serverUrl == self.serverUrl,
               let account = userInfo["account"] as? String,
               account == appDelegate.account
         else { return }
 
-        // do not exists metadata ?
-        guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) else {
-            reloadDataSource()
-            return
-        }
-        
-        let (indexPath, sameSections) = dataSource.reloadMetadata(ocId: metadata.ocId, ocIdTemp: ocIdTemp)
-        if let indexPath = indexPath {
-            if sameSections && (indexPath.section < collectionView.numberOfSections && indexPath.row < collectionView.numberOfItems(inSection: indexPath.section)) {
-                collectionView?.performBatchUpdates({
-                    collectionView?.reloadItems(at: [indexPath])
-                }, completion: { _ in
-                    self.collectionView?.reloadData()
-                })
-            } else {
-                self.collectionView?.reloadData()
-            }
-        } else {
-            reloadDataSource()
-        }
+        reloadDataSource()
     }
 
     @objc func uploadCancelFile(_ notification: NSNotification) {
@@ -1303,7 +1272,7 @@ extension NCCollectionViewCommon: UICollectionViewDelegate {
             
             let imageIcon = UIImage(contentsOfFile: CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag))
 
-            if metadata.isImage || metadata.isAudioOrVideo {
+            if !metadata.isDirectoryE2EE && (metadata.isImage || metadata.isAudioOrVideo) {
                 var metadatas: [tableMetadata] = []
                 for metadata in metadataSourceForAllSections {
                     if metadata.isImage || metadata.isAudioOrVideo {
@@ -1493,7 +1462,6 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
                 cell.fileInfoLabel?.text = NSLocalizedString("_in_", comment: "") + " " + NCUtilityFileSystem.shared.getPath(path: metadata.path, user: metadata.user)
             } else {
                 cell.fileInfoLabel?.text = metadata.subline
-                cell.titleInfoTrailingFull()
             }
         } else {
             cell.fileTitleLabel?.text = metadata.fileNameView
@@ -1667,6 +1635,13 @@ extension NCCollectionViewCommon: UICollectionViewDataSource {
         // Add TAGS
         cell.setTags(tags: Array(metadata.tags))
 
+        // Hide buttons
+        if metadata.name != NCGlobal.shared.appName {
+            cell.titleInfoTrailingFull()
+            cell.hideButtonShare(true)
+            cell.hideButtonMore(true)
+        }
+
         // ** IMPORT MUST BE AT THE END **
         //
 

+ 10 - 11
iOSClient/NCGlobal.swift

@@ -94,16 +94,16 @@ class NCGlobal: NSObject {
 
     // Nextcloud version
     //
-    let nextcloudVersion12: Int                     =  12
-    let nextcloudVersion15: Int                     =  15
-    let nextcloudVersion17: Int                     =  17
-    let nextcloudVersion18: Int                     =  18
-    let nextcloudVersion20: Int                     =  20
-    let nextcloudVersion23: Int                     =  23
-    let nextcloudVersion24: Int                     =  24
-    let nextcloudVersion25: Int                     =  25
-    let nextcloudVersion26: Int                     =  26
-    let nextcloudVersion27: Int                     =  27
+    let nextcloudVersion12: Int                     = 12
+    let nextcloudVersion15: Int                     = 15
+    let nextcloudVersion17: Int                     = 17
+    let nextcloudVersion18: Int                     = 18
+    let nextcloudVersion20: Int                     = 20
+    let nextcloudVersion23: Int                     = 23
+    let nextcloudVersion24: Int                     = 24
+    let nextcloudVersion25: Int                     = 25
+    let nextcloudVersion26: Int                     = 26
+    let nextcloudVersion27: Int                     = 27
 
     // Nextcloud unsupported
     //
@@ -127,7 +127,6 @@ class NCGlobal: NSObject {
 
     // E2EE
     //
-    let e2eeMaxFileSize: UInt64                     = 500000000     // 500 MB
     let e2eePassphraseTest                          = "more over television factory tendency independence international intellectual impress interest sentence pony"
     @objc let e2eeReadVersions                      = ["1.1", "1.2"]
 

+ 277 - 36
iOSClient/Networking/E2EE/NCEndToEndEncryption.m

@@ -44,6 +44,8 @@
 #define fileNamePrivateKey          @"privateKey.pem"
 #define fileNamePubliceKey          @"publicKey.pem"
 
+#define streamBuffer                1024
+
 #define AES_KEY_128_LENGTH          16
 #define AES_KEY_256_LENGTH          32
 #define AES_IVEC_LENGTH             16
@@ -536,7 +538,6 @@
 
 - (BOOL)encryptFile:(NSString *)fileName fileNameIdentifier:(NSString *)fileNameIdentifier directory:(NSString *)directory key:(NSString **)key initializationVector:(NSString **)initializationVector authenticationTag:(NSString **)authenticationTag
 {
-    NSMutableData *cipherData;
     NSData *authenticationTagData;
    
     NSData *plainData = [[NSFileManager defaultManager] contentsAtPath:[NSString stringWithFormat:@"%@/%@", directory, fileName]];
@@ -545,13 +546,11 @@
     
     NSData *keyData = [self generateKey:AES_KEY_128_LENGTH];
     NSData *initializationVectorData = [self generateIV:AES_IVEC_LENGTH];
-    
-    BOOL result = [self encryptData:plainData cipher:&cipherData key:keyData keyLen:AES_KEY_128_LENGTH initializationVector:initializationVectorData authenticationTag:&authenticationTagData];
-    
-    if (cipherData != nil && result) {
-        
-        [cipherData writeToFile:[NSString stringWithFormat:@"%@/%@", directory, fileNameIdentifier] atomically:YES];
-        
+
+    BOOL result = [self encryptFile:[NSString stringWithFormat:@"%@/%@", directory, fileName] fileNameCipher:[NSString stringWithFormat:@"%@/%@", directory, fileNameIdentifier] key:keyData keyLen:AES_KEY_128_LENGTH initializationVector:initializationVectorData authenticationTag:&authenticationTagData];
+
+    if (result) {
+
         *key = [keyData base64EncodedStringWithOptions:0];
         *initializationVector = [initializationVectorData base64EncodedStringWithOptions:0];
         *authenticationTag = [authenticationTagData base64EncodedStringWithOptions:0];
@@ -568,23 +567,11 @@
 
 - (BOOL)decryptFile:(NSString *)fileName fileNameView:(NSString *)fileNameView ocId:(NSString *)ocId key:(NSString *)key initializationVector:(NSString *)initializationVector authenticationTag:(NSString *)authenticationTag
 {
-    NSMutableData *plainData;
-
-    NSData *cipherData = [[NSFileManager defaultManager] contentsAtPath:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileName]];
-    if (cipherData == nil)
-        return false;
-    
     NSData *keyData = [[NSData alloc] initWithBase64EncodedString:key options:0];
     NSData *initializationVectorData = [[NSData alloc] initWithBase64EncodedString:initializationVector options:0];
     NSData *authenticationTagData = [[NSData alloc] initWithBase64EncodedString:authenticationTag options:0];
 
-    BOOL result = [self decryptData:cipherData plain:&plainData key:keyData keyLen:AES_KEY_128_LENGTH initializationVector:initializationVectorData authenticationTag:authenticationTagData];
-    if (plainData != nil && result) {
-        [plainData writeToFile:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileNameView] atomically:YES];
-        return true;
-    }
-    
-    return false;
+   return [self decryptFile:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileName] fileNamePlain:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileNameView] key:keyData keyLen:AES_KEY_128_LENGTH initializationVector:initializationVectorData authenticationTag:authenticationTagData];
 }
 
 // -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -729,7 +716,7 @@
 #pragma mark - AES/GCM/NoPadding
 #
 
-// Encryption using GCM mode
+// Encryption data using GCM mode
 - (BOOL)encryptData:(NSData *)plain cipher:(NSMutableData **)cipher key:(NSData *)key keyLen:(int)keyLen initializationVector:(NSData *)initializationVector authenticationTag:(NSData **)authenticationTag
 {
     int status = 0;
@@ -763,32 +750,41 @@
     else if (keyLen == AES_KEY_256_LENGTH)
         status = EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
     
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Set IV length. Not necessary if this is 12 bytes (96 bits)
     status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, (int)sizeof(cIV), NULL);
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Initialise key and IV
     status = EVP_EncryptInit_ex (ctx, NULL, NULL, cKey, cIV);
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Provide the message to be encrypted, and obtain the encrypted output
     *cipher = [NSMutableData dataWithLength:[plain length]];
     unsigned char * cCipher = [*cipher mutableBytes];
     int cCipherLen = 0;
     status = EVP_EncryptUpdate(ctx, cCipher, &cCipherLen, [plain bytes], (int)[plain length]);
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Finalise the encryption
-    len = cCipherLen;
-    status = EVP_EncryptFinal_ex(ctx, cCipher+cCipherLen, &len);
-    if (status <= 0)
+    status = EVP_EncryptFinal_ex(ctx, cCipher, &cCipherLen);
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Get the tag
     status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, (int)sizeof(cTag), cTag);
@@ -797,13 +793,139 @@
     // Append TAG
     [*cipher appendData:*authenticationTag];
 
-    // Free
     EVP_CIPHER_CTX_free(ctx);
     
     return status; // OpenSSL uses 1 for success
 }
 
-// Decryption using GCM mode
+// Encryption file using GCM mode
+- (BOOL)encryptFile:(NSString *)fileName fileNameCipher:(NSString *)fileNameCipher key:(NSData *)key keyLen:(int)keyLen initializationVector:(NSData *)initializationVector authenticationTag:(NSData **)authenticationTag
+{
+    int status = 0;
+    int len = 0;
+
+    // set up key
+    len = keyLen;
+    unsigned char cKey[len];
+    bzero(cKey, sizeof(cKey));
+    [key getBytes:cKey length:len];
+
+    // set up ivec
+    len = AES_IVEC_LENGTH;
+    unsigned char cIV[len];
+    bzero(cIV, sizeof(cIV));
+    [initializationVector getBytes:cIV length:len];
+
+    // set up tag
+    len = AES_GCM_TAG_LENGTH;
+    unsigned char cTag[len];
+    bzero(cTag, sizeof(cTag));
+
+    // Create and initialise the context
+    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
+    if (!ctx) {
+        return NO;
+    }
+
+    // Initialise the encryption operation
+    if (keyLen == AES_KEY_128_LENGTH)
+        status = EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
+    else if (keyLen == AES_KEY_256_LENGTH)
+        status = EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
+
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
+        return NO;
+    }
+
+    // Set IV length. Not necessary if this is 12 bytes (96 bits)
+    status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, (int)sizeof(cIV), NULL);
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
+        return NO;
+    }
+
+    // Initialise key and IV
+    status = EVP_EncryptInit_ex (ctx, NULL, NULL, cKey, cIV);
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
+        return NO;
+    }
+
+    NSInputStream *inStream = [NSInputStream inputStreamWithFileAtPath:fileName];
+    [inStream open];
+    NSOutputStream *outStream = [NSOutputStream outputStreamToFileAtPath:fileNameCipher append:false];
+    [outStream open];
+
+    Byte buffer[streamBuffer];
+    NSInteger totalNumberOfBytesWritten = 0;
+
+    int cCipherLen = 0;
+    unsigned char *cCipher;
+
+    while ([inStream hasBytesAvailable]) {
+
+        NSInteger bytesRead = [inStream read:buffer maxLength:streamBuffer];
+
+        if (bytesRead > 0) {
+
+            cCipher = [[NSMutableData dataWithLength:bytesRead] mutableBytes];
+            status = EVP_EncryptUpdate(ctx, cCipher, &cCipherLen, [[NSData dataWithBytes:buffer length:bytesRead] bytes], (int)bytesRead);
+            if (status <= 0) {
+                [inStream close];
+                [outStream close];
+                EVP_CIPHER_CTX_free(ctx);
+                return NO;
+            }
+
+            if ([outStream hasSpaceAvailable]) {
+                totalNumberOfBytesWritten = [outStream write:cCipher maxLength:cCipherLen];
+                if (totalNumberOfBytesWritten != cCipherLen) {
+                    [inStream close];
+                    [outStream close];
+                    EVP_CIPHER_CTX_free(ctx);
+                    return NO;
+                }
+            }
+        }
+    }
+
+    [inStream close];
+
+    status = EVP_EncryptFinal_ex(ctx, cCipher, &cCipherLen);
+    if (status <= 0) {
+        [outStream close];
+        EVP_CIPHER_CTX_free(ctx);
+        return NO;
+    }
+
+    // Get the tag
+    status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, (int)sizeof(cTag), cTag);
+    if (status <= 0) {
+        [outStream close];
+        EVP_CIPHER_CTX_free(ctx);
+        return NO;
+    }
+    *authenticationTag = [NSData dataWithBytes:cTag length:sizeof(cTag)];
+
+    // Append TAG
+    if ([outStream hasSpaceAvailable]) {
+        totalNumberOfBytesWritten = [outStream write:cTag maxLength:sizeof(cTag)];
+        if (totalNumberOfBytesWritten != sizeof(cTag)) {
+            status = NO;
+        }
+    } else {
+        status = NO;
+    }
+
+    [outStream close];
+
+    EVP_CIPHER_CTX_free(ctx);
+
+    return status; // OpenSSL uses 1 for success
+}
+
+// Decryption data using GCM mode
 - (BOOL)decryptData:(NSData *)cipher plain:(NSMutableData **)plain key:(NSData *)key keyLen:(int)keyLen initializationVector:(NSData *)initializationVector authenticationTag:(NSData *)authenticationTag
 {    
     int status = 0;
@@ -838,31 +960,41 @@
     else if (keyLen == AES_KEY_256_LENGTH)
         status = EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
     
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Set IV length. Not necessary if this is 12 bytes (96 bits)
     status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, (int)sizeof(cIV), NULL);
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Initialise key and IV
     status = EVP_DecryptInit_ex(ctx, NULL, NULL, cKey, cIV);
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Provide the message to be decrypted, and obtain the plaintext output
     *plain = [NSMutableData dataWithLength:([cipher length])];
     int cPlainLen = 0;
     unsigned char * cPlain = [*plain mutableBytes];
     status = EVP_DecryptUpdate(ctx, cPlain, &cPlainLen, [cipher bytes], (int)([cipher length]));
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Tag is the last 16 bytes
     status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, (int)sizeof(cTag), cTag);
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Finalise the encryption
     EVP_DecryptFinal_ex(ctx,NULL, &cPlainLen);
@@ -873,6 +1005,115 @@
     return status; // OpenSSL uses 1 for success
 }
 
+// Decryption file using GCM mode
+- (BOOL)decryptFile:(NSString *)fileName fileNamePlain:(NSString *)fileNamePlain key:(NSData *)key keyLen:(int)keyLen initializationVector:(NSData *)initializationVector authenticationTag:(NSData *)authenticationTag
+{
+    int status = 0;
+    int len = 0;
+
+    // set up key
+    len = keyLen;
+    unsigned char cKey[len];
+    bzero(cKey, sizeof(cKey));
+    [key getBytes:cKey length:len];
+
+    // set up ivec
+    len = (int)[initializationVector length];
+    unsigned char cIV[len];
+    bzero(cIV, sizeof(cIV));
+    [initializationVector getBytes:cIV length:len];
+
+    // set up tag
+    len = (int)[authenticationTag length];;
+    unsigned char cTag[len];
+    bzero(cTag, sizeof(cTag));
+    [authenticationTag getBytes:cTag length:len];
+
+    // Create and initialise the context
+    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
+    if (!ctx)
+        return NO;
+
+    // Initialise the decryption operation
+    if (keyLen == AES_KEY_128_LENGTH)
+        status = EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
+    else if (keyLen == AES_KEY_256_LENGTH)
+        status = EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
+
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
+        return NO;
+    }
+
+    // Set IV length. Not necessary if this is 12 bytes (96 bits)
+    status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, (int)sizeof(cIV), NULL);
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
+        return NO;
+    }
+
+    // Initialise key and IV
+    status = EVP_DecryptInit_ex(ctx, NULL, NULL, cKey, cIV);
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
+        return NO;
+    }
+
+    NSInputStream *inStream = [NSInputStream inputStreamWithFileAtPath:fileName];
+    [inStream open];
+    NSOutputStream *outStream = [NSOutputStream outputStreamToFileAtPath:fileNamePlain append:false];
+    [outStream open];
+
+    Byte buffer[streamBuffer];
+    NSInteger totalNumberOfBytesWritten = 0;
+
+    int cPlainLen = 0;
+    unsigned char *cPlain;
+
+    while ([inStream hasBytesAvailable]) {
+
+        NSInteger bytesRead = [inStream read:buffer maxLength:streamBuffer];
+
+        if (bytesRead > 0) {
+
+            cPlain = [[NSMutableData dataWithLength:bytesRead] mutableBytes];
+            status = EVP_DecryptUpdate(ctx, cPlain, &cPlainLen, [[NSData dataWithBytes:buffer length:bytesRead] bytes], (int)bytesRead);
+            if (status <= 0) {
+                [inStream close];
+                [outStream close];
+                EVP_CIPHER_CTX_free(ctx);
+                return NO;
+            }
+
+            if ([outStream hasSpaceAvailable]) {
+                totalNumberOfBytesWritten = [outStream write:cPlain maxLength:cPlainLen];
+                if (totalNumberOfBytesWritten != cPlainLen) {
+                    [inStream close];
+                    [outStream close];
+                    EVP_CIPHER_CTX_free(ctx);
+                    return NO;
+                }
+            }
+        }
+    }
+
+    [inStream close];
+    [outStream close];
+
+    // Tag is the last 16 bytes
+    status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, (int)sizeof(cTag), cTag);
+    if (status <= 0)
+        return NO;
+
+    // Finalise the encryption
+    EVP_DecryptFinal_ex(ctx,NULL, &cPlainLen);
+
+    // Free
+    EVP_CIPHER_CTX_free(ctx);
+
+    return status; // OpenSSL uses 1 for success
+}
+
 #
 #pragma mark - Utility
 #

+ 0 - 7
iOSClient/Networking/E2EE/NCNetworkingE2EEUpload.swift

@@ -54,13 +54,6 @@ class NCNetworkingE2EEUpload: NSObject {
         let ocIdTemp = metadata.ocId
         let errorCreateEncrypted = NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "_e2e_error_create_encrypted_")
 
-        // Verify max size
-        if metadata.size > NCGlobal.shared.e2eeMaxFileSize {
-            NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId": metadata.ocId, "serverUrl": metadata.serverUrl, "account": metadata.account, "fileName": metadata.fileName, "ocIdTemp": metadata.ocId, "error": NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "E2E Error file too big")])
-            return NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "E2E Error file too big")
-        }
-
         // Create metadata for upload
         if let result = NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "serverUrl == %@ AND fileNameView == %@ AND ocId != %@", metadata.serverUrl, metadata.fileNameView, metadata.ocId)) {
             metadata.fileName = result.fileName

+ 21 - 17
iOSClient/Networking/NCNetworkingProcessUpload.swift

@@ -39,25 +39,29 @@ class NCNetworkingProcessUpload: NSObject {
     private var pauseProcess: Bool = false
 
     func observeTableMetadata() {
-        let realm = try! Realm()
-        let results = realm.objects(tableMetadata.self).filter("session != '' || sessionError != ''")
-        notificationToken = results.observe { [weak self] (changes: RealmCollectionChange) in
-            switch changes {
-            case .initial:
-                print("Initial")
-            case .update(_, let deletions, let insertions, let modifications):
-                if (deletions.count > 0 || insertions.count > 0 || modifications.count > 0) {
-                    self?.invalidateObserveTableMetadata()
-                    self?.start(completition: { items in
-                        print("[LOG] PROCESS-UPLOAD-OBSERVE \(items)")
-                        DispatchQueue.main.async {
-                            self?.observeTableMetadata()
-                        }
-                    })
+        do {
+            let realm = try Realm()
+            let results = realm.objects(tableMetadata.self).filter("session != '' || sessionError != ''")
+            notificationToken = results.observe { [weak self] (changes: RealmCollectionChange) in
+                switch changes {
+                case .initial:
+                    print("Initial")
+                case .update(_, let deletions, let insertions, let modifications):
+                    if (deletions.count > 0 || insertions.count > 0 || modifications.count > 0) {
+                        self?.invalidateObserveTableMetadata()
+                        self?.start(completition: { items in
+                            print("[LOG] PROCESS-UPLOAD-OBSERVE \(items)")
+                            DispatchQueue.main.async {
+                                self?.observeTableMetadata()
+                            }
+                        })
+                    }
+                case .error(let error):
+                    NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not write to TableMetadata: \(error)")
                 }
-            case .error(let error):
-                NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not write to TableMetadata: \(error)")
             }
+        } catch let error as NSError {
+            NSLog("Could not access database: ", error)
         }
     }
 

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


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


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


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


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