marinofaggiana hace 4 años
padre
commit
fd00966254
Se han modificado 49 ficheros con 697 adiciones y 282 borrados
  1. 0 1
      Carthage/Checkouts/SVGKit/SVGKit.podspec
  2. 2 0
      Carthage/Checkouts/realm-cocoa/.gitignore
  3. 165 0
      Carthage/Checkouts/realm-cocoa/.jenkins.yml
  4. 1 1
      Carthage/Checkouts/realm-cocoa/.travis.yml
  5. 98 0
      Carthage/Checkouts/realm-cocoa/CHANGELOG.md
  6. 1 1
      Carthage/Checkouts/realm-cocoa/Jenkinsfile.releasability
  7. 2 2
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/dependencies.list
  8. 17 0
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object.cpp
  9. 1 0
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object.hpp
  10. 58 47
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object_accessor.hpp
  11. 13 0
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/property.hpp
  12. 1 14
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/thread_safe_reference.cpp
  13. 206 2
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/migrations.cpp
  14. 2 2
      Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist
  15. 1 1
      Carthage/Checkouts/realm-cocoa/build.sh
  16. 3 3
      Carthage/Checkouts/realm-cocoa/dependencies.list
  17. 10 8
      Carthage/Checkouts/realm-cocoa/examples/installation/build.sh
  18. 1 1
      Carthage/Checkouts/realm-cocoa/scripts/package_examples.rb
  19. 8 8
      Nextcloud.xcodeproj/project.pbxproj
  20. 1 1
      iOSClient/Activity/NCActivity.swift
  21. 1 1
      iOSClient/AppDelegate.m
  22. 2 2
      iOSClient/Database/NCManageDatabase.swift
  23. 3 3
      iOSClient/Favorites/CCFavorites.m
  24. 15 0
      iOSClient/Images.xcassets/cloudDownload.imageset/Contents.json
  25. BIN
      iOSClient/Images.xcassets/cloudDownload.imageset/cloudDownload.pdf
  26. 15 0
      iOSClient/Images.xcassets/cloudUpload.imageset/Contents.json
  27. BIN
      iOSClient/Images.xcassets/cloudUpload.imageset/cloudUpload.pdf
  28. 0 26
      iOSClient/Images.xcassets/uploadCloud.imageset/Contents.json
  29. BIN
      iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud.png
  30. BIN
      iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud@2x.png
  31. BIN
      iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud@3x.png
  32. 4 4
      iOSClient/Login/NCAppConfigView.swift
  33. 1 1
      iOSClient/Login/NCLoginWeb.swift
  34. 21 20
      iOSClient/Main/CCMain.m
  35. 1 1
      iOSClient/Main/Create cloud/NCCreateFormUploadAssets.swift
  36. 1 1
      iOSClient/Main/Create cloud/NCCreateFormUploadConflict.swift
  37. 4 4
      iOSClient/Main/Create cloud/NCCreateFormUploadScanDocument.swift
  38. 6 18
      iOSClient/Main/NCMainCommon.swift
  39. 0 79
      iOSClient/Networking/NCNetworking.swift
  40. 1 1
      iOSClient/Networking/NCNetworkingNotificationCenter.swift
  41. 1 1
      iOSClient/Networking/NCOperationQueue.swift
  42. 2 2
      iOSClient/RichWorkspace/NCRichWorkspaceCommon.swift
  43. 1 1
      iOSClient/Settings/CCManageAutoUpload.m
  44. 1 1
      iOSClient/Settings/NCManageAutoUploadFileName.swift
  45. 5 5
      iOSClient/Settings/NCManageEndToEndEncryption.m
  46. 6 6
      iOSClient/Share/NCShareNetworking.swift
  47. 1 1
      iOSClient/Shares/NCShares.m
  48. 4 4
      iOSClient/UploadFromOtherUpp/CCUploadFromOtherUpp.storyboard
  49. 10 8
      iOSClient/Utility/NCContentPresenter.swift

+ 0 - 1
Carthage/Checkouts/SVGKit/SVGKit.podspec

@@ -23,7 +23,6 @@ Pod::Spec.new do |s|
   s.libraries = 'xml2'
   s.framework = 'QuartzCore', 'CoreText'
   s.dependency 'CocoaLumberjack', '~> 3.0'
-  s.prefix_header_file = 'SVGKitLibrary/SVGKit-iOS/SVGKit-Prefix.pch'
   s.module_map = 'SVGKitLibrary/SVGKit-iOS/SVGKit.modulemap'
   s.requires_arc = true
   s.pod_target_xcconfig = {

+ 2 - 0
Carthage/Checkouts/realm-cocoa/.gitignore

@@ -117,3 +117,5 @@ Realm/ObjectServerTests/node_modules
 .swiftpm
 .build
 Package.resolved
+
+examples/installation/ios/swift/SwiftPackageManagerExample/SwiftPackageManagerExample.xcodeproj

+ 165 - 0
Carthage/Checkouts/realm-cocoa/.jenkins.yml

@@ -7,6 +7,7 @@ xcode_version:
  - 11.3
  - 11.4.1
  - 11.5
+ - 11.6
  - 12.0
 target: 
  - docs
@@ -62,6 +63,14 @@ exclude:
     target: docs
     configuration: Release
 
+  - xcode_version: 11.6
+    target: docs
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: docs
+    configuration: Release
+
   - xcode_version: 12.0
     target: docs
     configuration: Debug
@@ -90,6 +99,14 @@ exclude:
     target: swiftlint
     configuration: Release
 
+  - xcode_version: 11.6
+    target: swiftlint
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: swiftlint
+    configuration: Release
+
   - xcode_version: 12.0
     target: swiftlint
     configuration: Debug
@@ -114,6 +131,14 @@ exclude:
     target: osx-encryption
     configuration: Release
 
+  - xcode_version: 11.6
+    target: osx-encryption
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: osx-encryption
+    configuration: Release
+
   - xcode_version: 12.0
     target: osx-encryption
     configuration: Debug
@@ -138,6 +163,14 @@ exclude:
     target: osx-object-server
     configuration: Release
 
+  - xcode_version: 11.6
+    target: osx-object-server
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: osx-object-server
+    configuration: Release
+
   - xcode_version: 12.0
     target: osx-object-server
     configuration: Debug
@@ -162,6 +195,14 @@ exclude:
     target: ios-static
     configuration: Release
 
+  - xcode_version: 11.6
+    target: ios-static
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: ios-static
+    configuration: Release
+
   - xcode_version: 12.0
     target: ios-static
     configuration: Debug
@@ -186,6 +227,14 @@ exclude:
     target: ios-dynamic
     configuration: Release
 
+  - xcode_version: 11.6
+    target: ios-dynamic
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: ios-dynamic
+    configuration: Release
+
   - xcode_version: 12.0
     target: ios-dynamic
     configuration: Debug
@@ -210,6 +259,14 @@ exclude:
     target: watchos
     configuration: Release
 
+  - xcode_version: 11.6
+    target: watchos
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: watchos
+    configuration: Release
+
   - xcode_version: 12.0
     target: watchos
     configuration: Debug
@@ -234,6 +291,14 @@ exclude:
     target: tvos
     configuration: Release
 
+  - xcode_version: 11.6
+    target: tvos
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: tvos
+    configuration: Release
+
   - xcode_version: 12.0
     target: tvos
     configuration: Debug
@@ -258,6 +323,14 @@ exclude:
     target: ios-swift
     configuration: Release
 
+  - xcode_version: 11.6
+    target: ios-swift
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: ios-swift
+    configuration: Release
+
   - xcode_version: 12.0
     target: ios-swift
     configuration: Debug
@@ -282,6 +355,14 @@ exclude:
     target: tvos-swift
     configuration: Release
 
+  - xcode_version: 11.6
+    target: tvos-swift
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: tvos-swift
+    configuration: Release
+
   - xcode_version: 12.0
     target: tvos-swift
     configuration: Debug
@@ -306,6 +387,14 @@ exclude:
     target: catalyst
     configuration: Release
 
+  - xcode_version: 11.6
+    target: catalyst
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: catalyst
+    configuration: Release
+
   - xcode_version: 12.0
     target: catalyst
     configuration: Debug
@@ -330,6 +419,14 @@ exclude:
     target: catalyst-swift
     configuration: Release
 
+  - xcode_version: 11.6
+    target: catalyst-swift
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: catalyst-swift
+    configuration: Release
+
   - xcode_version: 12.0
     target: catalyst-swift
     configuration: Debug
@@ -358,6 +455,14 @@ exclude:
     target: xcframework
     configuration: Release
 
+  - xcode_version: 11.6
+    target: xcframework
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: xcframework
+    configuration: Release
+
   - xcode_version: 12.0
     target: xcframework
     configuration: Debug
@@ -374,6 +479,10 @@ exclude:
     target: cocoapods-osx
     configuration: Debug
 
+  - xcode_version: 11.6
+    target: cocoapods-osx
+    configuration: Debug
+
   - xcode_version: 12.0
     target: cocoapods-osx
     configuration: Debug
@@ -398,6 +507,14 @@ exclude:
     target: cocoapods-ios
     configuration: Release
 
+  - xcode_version: 11.6
+    target: cocoapods-ios
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: cocoapods-ios
+    configuration: Release
+
   - xcode_version: 12.0
     target: cocoapods-ios
     configuration: Debug
@@ -422,6 +539,14 @@ exclude:
     target: cocoapods-ios-dynamic
     configuration: Release
 
+  - xcode_version: 11.6
+    target: cocoapods-ios-dynamic
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: cocoapods-ios-dynamic
+    configuration: Release
+
   - xcode_version: 12.0
     target: cocoapods-ios-dynamic
     configuration: Debug
@@ -446,6 +571,14 @@ exclude:
     target: cocoapods-watchos
     configuration: Release
 
+  - xcode_version: 11.6
+    target: cocoapods-watchos
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: cocoapods-watchos
+    configuration: Release
+
   - xcode_version: 12.0
     target: cocoapods-watchos
     configuration: Debug
@@ -470,6 +603,14 @@ exclude:
     target: swiftpm
     configuration: Release
 
+  - xcode_version: 11.6
+    target: swiftpm
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: swiftpm
+    configuration: Release
+
   - xcode_version: 12.0
     target: swiftpm
     configuration: Debug
@@ -498,6 +639,14 @@ exclude:
     target: swiftpm-address
     configuration: Release
 
+  - xcode_version: 11.6
+    target: swiftpm-address
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: swiftpm-address
+    configuration: Release
+
   - xcode_version: 12.0
     target: swiftpm-address
     configuration: Debug
@@ -526,6 +675,14 @@ exclude:
     target: swiftpm-thread
     configuration: Release
 
+  - xcode_version: 11.6
+    target: swiftpm-thread
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: swiftpm-thread
+    configuration: Release
+
   - xcode_version: 12.0
     target: swiftpm-thread
     configuration: Debug
@@ -554,6 +711,14 @@ exclude:
     target: swiftpm-ios
     configuration: Release
 
+  - xcode_version: 11.6
+    target: swiftpm-ios
+    configuration: Debug
+
+  - xcode_version: 11.6
+    target: swiftpm-ios
+    configuration: Release
+
   - xcode_version: 12.0
     target: swiftpm-ios
     configuration: Debug

+ 1 - 1
Carthage/Checkouts/realm-cocoa/.travis.yml

@@ -1,5 +1,5 @@
 language: objective-c
-osx_image: xcode10.2
+osx_image: xcode11.6
 branches:
   only: master
 script: placeholder # workaround for https://github.com/travis-ci/travis-ci/issues/4681

+ 98 - 0
Carthage/Checkouts/realm-cocoa/CHANGELOG.md

@@ -1,3 +1,101 @@
+5.3.2 Release notes (2020-07-21)
+=============================================================
+
+### Fixed
+
+* Fix a file format upgrade bug when opening older Realm files.. Could cause
+  assertions like "Assertion failed: ref != 0" during opning of a Realm.
+  ([Core #6644](https://github.com/realm/realm-cocoa/issues/6644), since 5.2.0)
+* A use-after-free would occur if a Realm was compacted, opened on multiple
+  threads prior to the first write, then written to while reads were happening
+  on other threads. This could result in a variety of crashes, often inside
+  realm::util::EncryptedFileMapping::read_barrier.
+  (Since v5.0.0, [#6626](https://github.com/realm/realm-cocoa/issues/6626),
+  [#6628](https://github.com/realm/realm-cocoa/issues/6628),
+  [#6652](https://github.com/realm/realm-cocoa/issues/6652),
+  [#6655](https://github.com/realm/realm-cocoa/issues/6555),
+  [#6656](https://github.com/realm/realm-cocoa/issues/6656)).
+
+### Compatibility
+
+* File format: Generates Realms with format v10 (Reads and upgrades all previous formats)
+* Realm Object Server: 3.21.0 or later.
+* Realm Studio: 3.11 or later.
+* APIs are backwards compatible with all previous releases in the 5.x.y series.
+* Carthage release for Swift is built with Xcode 11.6.
+
+### Internal
+
+* Upgraded realm-core from v6.0.11 to v6.0.12
+* Upgraded realm-sync from v5.0.11 to v5.0.12
+
+5.3.1 Release notes (2020-07-17)
+=============================================================
+
+### Enhancements
+
+* Add prebuilt binary for Xcode 11.6 to the release package.
+
+### Fixed
+
+* Creating an object inside migration which changed that object type's primary
+  key would hit an assertion failure mentioning primary_key_col
+  ([#6613](https://github.com/realm/realm-cocoa/issues/6613), since 5.0.0).
+* Modifying the value of a string primary key property inside a migration with
+  a Realm file which was upgraded from pre-5.0 would corrupt the property's
+  index, typically resulting in crashes. ([Core #3765](https://github.com/realm/realm-core/issues/3765), since 5.0.0).
+* Some Realm files which hit assertion failures when upgrading from the pre-5.0
+  file format should now upgrade correctly (Since 5.0.0).
+
+### Compatibility
+
+* File format: Generates Realms with format v10 (Reads and upgrades all previous formats)
+* Realm Object Server: 3.21.0 or later.
+* Realm Studio: 3.11 or later.
+* APIs are backwards compatible with all previous releases in the 5.x.y series.
+* Carthage release for Swift is built with Xcode 11.6.
+
+### Internal
+
+* Upgraded realm-core from v6.0.9 to v6.0.11
+* Upgraded realm-sync from v5.0.8 to v5.0.11
+
+5.3.0 Release notes (2020-07-14)
+=============================================================
+
+### Enhancements
+
+* Add `Realm.objectWillChange`, which is a Combine publisher that will emit a
+  notification each time the Realm is refreshed or a write transaction is
+  commited.
+
+### Fixed
+
+* Fix the spelling of `ObjectKeyIdentifiable`. The old spelling is available
+  and deprecated for compatiblity.
+* Rename `RealmCollection.publisher` to `RealmCollection.collectionPublisher`.
+  The old name interacted with the `publisher` defined by `Sequence` in very
+  confusing ways, so we need to use a different name. The `publisher` name is
+  still available for compatiblity. ([#6516](https://github.com/realm/realm-cocoa/issues/6516))
+* Work around "xcodebuild timed out while trying to read
+  SwiftPackageManagerExample.xcodeproj" errors when installing Realm via
+  Carthage. ([#6549](https://github.com/realm/realm-cocoa/issues/6549)).
+* Fix a performance regression when using change notifications. (Since 5.0.0,
+  [#6629](https://github.com/realm/realm-cocoa/issues/6629)).
+
+### Compatibility
+
+* File format: Generates Realms with format v10 (Reads and upgrades all previous formats)
+* Realm Object Server: 3.21.0 or later.
+* Realm Studio: 3.11 or later.
+* APIs are backwards compatible with all previous releases in the 5.x.y series.
+* Carthage release for Swift is built with Xcode 11.5.
+
+### Internal
+
+* Upgraded realm-core from v6.0.8 to v6.0.9
+* Upgraded realm-sync from v5.0.7 to v5.0.8
+
 5.2.0 Release notes (2020-06-30)
 =============================================================
 

+ 1 - 1
Carthage/Checkouts/realm-cocoa/Jenkinsfile.releasability

@@ -1,4 +1,4 @@
-xcodeVersions = ['11.3', '11.4.1', '11.5']
+xcodeVersions = ['11.3', '11.4.1', '11.5', '11.6']
 platforms = ['osx', 'ios', 'watchos', 'tvos', 'catalyst']
 carthagePlatforms = ['osx', 'ios', 'watchos', 'tvos']
 platformNames = ['osx': 'macOS', 'ios': 'iOS', 'watchos': 'watchOS', 'tvos': 'tvOS', 'catalyst': 'Catalyst']

+ 2 - 2
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/dependencies.list

@@ -1,4 +1,4 @@
-REALM_CORE_VERSION=6.0.6
-REALM_SYNC_VERSION=5.0.5
+REALM_CORE_VERSION=6.0.10
+REALM_SYNC_VERSION=5.0.9
 REALM_CORE_PACKAGING=2
 OPENSSL_VERSION=1.1.1b

+ 17 - 0
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object.cpp

@@ -124,6 +124,23 @@ Property const& Object::property_for_name(StringData prop_name) const
     return *prop;
 }
 
+void Object::validate_property_for_setter(Property const& property) const
+{
+    verify_attached();
+    m_realm->verify_in_write();
+
+    // Modifying primary keys is allowed in migrations to make it possible to
+    // add a new primary key to a type (or change the property type), but it
+    // is otherwise considered the immutable identity of the row
+    if (property.is_primary) {
+        if (!m_realm->is_in_migration())
+            throw ModifyPrimaryKeyException(m_object_schema->name, property.name);
+        // Modifying the PK property while it's the PK will corrupt the table,
+        // so remove it and then restore it at the end of the migration (which will rebuild the table)
+        m_obj.get_table()->set_primary_key_column({});
+    }
+}
+
 #if REALM_ENABLE_SYNC
 void Object::ensure_user_in_everyone_role()
 {

+ 1 - 0
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object.hpp

@@ -146,6 +146,7 @@ private:
 
     void verify_attached() const;
     Property const& property_for_name(StringData prop_name) const;
+    void validate_property_for_setter(Property const&) const;
 };
 
 struct InvalidatedObjectException : public std::logic_error {

+ 58 - 47
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object_accessor.hpp

@@ -43,16 +43,8 @@ template <typename ValueType, typename ContextType>
 void Object::set_property_value(ContextType& ctx, StringData prop_name,
                                 ValueType value, CreatePolicy policy)
 {
-    verify_attached();
-    m_realm->verify_in_write();
     auto& property = property_for_name(prop_name);
-
-    // Modifying primary keys is allowed in migrations to make it possible to
-    // add a new primary key to a type (or change the property type), but it
-    // is otherwise considered the immutable identity of the row
-    if (property.is_primary && !m_realm->is_in_migration())
-        throw ModifyPrimaryKeyException(m_object_schema->name, property.name);
-
+    validate_property_for_setter(property);
     set_property_value_impl(ctx, property, value, policy, false);
 }
 
@@ -185,6 +177,16 @@ Object Object::create(ContextType& ctx, std::shared_ptr<Realm> const& realm,
     return create(ctx, realm, *object_schema, value, policy, current_obj, out_row);
 }
 
+template<typename ValueType, typename ContextType>
+Mixed as_mixed(ContextType& ctx, ValueType& value, PropertyType type)
+{
+    if (!value)
+        return {};
+    return switch_on_type(type, [&](auto* t) {
+        return Mixed(ctx.template unbox<NonObjTypeT<decltype(*t)>>(*value));
+    });
+}
+
 template<typename ValueType, typename ContextType>
 Object Object::create(ContextType& ctx, std::shared_ptr<Realm> const& realm,
                       ObjectSchema const& object_schema, ValueType value,
@@ -192,69 +194,75 @@ Object Object::create(ContextType& ctx, std::shared_ptr<Realm> const& realm,
 {
     realm->verify_in_write();
 
-    // get or create our accessor
+    // When setting each property, we normally want to skip over the primary key
+    // as that's set as part of object creation. However, during migrations the
+    // property marked as the primary key in the schema may not currently be
+    // considered a primary key by core, and so will need to be set.
+    bool skip_primary = true;
+    // If the input value is missing values for any of the properties we want to
+    // set the propery to the default value for new objects, but leave it
+    // untouched for existing objects.
     bool created = false;
 
-    // try to get existing row if updating
     Obj obj;
     auto table = realm->read_group().get_table(object_schema.table_key);
 
-    bool skip_primary = true;
+    // If there's a primary key, we need to first check if an object with the
+    // same primary key already exists. If it does, we either update that object
+    // or throw an exception if updating is disabled.
     if (auto primary_prop = object_schema.primary_key_property()) {
-        // search for existing object based on primary key type
         auto primary_value = ctx.value_for_property(value, *primary_prop,
                                                     primary_prop - &object_schema.persisted_properties[0]);
         if (!primary_value)
             primary_value = ctx.default_value_for_property(object_schema, *primary_prop);
-        if (!primary_value) {
-            if (!is_nullable(primary_prop->type))
-                throw MissingPropertyValueException(object_schema.name, primary_prop->name);
-            primary_value = ctx.null_value();
-        }
-        auto key = get_for_primary_key_impl(ctx, *table, *primary_prop, *primary_value);
-        if (key) {
-            if (policy != CreatePolicy::ForceCreate)
-                obj = table->get_object(key);
-            else if (realm->is_in_migration()) {
-                // Creating objects with duplicate primary keys is allowed in migrations
-                // as long as there are no duplicates at the end, as adding an entirely
-                // new column which is the PK will inherently result in duplicates at first
-                obj = table->create_object();
-                created = true;
-                skip_primary = false;
-            }
-            else {
-                throw std::logic_error(util::format("Attempting to create an object of type '%1' with an existing primary key value '%2'.",
-                                                    object_schema.name, ctx.print(*primary_value)));
+        if (!primary_value && !is_nullable(primary_prop->type))
+            throw MissingPropertyValueException(object_schema.name, primary_prop->name);
+
+        // When changing the primary key of a table, we remove the existing pk (if any), call
+        // the migration function, then add the new pk (if any). This means that we can't call
+        // create_object_with_primary_key(), and creating duplicate primary keys is allowed as
+        // long as they're unique by the end of the migration.
+        if (table->get_primary_key_column() == ColKey{}) {
+            REALM_ASSERT(realm->is_in_migration());
+            if (policy != CreatePolicy::ForceCreate) {
+                if (auto key = get_for_primary_key_impl(ctx, *table, *primary_prop, *primary_value))
+                    obj = table->get_object(key);
             }
+            if (!obj)
+                skip_primary = false;
         }
         else {
-            created = true;
-            Mixed primary_key;
-            if (primary_prop->type == PropertyType::Int) {
-                primary_key = ctx.template unbox<util::Optional<int64_t>>(*primary_value);
-            }
-            else if (primary_prop->type == PropertyType::String) {
-                primary_key = ctx.template unbox<StringData>(*primary_value);
-            }
-            else {
-                REALM_TERMINATE("Unsupported primary key type.");
+            obj = table->create_object_with_primary_key(as_mixed(ctx, primary_value, primary_prop->type), &created);
+            if (!created && policy == CreatePolicy::ForceCreate) {
+                if (!realm->is_in_migration()) {
+                    throw std::logic_error(util::format("Attempting to create an object of type '%1' with an existing primary key value '%2'.",
+                                                        object_schema.name, ctx.print(*primary_value)));
+                }
+                table->set_primary_key_column(ColKey{});
+                skip_primary = false;
+                obj = {};
             }
-            obj = table->create_object_with_primary_key(primary_key);
         }
     }
-    else {
+
+    // No primary key (possibly temporarily due to migrations). If we're
+    // currently performing a recursive update on an existing object tree then
+    // an object key was passed in that we need to look up, and otherwise we
+    // need to create the new object.
+    if (!obj) {
         if (policy == CreatePolicy::UpdateModified && current_obj) {
             obj = table->get_object(current_obj);
         }
         else {
-        obj = table->create_object();
+            obj = table->create_object();
             created = true;
         }
     }
 
-    // populate
     Object object(realm, object_schema, obj);
+    // KVO in Cocoa requires that the obj ivar on the wrapper object be set
+    // *before* we start setting the properties, so it passes in a pointer to
+    // that.
     if (out_row)
         *out_row = obj;
     for (size_t i = 0; i < object_schema.persisted_properties.size(); ++i) {
@@ -271,6 +279,9 @@ Object Object::create(ContextType& ctx, std::shared_ptr<Realm> const& realm,
             v = ctx.default_value_for_property(object_schema, prop);
             is_default = true;
         }
+        // We consider null or a missing value to be equivalent to an empty
+        // array for historical reasons; the original implementation did this
+        // accidentally and it's not worth changing.
         if ((!v || ctx.is_null(*v)) && !is_nullable(prop.type) && !is_array(prop.type)) {
             if (prop.is_primary || !ctx.allow_missing(value))
                 throw MissingPropertyValueException(object_schema.name, prop.name);

+ 13 - 0
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/property.hpp

@@ -173,6 +173,19 @@ inline constexpr bool is_nullable(PropertyType a)
     return to_underlying(a & PropertyType::Nullable) == to_underlying(PropertyType::Nullable);
 }
 
+// Some of the places we use switch_on_type() the Obj version isn't instantiatable
+// or reachable, so we want to map it to a valid type to let the unreachable code compile
+template<typename T>
+struct NonObjType {
+    using type = std::remove_reference_t<T>;
+};
+template<>
+struct NonObjType<Obj&> {
+    using type = int64_t;
+};
+template<typename T>
+using NonObjTypeT = typename NonObjType<T>::type;
+
 template<typename ObjType=Obj, typename Fn>
 static auto switch_on_type(PropertyType type, Fn&& fn)
 {

+ 1 - 14
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/thread_safe_reference.cpp

@@ -109,19 +109,6 @@ private:
     std::string m_object_schema_name;
 };
 
-template<typename T>
-struct ListType {
-    using type = Lst<std::remove_reference_t<T>>;
-};
-
-// The code path which would instantiate List<Obj> isn't reachable, but still
-// produces errors about the type not being instantiable so we instead map it
-// to an arbitrary valid type
-template<>
-struct ListType<Obj&> {
-    using type = Lst<int64_t>;
-};
-
 template<>
 class ThreadSafeReference::PayloadImpl<Results> : public ThreadSafeReference::Payload {
 public:
@@ -161,7 +148,7 @@ public:
                 // match what happens for other types of handover where the
                 // object doesn't exist.
                 switch_on_type(ObjectSchema::from_core_type(*table, m_col_key), [&](auto* t) -> void {
-                    list = std::make_unique<typename ListType<decltype(*t)>::type>();
+                    list = std::make_unique<Lst<NonObjTypeT<decltype(*t)>>>();
                 });
             }
             return Results(r, std::move(list), m_ordering);

+ 206 - 2
Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/migrations.cpp

@@ -716,6 +716,14 @@ TEST_CASE("migration: Automatic") {
             {"array target", {
                 {"value", PropertyType::Int},
             }},
+            {"int pk", {
+                {"pk", PropertyType::Int, Property::IsPrimary{true}},
+                {"value", PropertyType::Int},
+            }},
+            {"string pk", {
+                {"pk", PropertyType::String, Property::IsPrimary{true}},
+                {"value", PropertyType::Int},
+            }},
         };
 
         InMemoryTestFile config;
@@ -909,10 +917,22 @@ TEST_CASE("migration: Automatic") {
             });
         }
 
+        SECTION("upsert in new realm after modifying primary key") {
+            realm->update_schema(schema, 2, [&values](auto, auto new_realm, Schema&) {
+                get_table(new_realm, "all types")->set_primary_key_column(ColKey());
+                REQUIRE(new_realm->is_in_transaction());
+                CppContext ctx(new_realm);
+                any_cast<AnyDict&>(values)["bool"] = false;
+                Object obj = Object::create(ctx, new_realm, "all types", values, CreatePolicy::UpdateAll);
+                REQUIRE(get_table(new_realm, "all types")->size() == 1);
+                REQUIRE(get_table(new_realm, "link target")->size() == 2);
+                REQUIRE(get_table(new_realm, "array target")->size() == 2);
+                REQUIRE(any_cast<bool>(obj.get_property_value<util::Any>(ctx, "bool")) == false);
+            });
+        }
+
         SECTION("change primary key property type") {
             schema = set_type(schema, "all types", "pk", PropertyType::String);
-            // FIXME: changing the primary key of a type with binary columns currently crashes in core
-            schema = remove_property(schema, "all types", "data");
             realm->update_schema(schema, 2, [](auto, auto new_realm, auto&) {
                 Object obj(new_realm, "all types", 0);
 
@@ -943,6 +963,169 @@ TEST_CASE("migration: Automatic") {
             REQUIRE_NOTHROW(realm->update_schema(schema, 2, good_migration));
             REQUIRE(get_table(realm, "all types")->size() == 2);
         }
+
+        SECTION("modify existing int primary key values in migration") {
+            // Create several more objects to increase the chance of things
+            // actually breaking if we're doing invalid things
+            CppContext ctx(realm);
+            auto object_schema = realm->schema().find("all types");
+            realm->begin_transaction();
+            for (int i = 1; i < 10; ++i) {
+                any_cast<AnyDict&>(values)["pk"] = INT64_C(1) + i;
+                any_cast<AnyDict&>(values)["int"] = INT64_C(5) + i;
+                Object::create(ctx, realm, *object_schema, values);
+            }
+            realm->commit_transaction();
+
+            // Increase the PK of each object by one in a migration
+            realm->update_schema(schema, 2, [](auto, auto new_realm, Schema&) {
+                CppContext ctx(new_realm);
+                Results results(new_realm, get_table(new_realm, "all types"));
+                for (size_t i = 0, count = results.size(); i < count; ++i) {
+                    Object obj(new_realm, results.get<Obj>(i));
+                    util::Any v = 1 + any_cast<int64_t>(obj.get_property_value<util::Any>(ctx, "pk"));
+                    obj.set_property_value(ctx, "pk", v);
+                }
+            });
+
+            // Create a new object with the no-longer-used pk of 1
+            realm->begin_transaction();
+            any_cast<AnyDict&>(values)["pk"] = INT64_C(1);
+            any_cast<AnyDict&>(values)["int"] = INT64_C(4);
+            object_schema = realm->schema().find("all types");
+            Object::create(ctx, realm, *object_schema, values);
+            realm->commit_transaction();
+
+            // Verify results
+            auto table = get_table(realm, "all types");
+            REQUIRE(table->size() == 11);
+            REQUIRE(table->get_primary_key_column() == table->get_column_key("pk"));
+            for (int i = 0; i < 10; ++i) {
+                auto obj = table->get_object(i);
+                REQUIRE(obj.get<int64_t>("pk") == i + 2);
+                REQUIRE(obj.get<int64_t>("int") == i + 5);
+            }
+            auto obj = table->get_object(10);
+            REQUIRE(obj.get<int64_t>("pk") == 1);
+            REQUIRE(obj.get<int64_t>("int") == 4);
+        }
+
+        SECTION("modify existing string primary key values in migration") {
+            // Create several objects to increase the chance of things
+            // actually breaking if we're doing invalid things
+            CppContext ctx(realm);
+            auto object_schema = realm->schema().find("string pk");
+            realm->begin_transaction();
+            for (int64_t i = 0; i < 10; ++i) {
+                util::Any values = AnyDict{
+                    {"pk", util::to_string(i)},
+                    {"value", i + 1},
+                };
+                Object::create(ctx, realm, *object_schema, values);
+            }
+            realm->commit_transaction();
+
+            // Increase the PK of each object by one in a migration
+            realm->update_schema(schema, 2, [](auto, auto new_realm, Schema&) {
+                CppContext ctx(new_realm);
+                Results results(new_realm, get_table(new_realm, "string pk"));
+                for (size_t i = 0, count = results.size(); i < count; ++i) {
+                    Object obj(new_realm, results.get<Obj>(i));
+                    util::Any v = util::to_string(any_cast<int64_t>(obj.get_property_value<util::Any>(ctx, "value")));
+                    obj.set_property_value(ctx, "pk", v);
+                }
+            });
+
+            // Create a new object with the no-longer-used pk of 0
+            realm->begin_transaction();
+            util::Any values = AnyDict{
+                {"pk", "0"s},
+                {"value", INT64_C(0)},
+            };
+            object_schema = realm->schema().find("string pk");
+            Object::create(ctx, realm, *object_schema, values);
+            realm->commit_transaction();
+
+            // Verify results
+            auto table = get_table(realm, "string pk");
+            REQUIRE(table->size() == 11);
+            REQUIRE(table->get_primary_key_column() == table->get_column_key("pk"));
+            for (auto& obj : *table) {
+                REQUIRE(util::to_string(obj.get<int64_t>("value")).c_str() == obj.get<StringData>("pk"));
+            }
+        }
+
+        SECTION("create and modify int primary key inside migration") {
+            SECTION("with index") {
+                realm->begin_transaction();
+                auto table = get_table(realm, "int pk");
+                table->add_search_index(table->get_column_key("pk"));
+                realm->commit_transaction();
+            }
+            SECTION("no index") {
+            }
+
+            realm->update_schema(schema, 2, [](auto, auto new_realm, Schema&) {
+                CppContext ctx(new_realm);
+                for (int64_t i = 0; i < 10; ++i) {
+                    auto obj = Object::create(ctx, new_realm, *new_realm->schema().find("int pk"),
+                                              util::Any(AnyDict{
+                        {"pk", INT64_C(0)},
+                        {"value", i}
+                    }));
+                    obj.set_property_value(ctx, "pk", util::Any(i));
+                }
+            });
+
+            auto table = get_table(realm, "int pk");
+            REQUIRE(table->size() == 10);
+            REQUIRE(table->get_primary_key_column() == table->get_column_key("pk"));
+            for (int i = 0; i < 10; ++i) {
+                auto obj = table->get_object(i);
+                REQUIRE(obj.get<int64_t>("pk") == i);
+                REQUIRE(obj.get<int64_t>("value") == i);
+            }
+        }
+
+        SECTION("create and modify string primary key inside migration") {
+            SECTION("with index") {
+                realm->begin_transaction();
+                auto table = get_table(realm, "string pk");
+                table->add_search_index(table->get_column_key("pk"));
+                realm->commit_transaction();
+            }
+            SECTION("no index") {
+            }
+
+            realm->update_schema(schema, 2, [](auto, auto new_realm, Schema&) {
+                CppContext ctx(new_realm);
+                for (int64_t i = 0; i < 10; ++i) {
+                    auto obj = Object::create(ctx, new_realm, *new_realm->schema().find("string pk"),
+                                              util::Any(AnyDict{
+                        {"pk", ""s},
+                        {"value", i}
+                    }));
+                    obj.set_property_value(ctx, "pk", util::Any(util::to_string(i)));
+                }
+            });
+
+            auto table = get_table(realm, "string pk");
+            REQUIRE(table->size() == 10);
+            REQUIRE(table->get_primary_key_column() == table->get_column_key("pk"));
+            for (auto& obj : *table)
+                REQUIRE(obj.get<StringData>("pk") == util::to_string(obj.get<int64_t>("value")).c_str());
+        }
+
+        SECTION("create object after adding primary key") {
+            schema = set_primary_key(schema, "all types", "");
+            realm->update_schema(schema, 2);
+            schema = set_primary_key(schema, "all types", "pk");
+            REQUIRE_NOTHROW(realm->update_schema(schema, 3, [&](auto, auto new_realm, Schema&) {
+                CppContext ctx(new_realm);
+                any_cast<AnyDict&>(values)["pk"] = INT64_C(2);
+                Object::create(ctx, realm, "all types", values);
+            }));
+        }
     }
 
     SECTION("property renaming") {
@@ -1132,6 +1315,27 @@ TEST_CASE("migration: Automatic") {
             schema = set_indexed(schema, "object", "value", true);
             SUCCESSFUL_RENAME(schema, schema2, {"object", "value", "new"});
         }
+
+        SECTION("create object inside migration after renaming pk") {
+            schema = set_primary_key(schema, "object", "value");
+            auto new_schema = set_primary_key(rename_value(schema), "object", "new");
+            init(schema);
+            REQUIRE_NOTHROW(realm->update_schema(new_schema, 2, [](auto, auto realm, Schema& schema) {
+                ObjectStore::rename_property(realm->read_group(), schema,
+                                             "object", "value", "new");
+
+                CppContext ctx(realm);
+                util::Any values = AnyDict{{"new", INT64_C(11)}};
+                Object::create(ctx, realm, "object", values);
+            }));
+            REQUIRE(realm->schema() == new_schema);
+            VERIFY_SCHEMA(*realm, false);
+            auto table = ObjectStore::table_for_object_type(realm->read_group(), "object");
+            auto key = table->get_column_keys()[0];
+            auto it = table->begin();
+            REQUIRE(it->get<int64_t>(key) == 10);
+            REQUIRE((++it)->get<int64_t>(key) == 11);
+        }
     }
 }
 

+ 2 - 2
Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist

@@ -17,11 +17,11 @@
 	<key>CFBundlePackageType</key>
 	<string>FMWK</string>
 	<key>CFBundleShortVersionString</key>
-	<string>5.2.0</string>
+	<string>5.3.2</string>
 	<key>CFBundleSignature</key>
 	<string>????</string>
 	<key>CFBundleVersion</key>
-	<string>5.2.0</string>
+	<string>5.3.2</string>
 	<key>NSHumanReadableCopyright</key>
 	<string>Copyright © 2014 Realm. All rights reserved.</string>
 	<key>NSPrincipalClass</key>

+ 1 - 1
Carthage/Checkouts/realm-cocoa/build.sh

@@ -1551,7 +1551,7 @@ x.y.z Release notes (yyyy-MM-dd)
 * Realm Object Server: 3.21.0 or later.
 * Realm Studio: 3.11 or later.
 * APIs are backwards compatible with all previous releases in the 5.x.y series.
-* Carthage release for Swift is built with Xcode 11.5.
+* Carthage release for Swift is built with Xcode 11.6.
 
 ### Internal
 * Upgraded realm-core from ? to ?

+ 3 - 3
Carthage/Checkouts/realm-cocoa/dependencies.list

@@ -1,4 +1,4 @@
-VERSION=5.2.0
-REALM_CORE_VERSION=6.0.8
-REALM_SYNC_VERSION=5.0.7
+VERSION=5.3.2
+REALM_CORE_VERSION=6.0.12
+REALM_SYNC_VERSION=5.0.12
 REALM_OBJECT_SERVER_VERSION=3.28.5

+ 10 - 8
Carthage/Checkouts/realm-cocoa/examples/installation/build.sh

@@ -40,9 +40,6 @@ command:
   test-watchos-swift-xcframework:  tests watchOS Swift xcframework example.
   test-watchos-swift-cocoapods:    tests watchOS Swift CocoaPods example.
   test-watchos-swift-carthage:     tests watchOS Swift Carthage example.
-  test-watchos-spm:                tests watchOS Swift Package Manager example.
-
-  test-tvos-spm:                   tests tvOS Swift Package Manager example.
 EOF
 }
 
@@ -167,11 +164,9 @@ case "$COMMAND" in
         for target in ios-swift-dynamic ios-swift-cocoapods osx-swift-dynamic ios-swift-carthage osx-swift-carthage; do
             ./build.sh test-$target || exit 1
         done
-        if (( $(xcode_version_major) >= 11 )); then
-            for target in ios osx watchos tvos; do
-                ./build.sh test-$target-spm || exit 1
-            done
-        fi
+        for target in ios osx; do
+            ./build.sh test-$target-spm || exit 1
+        done
         ;;
 
     test-*-*-cocoapods)
@@ -199,6 +194,13 @@ case "$COMMAND" in
         ;;
 
     test-ios-spm)
+        # We have to "hide" the spm example from carthage because otherwise
+        # it'll fetch the example's package dependencies as part of deciding
+        # what to build from this repo.
+        if ! [ -L ios/swift/SwiftPackageManagerExample/SwiftPackageManagerExample.xcodeproj/project.pbxproj ]; then
+            mkdir -p ios/swift/SwiftPackageManagerExample/SwiftPackageManagerExample.xcodeproj
+            ln -s ../project.pbxproj ios/swift/SwiftPackageManagerExample/SwiftPackageManagerExample.xcodeproj
+        fi
         xctest "$PLATFORM" swift SwiftPackageManagerExample
         ;;
 

+ 1 - 1
Carthage/Checkouts/realm-cocoa/scripts/package_examples.rb

@@ -41,7 +41,7 @@ base_examples = [
   "examples/tvos/swift",
 ]
 
-xcode_versions = %w(11.3 11.4.1 11.5)
+xcode_versions = %w(11.3 11.4.1 11.5 11.6)
 
 # Remove reference to Realm.xcodeproj from all example workspaces.
 base_examples.each do |example|

+ 8 - 8
Nextcloud.xcodeproj/project.pbxproj

@@ -2199,7 +2199,7 @@
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 7;
+				CURRENT_PROJECT_VERSION = 8;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2250,7 +2250,7 @@
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 7;
+				CURRENT_PROJECT_VERSION = 8;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2293,7 +2293,7 @@
 				CODE_SIGN_ENTITLEMENTS = iOSClient/Brand/Share.entitlements;
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
-				CURRENT_PROJECT_VERSION = 7;
+				CURRENT_PROJECT_VERSION = 8;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2337,7 +2337,7 @@
 				CODE_SIGN_ENTITLEMENTS = iOSClient/Brand/Share.entitlements;
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
-				CURRENT_PROJECT_VERSION = 7;
+				CURRENT_PROJECT_VERSION = 8;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2387,7 +2387,7 @@
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 7;
+				CURRENT_PROJECT_VERSION = 8;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2437,7 +2437,7 @@
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 7;
+				CURRENT_PROJECT_VERSION = 8;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2479,7 +2479,7 @@
 				CODE_SIGN_ENTITLEMENTS = iOSClient/Brand/iOSClient.entitlements;
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
-				CURRENT_PROJECT_VERSION = 7;
+				CURRENT_PROJECT_VERSION = 8;
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				ENABLE_BITCODE = YES;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2524,7 +2524,7 @@
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				COPY_PHASE_STRIP = NO;
-				CURRENT_PROJECT_VERSION = 7;
+				CURRENT_PROJECT_VERSION = 8;
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				ENABLE_BITCODE = YES;
 				FRAMEWORK_SEARCH_PATHS = (

+ 1 - 1
iOSClient/Activity/NCActivity.swift

@@ -361,7 +361,7 @@ extension activityTableViewCell: UICollectionViewDelegate {
                         viewController.path = result.filePath
                         (responder as? UIViewController)!.navigationController?.pushViewController(viewController, animated: true)
                     } else {
-                        NCContentPresenter.shared.messageNotification("_error_", description: "_trash_file_not_found_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0)
+                        NCContentPresenter.shared.messageNotification("_error_", description: "_trash_file_not_found_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError))
                     }
                 }
             }

+ 1 - 1
iOSClient/AppDelegate.m

@@ -838,7 +838,7 @@
         UIViewController *vc = _activeMain.splitViewController.viewControllers[0];
         [self showMenuInViewController: vc];
     } else {
-        [[NCContentPresenter shared] messageNotification:@"_warning_" description:@"_no_permission_add_file_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0];
+        [[NCContentPresenter shared] messageNotification:@"_warning_" description:@"_no_permission_add_file_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorInternalError forced:false];
     }
 }
 

+ 2 - 2
iOSClient/Database/NCManageDatabase.swift

@@ -131,7 +131,7 @@ class NCManageDatabase: NSObject {
                 if let databaseFilePath = databaseFilePath {
                     do {
                         #if !EXTENSION
-                        NCContentPresenter.shared.messageNotification("_error_", description: "_database_corrupt_", delay: TimeInterval(k_dismissAfterSecondLong), type: NCContentPresenter.messageType.info, errorCode: 0)
+                        NCContentPresenter.shared.messageNotification("_error_", description: "_database_corrupt_", delay: TimeInterval(k_dismissAfterSecondLong), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError), forced: true)
                         #endif
                         try FileManager.default.removeItem(at: databaseFilePath)
                     } catch {}
@@ -153,7 +153,7 @@ class NCManageDatabase: NSObject {
             if let databaseFilePath = databaseFilePath {
                 do {
                     #if !EXTENSION
-                    NCContentPresenter.shared.messageNotification("_error_", description: "_database_corrupt_", delay: TimeInterval(k_dismissAfterSecondLong), type: NCContentPresenter.messageType.info, errorCode: 0)
+                    NCContentPresenter.shared.messageNotification("_error_", description: "_database_corrupt_", delay: TimeInterval(k_dismissAfterSecondLong), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError), forced: true)
                     #endif
                     try FileManager.default.removeItem(at: databaseFilePath)
                 } catch {}

+ 3 - 3
iOSClient/Favorites/CCFavorites.m

@@ -524,7 +524,7 @@
                 
             if (tableDirectory.e2eEncrypted && ![CCUtility isEndToEndEnabled:appDelegate.activeAccount]) {
                     
-                [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_e2e_goto_settings_for_enable_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0];
+                [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_e2e_goto_settings_for_enable_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorInternalError forced:false];
                     
             } else {
                     
@@ -537,7 +537,7 @@
                         if (NCCommunication.shared.isNetworkReachable) {
                             [self shouldPerformSegue:self.metadata selector:@""];
                         } else {
-                            [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_go_online_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0];
+                            [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_go_online_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorInternalError forced:false];
                         }
                         
                     } else if ([self.metadata.typeFile isEqualToString: k_metadataTypeFile_document] && [[NCUtility sharedInstance] isRichDocument:self.metadata]) {
@@ -545,7 +545,7 @@
                         if (NCCommunication.shared.isNetworkReachable) {
                             [self shouldPerformSegue:self.metadata selector:@""];
                         } else {
-                            [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_go_online_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0];
+                            [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_go_online_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorInternalError forced:false];
                         }
                         
                 } else {

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

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

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


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

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

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


+ 0 - 26
iOSClient/Images.xcassets/uploadCloud.imageset/Contents.json

@@ -1,26 +0,0 @@
-{
-  "images" : [
-    {
-      "idiom" : "universal",
-      "filename" : "uploadCloud.png",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "uploadCloud@2x.png",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "uploadCloud@3x.png",
-      "scale" : "3x"
-    }
-  ],
-  "info" : {
-    "version" : 1,
-    "author" : "xcode"
-  },
-  "properties" : {
-    "template-rendering-intent" : "template"
-  }
-}

BIN
iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud.png


BIN
iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud@2x.png


BIN
iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud@3x.png


+ 4 - 4
iOSClient/Login/NCAppConfigView.swift

@@ -61,15 +61,15 @@ class NCAppConfigView: UIViewController {
         appDelegate.timerErrorNetworking.invalidate()
         
         guard let serverUrl = self.serverUrl else {
-            NCContentPresenter.shared.messageNotification("_error_", description: "User Default, serverUrl not found", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0)
+            NCContentPresenter.shared.messageNotification("_error_", description: "User Default, serverUrl not found", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true)
             return
         }
         guard let username = self.username else {
-            NCContentPresenter.shared.messageNotification("_error_", description: "User Default, username not found", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0)
+            NCContentPresenter.shared.messageNotification("_error_", description: "User Default, username not found", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true)
             return
         }
         guard let password = self.password else {
-            NCContentPresenter.shared.messageNotification("_error_", description: "User Default, password not found", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0)
+            NCContentPresenter.shared.messageNotification("_error_", description: "User Default, password not found", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true)
             return
         }
         
@@ -86,7 +86,7 @@ class NCAppConfigView: UIViewController {
                     NCManageDatabase.sharedInstance.addAccount(account, url: serverUrl, user: username, password: token!)
                     
                     guard let tableAccount = NCManageDatabase.sharedInstance.setAccountActive(account) else {
-                        NCContentPresenter.shared.messageNotification("_error_", description: "setAccountActive error", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0)
+                        NCContentPresenter.shared.messageNotification("_error_", description: "setAccountActive error", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true)
                         self.dismiss(animated: true, completion: nil)
                         return
                     }

+ 1 - 1
iOSClient/Login/NCLoginWeb.swift

@@ -78,7 +78,7 @@ class NCLoginWeb: UIViewController {
         if let url = URL(string: urlBase) {
             loadWebPage(webView: webView!, url: url)
         } else {
-            NCContentPresenter.shared.messageNotification("_error_", description: "_login_url_error_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0)
+            NCContentPresenter.shared.messageNotification("_error_", description: "_login_url_error_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true)
         }
     }
     

+ 21 - 20
iOSClient/Main/CCMain.m

@@ -473,7 +473,7 @@
     }
     
     if (errorCode != 0 && self.view.window != nil) {
-        [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode];
+        [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:false];
     }
 }
 
@@ -496,7 +496,7 @@
     }
     
     if (errorCode != 0 && self.view.window != nil) {
-        [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode];
+        [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:false];
     }
 }
 
@@ -519,7 +519,7 @@
     }
     
     if (errorCode != 0 && self.view.window != nil) {
-        [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode];
+        [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:false];
     }
 }
 
@@ -549,7 +549,7 @@
         }
         
     } else {
-        [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode];
+        [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:false];
     }
 }
 
@@ -796,12 +796,12 @@
 
                 } else {
                                         
-                    [[NCContentPresenter shared] messageNotification:@"_error_" description:error.description delay:k_dismissAfterSecond type:messageTypeError errorCode:error.code];
+                    [[NCContentPresenter shared] messageNotification:@"_error_" description:error.description delay:k_dismissAfterSecond type:messageTypeError errorCode:error.code forced:false];
                 }
                 
             } else {
                 
-                [[NCContentPresenter shared] messageNotification:@"_error_" description:@"_read_file_error_" delay:k_dismissAfterSecond type:messageTypeError errorCode:error.code];
+                [[NCContentPresenter shared] messageNotification:@"_error_" description:@"_read_file_error_" delay:k_dismissAfterSecond type:messageTypeError errorCode:error.code forced:false];
             }
         }];
     }
@@ -863,7 +863,7 @@
         if (image)
             UIImageWriteToSavedPhotosAlbum(image, self, @selector(saveSelectedFilesSelector: didFinishSavingWithError: contextInfo:), nil);
         else
-            [[NCContentPresenter shared] messageNotification:@"_save_selected_files_" description:@"_file_not_saved_cameraroll_" delay:k_dismissAfterSecond type:messageTypeError errorCode:k_CCErrorInternalError];
+            [[NCContentPresenter shared] messageNotification:@"_save_selected_files_" description:@"_file_not_saved_cameraroll_" delay:k_dismissAfterSecond type:messageTypeError errorCode:k_CCErrorInternalError forced:false];
     }
     
     if ([metadata.typeFile isEqualToString: k_metadataTypeFile_video] && status == PHAuthorizationStatusAuthorized) {
@@ -872,7 +872,7 @@
             
             UISaveVideoAtPathToSavedPhotosAlbum(fileNamePath, self, @selector(saveSelectedFilesSelector: didFinishSavingWithError: contextInfo:), nil);
         } else {
-            [[NCContentPresenter shared] messageNotification:@"_save_selected_files_" description:@"_file_not_saved_cameraroll_" delay:k_dismissAfterSecond type:messageTypeError errorCode:k_CCErrorInternalError];
+            [[NCContentPresenter shared] messageNotification:@"_save_selected_files_" description:@"_file_not_saved_cameraroll_" delay:k_dismissAfterSecond type:messageTypeError errorCode:k_CCErrorInternalError forced:false];
         }
     }
     
@@ -889,7 +889,7 @@
 - (void)saveSelectedFilesSelector:(NSString *)path didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
 {
     if (error) {
-        [[NCContentPresenter shared] messageNotification:@"_save_selected_files_" description:@"_file_not_saved_cameraroll_" delay:k_dismissAfterSecond type:messageTypeError errorCode:error.code];
+        [[NCContentPresenter shared] messageNotification:@"_save_selected_files_" description:@"_file_not_saved_cameraroll_" delay:k_dismissAfterSecond type:messageTypeError errorCode:error.code forced:false];
     }
 }
 
@@ -1137,12 +1137,12 @@
                             BOOL result = [[NCEndToEndMetadata sharedInstance] decoderMetadata:e2eMetadata privateKey:[CCUtility getEndToEndPrivateKey:account] serverUrl:self.serverUrl account:account url:appDelegate.activeUrl];
                             
                             if (result == false) {
-                                [[NCContentPresenter shared] messageNotification:@"_error_e2ee_" description:@"_e2e_error_decode_metadata_" delay:k_dismissAfterSecond type:messageTypeError errorCode:k_CCErrorInternalError];
+                                [[NCContentPresenter shared] messageNotification:@"_error_e2ee_" description:@"_e2e_error_decode_metadata_" delay:k_dismissAfterSecond type:messageTypeError errorCode:k_CCErrorInternalError forced:true];
                             }
                                                         
                         } else if (errorCode != 404) {
                             
-                            [[NCContentPresenter shared] messageNotification:@"_e2e_error_get_metadata_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode];
+                            [[NCContentPresenter shared] messageNotification:@"_e2e_error_get_metadata_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:true];
                         }
                         
                        [self reloadDatasource:_serverUrl ocId:nil];
@@ -1150,12 +1150,12 @@
                     
                 } else {
                     
-                    [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_e2e_goto_settings_for_enable_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0];
+                    [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_e2e_goto_settings_for_enable_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorInternalError forced:true];
                 }
             }
             
         } else {
-            [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode];
+            [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:true];
         }
         
         _loadingFolder = NO;
@@ -1185,7 +1185,7 @@
             }
             
         } else if (errorCode != 0) {
-            [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode];
+            [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:false];
         }
     }];
 }
@@ -1219,10 +1219,11 @@
          } else {
              
              if (errorCode != 0) {
-                 [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode];
+                 [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:true];
              }
              
              _searchFileName = @"";
+             [self cancelSearchBar];
          }
         
     }];
@@ -1373,7 +1374,7 @@
         // E2EE DENIED
         if ([CCUtility isFolderEncrypted:serverUrl e2eEncrypted:metadata.e2eEncrypted account:appDelegate.activeAccount]) {
             
-            [[NCContentPresenter shared] messageNotification:@"_move_" description:@"Not possible move files to encrypted directory" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0];
+            [[NCContentPresenter shared] messageNotification:@"_move_" description:@"Not possible move files to encrypted directory" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorInternalError forced:true];
             return;
         }
         
@@ -2457,7 +2458,7 @@
             
             if (_metadataFolder.e2eEncrypted && ![CCUtility isEndToEndEnabled:appDelegate.activeAccount]) {
                 
-                [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_e2e_goto_settings_for_enable_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0];
+                [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_e2e_goto_settings_for_enable_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorInternalError forced:true];
                 
             } else {
             
@@ -2470,7 +2471,7 @@
                     if (NCCommunication.shared.isNetworkReachable) {
                         [self shouldPerformSegue:self.metadata selector:@""];
                     } else {
-                        [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_go_online_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0];
+                        [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_go_online_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorInternalError forced:true];
                     }
                     
                 } else if ([self.metadata.typeFile isEqualToString: k_metadataTypeFile_document] && [[NCUtility sharedInstance] isRichDocument:self.metadata]) {
@@ -2478,7 +2479,7 @@
                     if (NCCommunication.shared.isNetworkReachable) {
                         [self shouldPerformSegue:self.metadata selector:@""];
                     } else {
-                        [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_go_online_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0];
+                        [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_go_online_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorInternalError forced:true];
                     }
                     
                 } else {
@@ -2606,7 +2607,7 @@
         // E2EE Check enable
         if (metadata.e2eEncrypted && [CCUtility isEndToEndEnabled:appDelegate.activeAccount] == NO) {
             
-            [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_e2e_goto_settings_for_enable_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0];
+            [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_e2e_goto_settings_for_enable_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorInternalError forced:true];
             return;
         }
         

+ 1 - 1
iOSClient/Main/Create cloud/NCCreateFormUploadAssets.swift

@@ -277,7 +277,7 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate {
                     
                     self.reloadFormRow(formRow)
                     
-                    NCContentPresenter.shared.messageNotification("_info_", description: "_forbidden_characters_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0)
+                    NCContentPresenter.shared.messageNotification("_info_", description: "_forbidden_characters_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError))
                 }
             }
             

+ 1 - 1
iOSClient/Main/Create cloud/NCCreateFormUploadConflict.swift

@@ -148,7 +148,7 @@ extension NCCreateFormUploadConflictDelegate {
             }
             
             switchAlreadyExistingFiles.isOn = true
-            NCContentPresenter.shared.messageNotification("_info_", description: "_file_not_rewite_doc_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0)
+            NCContentPresenter.shared.messageNotification("_info_", description: "_file_not_rewite_doc_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError))
         }
         
         tableView.reloadData()

+ 4 - 4
iOSClient/Main/Create cloud/NCCreateFormUploadScanDocument.swift

@@ -445,7 +445,7 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC
     func dismissAndUpload(_ metadata: tableMetadata) {
         
         guard let fileNameGenerateExport = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView) else {
-            NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0)
+            NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError))
             return
         }
         
@@ -475,7 +475,7 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC
                 do {
                     try textFile.write(to: NSURL(fileURLWithPath: fileNameGenerateExport) as URL  , atomically: true, encoding: .utf8)
                 } catch {
-                    NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0)
+                    NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError))
                     return
                 }
             }
@@ -553,14 +553,14 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC
             let image =  changeImageFromQuality(self.arrayImages[0], dpiQuality: dpiQuality)
             
             guard let data = image.jpegData(compressionQuality: CGFloat(0.5)) else {
-                NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0)
+                NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError))
                 return
             }
             
             do {
                 try data.write(to: NSURL.fileURL(withPath: fileNameGenerateExport), options: .atomic)
             } catch {
-                NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0)
+                NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError))
                 return
             }
         }

+ 6 - 18
iOSClient/Main/NCMainCommon.swift

@@ -671,34 +671,22 @@ class NCMainCommon: NSObject, NCAudioRecorderViewControllerDelegate, UIDocumentI
 
             if iconFileExists {
                 cell.file.image =  UIImage(contentsOfFile: CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag))
-            } else if(!metadata.hasPreview){
-                if metadata.iconName.count > 0 {
-                    cell.file.image = UIImage.init(named: metadata.iconName)
+            } else {
+                if metadata.status == k_metadataStatusWaitUpload || metadata.status == k_metadataStatusInUpload || metadata.status == k_metadataStatusUploading || metadata.status == k_metadataStatusUploadError {
+                
+                    cell.file.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "cloudUpload"), width: 100, height: 100, color: NCBrandColor.sharedInstance.brandElement)
+                
                 } else {
-                    cell.file.image = UIImage.init(named: "file")
-                }
-            }           
-            
-            // uploadFile
-            if metadata.status == k_metadataStatusWaitUpload || metadata.status == k_metadataStatusInUpload || metadata.status == k_metadataStatusUploading || metadata.status == k_metadataStatusUploadError {
                 
-                if (!iconFileExists) {
-                    cell.file.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "uploadCloud"), multiplier: 2, color: NCBrandColor.sharedInstance.brandElement)
+                    cell.file.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "cloudDownload"), width: 100, height: 100, color: NCBrandColor.sharedInstance.brandElement)
                 }
-                
-                cell.labelTitle.isEnabled = false
             }
             
             // uploadFileError
             if metadata.status == k_metadataStatusUploadError {
                 
-                cell.labelTitle.isEnabled = false
                 cell.status.image = UIImage.init(named: "statuserror")
                 
-                if !iconFileExists {
-                    cell.file.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "uploadCloud"), multiplier: 2, color: NCBrandColor.sharedInstance.brandElement)
-                }
-                
                 if metadata.sessionError.count == 0 {
                     cell.labelInfoFile.text = NSLocalizedString("_error_", comment: "") + ", " + NSLocalizedString("_file_not_uploaded_", comment: "")
                 } else {

+ 0 - 79
iOSClient/Networking/NCNetworking.swift

@@ -471,86 +471,7 @@ import Alamofire
             NotificationCenter.default.postOnMainThread(name: k_notificationCenter_reloadDataSource, userInfo: ["ocId":metadata.ocId, "serverUrl":metadata.serverUrl])
         }
     }
-    
-    //MARK: - Download / Upload
-    
-    @objc func verifyTransfer() {
-        
-        var session: URLSession?
-        
-        // download
-        var metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "status == %d", Int(k_metadataStatusDownloading)))
-        for metadata in metadatas {
-            guard let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView) else { continue }
-            let request = downloadRequest[fileNameLocalPath]
-            if request == nil {
-                NCManageDatabase.sharedInstance.setMetadataSession(ocId: metadata.ocId, session: "", sessionError: "", sessionSelector: "", sessionTaskIdentifier: 0, status: Int(k_metadataStatusNormal))
-                
-                NotificationCenter.default.postOnMainThread(name: k_notificationCenter_reloadDataSource, userInfo: ["ocId":metadata.ocId, "serverUrl":metadata.serverUrl])
-            }
-        }
-        
         
-        // upload
-        metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "session == %@ AND status == %d", NCCommunicationCommon.shared.sessionIdentifierUpload ,Int(k_metadataStatusUploading)))
-        for metadata in metadatas {
-            guard let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView) else { continue }
-            let request = uploadRequest[fileNameLocalPath]
-            if request == nil {
-                CCUtility.removeFile(atPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId))
-                NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-                
-                NotificationCenter.default.postOnMainThread(name: k_notificationCenter_reloadDataSource, userInfo: ["serverUrl":metadata.serverUrl])
-            }
-        }
-        
-        
-        // k_metadataStatusUploading (BACKGROUND)
-        let sessionBackground = NCCommunicationCommon.shared.sessionIdentifierBackground
-        let sessionBackgroundWWan = NCCommunicationCommon.shared.sessionIdentifierBackgroundWWan
-        metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "(session == %@ OR session == %@) AND status == %d", sessionBackground, sessionBackgroundWWan, k_metadataStatusUploading))
-        for metadata in metadatas {
-            
-            if metadata.session == NCCommunicationCommon.shared.sessionIdentifierBackground {
-                session = NCCommunicationBackground.shared.sessionManagerTransfer
-            } else if metadata.session == NCCommunicationCommon.shared.sessionIdentifierBackgroundWWan {
-                session = NCCommunicationBackground.shared.sessionManagerTransferWWan
-            } else if metadata.session == NCCommunicationCommon.shared.sessionIdentifierExtension {
-                session = NCCommunicationBackground.shared.sessionManagerTransferExtension
-            }
-            
-            var findTask = false
-            
-            session?.getAllTasks(completionHandler: { (tasks) in
-                for task in tasks {
-                    if task.taskIdentifier == metadata.sessionTaskIdentifier {
-                        findTask = true
-                    }
-                }
-                
-                if !findTask {
-                    DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
-                        if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@ AND status == %d", metadata.ocId, k_metadataStatusUploading)) {
-                            NCManageDatabase.sharedInstance.setMetadataSession(ocId: metadata.ocId, session: NCCommunicationCommon.shared.sessionIdentifierBackground, sessionError: "", sessionSelector: nil, sessionTaskIdentifier: 0, status: Int(k_metadataStatusWaitUpload))
-                        }
-                    }
-                }
-            })
-        }
-        
-        
-        // verify k_metadataStatusInUpload (BACKGROUND)
-        metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "(session == %@ OR session == %@) AND status == %d AND sessionTaskIdentifier == 0", sessionBackground, sessionBackgroundWWan, k_metadataStatusInUpload))
-        for metadata in metadatas {
-            DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
-                if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@ AND status == %d AND sessionTaskIdentifier == 0", metadata.ocId, k_metadataStatusInUpload)) {
-                    NCManageDatabase.sharedInstance.setMetadataSession(ocId: metadata.ocId, session: NCCommunicationCommon.shared.sessionIdentifierBackground, sessionError: "", sessionSelector: nil, sessionTaskIdentifier: 0, status: Int(k_metadataStatusWaitUpload))
-                }
-            }
-        }
-        
-    }
-    
     //MARK: - WebDav Read file, folder
     
     @objc func readFolder(serverUrl: String, account: String, completion: @escaping (_ account: String, _ metadataFolder: tableMetadata?, _ metadatas: [tableMetadata]?, _ metadatasChanged: [tableMetadata]?, _ errorCode: Int, _ errorDescription: String)->()) {

+ 1 - 1
iOSClient/Networking/NCNetworkingNotificationCenter.swift

@@ -86,7 +86,7 @@ import Foundation
                         if metadata.typeFile == k_metadataTypeFile_imagemeter {
                             
                             if !IMUtility.shared.IMUnzip(metadata: metadata) {
-                                NCContentPresenter.shared.messageNotification("_error_", description: "Bundle imagemeter error. 🤷‍♂️", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0)
+                                NCContentPresenter.shared.messageNotification("_error_", description: "Bundle imagemeter error. 🤷‍♂️", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError))
                                 return
                             }
                             

+ 1 - 1
iOSClient/Networking/NCOperationQueue.swift

@@ -200,7 +200,7 @@ class NCOperationSynchronization: ConcurrentOperation {
                         NCManageDatabase.sharedInstance.convertNCCommunicationFilesToMetadatas(files, useMetadataFolder: useMetadataFolder, account: account) { (metadataFolder, metadatasFolder, metadatas) in
                             if metadatas.count > 0 {
                                 let metadatasResult = NCManageDatabase.sharedInstance.getMetadatas(predicate: predicate)
-                                let metadatasChanged = NCManageDatabase.sharedInstance.updateMetadatas(metadatas, metadatasResult: metadatasResult)
+                                let metadatasChanged = NCManageDatabase.sharedInstance.updateMetadatas(metadatas, metadatasResult: metadatasResult, withVerifyLocal: download)
                                 if download {
                                     for metadata in metadatasChanged {
                                         NCNetworking.shared.download(metadata: metadata, selector: selectorDownloadSynchronize) { (_) in }                                        

+ 2 - 2
iOSClient/RichWorkspace/NCRichWorkspaceCommon.swift

@@ -31,7 +31,7 @@ import NCCommunication
     @objc func createViewerNextcloudText(serverUrl: String,viewController: UIViewController) {
         
         if !NCCommunication.shared.isNetworkReachable() {
-            NCContentPresenter.shared.messageNotification("_error_", description: "_go_online_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0)
+            NCContentPresenter.shared.messageNotification("_error_", description: "_go_online_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError), forced: true)
             return;
         }
         
@@ -64,7 +64,7 @@ import NCCommunication
         
         if !NCCommunication.shared.isNetworkReachable() {
             
-            NCContentPresenter.shared.messageNotification("_error_", description: "_go_online_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0)
+            NCContentPresenter.shared.messageNotification("_error_", description: "_go_online_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError), forced: true)
             return;
         }
         

+ 1 - 1
iOSClient/Settings/CCManageAutoUpload.m

@@ -487,7 +487,7 @@
     if (serverUrl != nil) {
         
         if ([serverUrl isEqualToString:[CCUtility getHomeServerUrlActiveUrl:appDelegate.activeUrl]]) {
-            [[NCContentPresenter shared] messageNotification:@"_error_" description:@"_autoupload_error_select_folder_" delay:k_dismissAfterSecond type:messageTypeError errorCode:0];
+            [[NCContentPresenter shared] messageNotification:@"_error_" description:@"_autoupload_error_select_folder_" delay:k_dismissAfterSecond type:messageTypeError errorCode:k_CCErrorInternalError forced:true];
             return;
         }
         

+ 1 - 1
iOSClient/Settings/NCManageAutoUploadFileName.swift

@@ -170,7 +170,7 @@ class NCManageAutoUploadFileName: XLFormViewController {
                     
                     self.reloadFormRow(formRow)
                     
-                    NCContentPresenter.shared.messageNotification("_info_", description: "_forbidden_characters_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0)
+                    NCContentPresenter.shared.messageNotification("_info_", description: "_forbidden_characters_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError), forced: true)
                 }
             }
             

+ 5 - 5
iOSClient/Settings/NCManageEndToEndEncryption.m

@@ -47,7 +47,7 @@
     NSString *versionE2EE = [[NCManageDatabase sharedInstance] getCapabilitiesServerStringWithAccount:appDelegate.activeAccount elements:NCElementsJSON.shared.capabilitiesE2EEApiVersion];
     
     if (![versionE2EE isEqual:k_E2EE_API] && isE2EEEnabled) {
-        [[NCContentPresenter shared] messageNotification:@"_error_e2ee_" description:@"_err_e2ee_app_version_" delay:k_dismissAfterSecond type:messageTypeError errorCode:k_CCErrorInternalError];
+        [[NCContentPresenter shared] messageNotification:@"_error_e2ee_" description:@"_err_e2ee_app_version_" delay:k_dismissAfterSecond type:messageTypeError errorCode:k_CCErrorInternalError forced:true];
     }
     
     if (isE2EEEnabled == NO || ![versionE2EE isEqual:k_E2EE_API]) {
@@ -370,9 +370,9 @@
     
     [[NCCommunication shared] deleteE2EEPublicKeyWithCustomUserAgent:nil addCustomHeaders:nil completionHandler:^(NSString *account, NSInteger errorCode, NSString *errorDescription) {
        if (errorCode == 0 && [account isEqualToString:appDelegate.activeAccount]) {
-            [[NCContentPresenter shared] messageNotification:@"E2E delete publicKey" description:@"Success" delay:k_dismissAfterSecond type:messageTypeSuccess errorCode:0];
+            [[NCContentPresenter shared] messageNotification:@"E2E delete publicKey" description:@"Success" delay:k_dismissAfterSecond type:messageTypeSuccess errorCode:k_CCErrorInternalError forced:true];
         } else {
-            [[NCContentPresenter shared] messageNotification:@"E2E delete publicKey" description:errorDescription  delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode];
+            [[NCContentPresenter shared] messageNotification:@"E2E delete publicKey" description:errorDescription  delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:true];
         }
     }];
 }
@@ -383,9 +383,9 @@
     
     [[NCCommunication shared] deleteE2EEPrivateKeyWithCustomUserAgent:nil addCustomHeaders:nil completionHandler:^(NSString *account, NSInteger errorCode, NSString *errorDescription) {
         if (errorCode == 0 && [account isEqualToString:appDelegate.activeAccount]) {
-            [[NCContentPresenter shared] messageNotification:@"E2E delete privateKey" description:@"Success" delay:k_dismissAfterSecond type:messageTypeSuccess errorCode:0];
+            [[NCContentPresenter shared] messageNotification:@"E2E delete privateKey" description:@"Success" delay:k_dismissAfterSecond type:messageTypeSuccess errorCode:k_CCErrorInternalError forced:true];
         } else {
-            [[NCContentPresenter shared] messageNotification:@"E2E delete privateKey" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode];
+            [[NCContentPresenter shared] messageNotification:@"E2E delete privateKey" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:true];
         }
     }];
 }

+ 6 - 6
iOSClient/Share/NCShareNetworking.swift

@@ -52,7 +52,7 @@ class NCShareNetworking: NSObject {
                 NCManageDatabase.sharedInstance.addShare(account: self.metadata.account, activeUrl: self.activeUrl, shares: shares!)
                 self.appDelegate.shares = NCManageDatabase.sharedInstance.getTableShares(account: self.metadata.account)
             } else {
-                NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0)
+                NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true)
             }
             self.delegate?.readShareCompleted()
         }
@@ -67,7 +67,7 @@ class NCShareNetworking: NSObject {
                 NCManageDatabase.sharedInstance.addShare(account: self.metadata.account, activeUrl: self.activeUrl, shares: [share!])
                 self.appDelegate.shares = NCManageDatabase.sharedInstance.getTableShares(account: self.metadata.account)
             } else if errorCode != 0 {
-                NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0)
+                NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true)
             }
             self.delegate?.shareCompleted()
         }
@@ -84,7 +84,7 @@ class NCShareNetworking: NSObject {
                 NCManageDatabase.sharedInstance.addShare(account: self.metadata.account, activeUrl: self.activeUrl, shares: [share!])
                 self.appDelegate.shares = NCManageDatabase.sharedInstance.getTableShares(account: self.metadata.account)
             } else {
-                NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0)
+                NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true)
             }
             self.delegate?.shareCompleted()
         }
@@ -98,7 +98,7 @@ class NCShareNetworking: NSObject {
                 NCManageDatabase.sharedInstance.deleteTableShare(account: account, idShare: idShare)
                 self.delegate?.unShareCompleted()
             } else {
-                NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0)
+                NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true)
             }
         }
     }
@@ -112,7 +112,7 @@ class NCShareNetworking: NSObject {
                 self.appDelegate.shares = NCManageDatabase.sharedInstance.getTableShares(account: self.metadata.account)
                 self.delegate?.readShareCompleted()
             } else {
-                NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0)
+                NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true)
                 self.delegate?.updateShareWithError(idShare: idShare)
             }
         }
@@ -125,7 +125,7 @@ class NCShareNetworking: NSObject {
             if errorCode == 0 {
                 self.delegate?.getSharees(sharees: sharees)
             } else {
-                NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0)
+                NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true)
                 self.delegate?.getSharees(sharees: nil)
             }
         }

+ 1 - 1
iOSClient/Shares/NCShares.m

@@ -170,7 +170,7 @@
             [self reloadDatasource];
             
         } else if (errorCode != 0) {
-            [[NCContentPresenter shared] messageNotification:@"_share_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode];
+            [[NCContentPresenter shared] messageNotification:@"_share_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:true];
         } else {
             NSLog(@"[LOG] It has been changed user during networking process, error.");
         }

+ 4 - 4
iOSClient/UploadFromOtherUpp/CCUploadFromOtherUpp.storyboard

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15705" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina4_7" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <scenes>
@@ -106,7 +106,7 @@
                                                 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xRI-9K-ta8">
                                                     <rect key="frame" x="32" y="0.0" width="311" height="62"/>
                                                     <subviews>
-                                                        <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="uploadCloud" translatesAutoresizingMaskIntoConstraints="NO" id="lAw-g4-lYL">
+                                                        <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cloudUpload" translatesAutoresizingMaskIntoConstraints="NO" id="lAw-g4-lYL">
                                                             <rect key="frame" x="16" y="11" width="40" height="40"/>
                                                             <color key="tintColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                             <constraints>
@@ -191,7 +191,7 @@
         </scene>
     </scenes>
     <resources>
+        <image name="cloudUpload" width="425" height="425"/>
         <image name="folder" width="300" height="300"/>
-        <image name="uploadCloud" width="25" height="25"/>
     </resources>
 </document>

+ 10 - 8
iOSClient/Utility/NCContentPresenter.swift

@@ -64,16 +64,18 @@ class NCContentPresenter: NSObject {
 
     //MARK: - Message
     
-    @objc func messageNotification(_ title: String, description: String?, delay: TimeInterval, type: messageType, errorCode: Int) {
+    @objc func messageNotification(_ title: String, description: String?, delay: TimeInterval, type: messageType, errorCode: Int, forced: Bool = false) {
                        
         // No notification message
-        if errorCode == -999 { return }         // Cancelled transfer
-        else if errorCode == 200 { return }     // Transfer stopped
-        else if errorCode == 207 { return }     // WebDAV multistatus
-        else if errorCode == 423 { return }     // WebDAV locked
-        else if errorCode == -1001 { return }   // Time out
-        else if errorCode == -1005 { return }   // Connection lost
-        else if errorCode == 0 && type == messageType.error { return }
+        if forced == false {
+            if errorCode == -999 { return }         // Cancelled transfer
+            else if errorCode == 200 { return }     // Transfer stopped
+            else if errorCode == 207 { return }     // WebDAV multistatus
+            else if errorCode == 423 { return }     // WebDAV locked
+            else if errorCode == -1001 { return }   // Time out
+            else if errorCode == -1005 { return }   // Connection lost
+            else if errorCode == 0 && type == messageType.error { return }
+        }
         
         // No repeat message for:
         if errorCode == lastErrorCode {