瀏覽代碼

Merge branch 'develop'

marinofaggiana 4 年之前
父節點
當前提交
da3dec59f3
共有 100 個文件被更改,包括 1226 次插入694 次删除
  1. 5 5
      Cartfile
  2. 8 8
      Cartfile.resolved
  3. 1 4
      Carthage/Checkouts/SVGKit/SVGKit.podspec
  4. 0 31
      Carthage/Checkouts/SVGKit/SVGKitLibrary/SVGKit-iOS/SVGKit-Prefix.pch
  5. 5 0
      Carthage/Checkouts/SVGKit/Source/AppKit additions/SVGKImageRep.h
  6. 4 1
      Carthage/Checkouts/SVGKit/Source/AppKit additions/SVGKImageRep.m
  7. 2 0
      Carthage/Checkouts/SVGKit/Source/DOM classes/Core DOM/CSSStyleDeclaration.m
  8. 1 0
      Carthage/Checkouts/SVGKit/Source/DOM classes/Core DOM/CSSValueList.m
  9. 2 0
      Carthage/Checkouts/SVGKit/Source/DOM classes/Core DOM/Document.m
  10. 2 0
      Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGClipPathElement.m
  11. 2 0
      Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGDocument.m
  12. 2 0
      Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGHelperUtilities.m
  13. 1 0
      Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGLength.m
  14. 1 0
      Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGRect.m
  15. 1 0
      Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGCircleElement.m
  16. 2 0
      Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGElement.m
  17. 1 0
      Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGGradientElement.m
  18. 2 0
      Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGImageElement.m
  19. 1 0
      Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGLinearGradientElement.m
  20. 2 0
      Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGPathElement.m
  21. 1 0
      Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGRadialGradientElement.m
  22. 2 0
      Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGSVGElement.m
  23. 1 0
      Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGTextElement.m
  24. 6 0
      Carthage/Checkouts/SVGKit/Source/Exporters/SVGKExporterNSImage.h
  25. 5 0
      Carthage/Checkouts/SVGKit/Source/Exporters/SVGKExporterNSImage.m
  26. 4 0
      Carthage/Checkouts/SVGKit/Source/Exporters/SVGKExporterUIImage.m
  27. 2 0
      Carthage/Checkouts/SVGKit/Source/Exporters/SVGKImage+CGContext.m
  28. 1 0
      Carthage/Checkouts/SVGKit/Source/Foundation additions/NSCharacterSet+SVGKExtensions.m
  29. 1 1
      Carthage/Checkouts/SVGKit/Source/Foundation additions/NSData+NSInputStream.m
  30. 2 0
      Carthage/Checkouts/SVGKit/Source/Parsers/Parser Extensions/SVGKParserSVG.m
  31. 1 0
      Carthage/Checkouts/SVGKit/Source/Parsers/SVGKParseResult.m
  32. 2 0
      Carthage/Checkouts/SVGKit/Source/Parsers/SVGKParser.m
  33. 5 0
      Carthage/Checkouts/SVGKit/Source/QuartzCore additions/CALayerWithClipRender.m
  34. 1 0
      Carthage/Checkouts/SVGKit/Source/QuartzCore additions/CAShapeLayerWithHitTest.m
  35. 1 0
      Carthage/Checkouts/SVGKit/Source/QuartzCore additions/CGPathAdditions.m
  36. 1 0
      Carthage/Checkouts/SVGKit/Source/QuartzCore additions/SVGGradientLayer.m
  37. 2 0
      Carthage/Checkouts/SVGKit/Source/SVGKImage.m
  38. 2 0
      Carthage/Checkouts/SVGKit/Source/SVGKit.h
  39. 1 0
      Carthage/Checkouts/SVGKit/Source/Sources/SVGKSourceLocalFile.m
  40. 1 0
      Carthage/Checkouts/SVGKit/Source/Sources/SVGKSourceNSData.m
  41. 1 0
      Carthage/Checkouts/SVGKit/Source/Sources/SVGKSourceURL.m
  42. 1 0
      Carthage/Checkouts/SVGKit/Source/UIKit additions/SVGKFastImageView.m
  43. 2 0
      Carthage/Checkouts/SVGKit/Source/UIKit additions/SVGKLayeredImageView.m
  44. 1 0
      Carthage/Checkouts/SVGKit/Source/Utils/SVGUtils.h
  45. 1 0
      Carthage/Checkouts/SVGKit/Source/Utils/SVGUtils.m
  46. 19 12
      Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/Base.lproj/Main.storyboard
  47. 18 0
      Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/ViewController.swift
  48. 12 2
      Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLPhotosPickerViewController.swift
  49. 2 0
      Carthage/Checkouts/realm-cocoa/.gitignore
  50. 165 0
      Carthage/Checkouts/realm-cocoa/.jenkins.yml
  51. 1 1
      Carthage/Checkouts/realm-cocoa/.travis.yml
  52. 98 0
      Carthage/Checkouts/realm-cocoa/CHANGELOG.md
  53. 1 1
      Carthage/Checkouts/realm-cocoa/Jenkinsfile.releasability
  54. 2 2
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/dependencies.list
  55. 17 0
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object.cpp
  56. 1 0
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object.hpp
  57. 58 47
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object_accessor.hpp
  58. 13 0
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/property.hpp
  59. 1 14
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/thread_safe_reference.cpp
  60. 206 2
      Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/migrations.cpp
  61. 2 2
      Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist
  62. 1 1
      Carthage/Checkouts/realm-cocoa/build.sh
  63. 3 3
      Carthage/Checkouts/realm-cocoa/dependencies.list
  64. 10 8
      Carthage/Checkouts/realm-cocoa/examples/installation/build.sh
  65. 1 1
      Carthage/Checkouts/realm-cocoa/scripts/package_examples.rb
  66. 37 37
      File Provider Extension/FileProviderData.swift
  67. 68 73
      File Provider Extension/FileProviderEnumerator.swift
  68. 68 41
      File Provider Extension/FileProviderExtension+Actions.swift
  69. 7 8
      File Provider Extension/FileProviderExtension+NetworkingDelegate.swift
  70. 17 10
      File Provider Extension/FileProviderExtension.swift
  71. 0 4
      File Provider Extension/FileProviderItem.swift
  72. 24 30
      Nextcloud.xcodeproj/project.pbxproj
  73. 3 3
      Share/NCSelectDestination.m
  74. 1 0
      Share/ShareViewController.h
  75. 4 3
      Share/ShareViewController.m
  76. 3 4
      iOSClient/Activity/NCActivity.swift
  77. 8 10
      iOSClient/AppDelegate.m
  78. 9 4
      iOSClient/AutoUpload/NCAutoUpload.m
  79. 11 5
      iOSClient/CCGlobal.h
  80. 99 127
      iOSClient/Database/NCManageDatabase.swift
  81. 0 1
      iOSClient/Favorites/CCFavorites.h
  82. 16 69
      iOSClient/Favorites/CCFavorites.m
  83. 8 16
      iOSClient/Images.xcassets/avatarBN.imageset/Contents.json
  84. 二進制
      iOSClient/Images.xcassets/avatarBN.imageset/avatarBN.pdf
  85. 二進制
      iOSClient/Images.xcassets/avatarBN.imageset/avatarBN.png
  86. 二進制
      iOSClient/Images.xcassets/avatarBN.imageset/avatarBN@2x.png
  87. 二進制
      iOSClient/Images.xcassets/avatarBN.imageset/avatarBN@3x.png
  88. 15 0
      iOSClient/Images.xcassets/capabilities.imageset/Contents.json
  89. 二進制
      iOSClient/Images.xcassets/capabilities.imageset/capabilities.pdf
  90. 15 0
      iOSClient/Images.xcassets/cloudDownload.imageset/Contents.json
  91. 二進制
      iOSClient/Images.xcassets/cloudDownload.imageset/cloudDownload.pdf
  92. 15 0
      iOSClient/Images.xcassets/cloudUpload.imageset/Contents.json
  93. 二進制
      iOSClient/Images.xcassets/cloudUpload.imageset/cloudUpload.pdf
  94. 0 26
      iOSClient/Images.xcassets/uploadCloud.imageset/Contents.json
  95. 二進制
      iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud.png
  96. 二進制
      iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud@2x.png
  97. 二進制
      iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud@3x.png
  98. 4 4
      iOSClient/Login/NCAppConfigView.swift
  99. 2 2
      iOSClient/Login/NCLoginWeb.swift
  100. 68 71
      iOSClient/Main/CCMain.m

+ 5 - 5
Cartfile

@@ -1,16 +1,16 @@
-github "nextcloud/ios-communication-library" "v0.74"
-github "tilltue/TLPhotoPicker" "2.0.11"
+github "nextcloud/ios-communication-library" "v0.75"
+github "tilltue/TLPhotoPicker" "2.0.12"
 github "kishikawakatsumi/UICKeyChainStore" "v2.1.2"
 github "MortimerGoro/MGSwipeTableCell" "1.6.8"
 github "dzenbot/DZNEmptyDataSet" "v1.8.1"
 github "jdg/MBProgressHUD" "1.1.0"
-github "realm/realm-cocoa" 
+github "realm/realm-cocoa" "v5.3.2"
 github "SVGKit/SVGKit" "3.x"
 github "WeTransfer/WeScan" "1.2.0"
 github "malcommac/SwiftRichString"
 github "yannickl/QRCodeReader.swift" "10.1.1"
 github "weichsel/ZIPFoundation" "0.9.10"
-github "rechsteiner/Parchment" "v1.7.0"
+github "rechsteiner/Parchment" "v2.4.0"
 github "WenchaoD/FSCalendar" "2.8.0"
 github "AssistoLab/DropDown" "v2.3.13"
 github "krzyzanowskim/OpenSSL" "1.0.218"
@@ -19,7 +19,7 @@ github "scenee/FloatingPanel"
 github "ivanbruel/MarkdownKit"
 github "getsentry/sentry-cocoa"
 github "FabrizioBrancati/Queuer"
+github "xmartlabs/XLForm" ~> 4.1
 
 github "https://github.com/marinofaggiana/KTVHTTPCache" "2.0.2"
-github "https://github.com/marinofaggiana/XLForm" "master"
 github "https://github.com/marinofaggiana/TOPasscodeViewController" "0.0.7"

+ 8 - 8
Cartfile.resolved

@@ -1,14 +1,14 @@
-github "Alamofire/Alamofire" "5.2.1"
+github "Alamofire/Alamofire" "5.2.2"
 github "AssistoLab/DropDown" "v2.3.13"
 github "CocoaLumberjack/CocoaLumberjack" "3.6.1"
 github "FabrizioBrancati/Queuer" "2.1.1"
 github "MortimerGoro/MGSwipeTableCell" "1.6.8"
-github "SVGKit/SVGKit" "2a4068f0ea546dcd82f7e4dd9aa9026c0a0a2235"
+github "SVGKit/SVGKit" "9240977515c04053f8c96c9dfdb764dc7b98b9ba"
 github "SwiftyJSON/SwiftyJSON" "5.0.0"
 github "WeTransfer/WeScan" "1.2.0"
 github "WenchaoD/FSCalendar" "2.8.0"
 github "dzenbot/DZNEmptyDataSet" "v1.8.1"
-github "getsentry/sentry-cocoa" "5.1.8"
+github "getsentry/sentry-cocoa" "5.1.10"
 github "huri000/QuickLayout" "3.0.0"
 github "huri000/SwiftEntryKit" "1.2.3"
 github "ivanbruel/MarkdownKit" "1.6"
@@ -18,12 +18,12 @@ github "krzyzanowskim/OpenSSL" "1.0.218"
 github "malcommac/SwiftRichString" "3.7.2"
 github "marinofaggiana/KTVHTTPCache" "2.0.2"
 github "marinofaggiana/TOPasscodeViewController" "0.0.7"
-github "marinofaggiana/XLForm" "eb9381ad8129f60402bf412250fb31b95a628a08"
-github "nextcloud/ios-communication-library" "v0.74"
-github "realm/realm-cocoa" "v5.2.0"
-github "rechsteiner/Parchment" "v1.7.0"
+github "nextcloud/ios-communication-library" "v0.75"
+github "realm/realm-cocoa" "v5.3.2"
+github "rechsteiner/Parchment" "v2.4.0"
 github "scenee/FloatingPanel" "v1.7.5"
-github "tilltue/TLPhotoPicker" "2.0.11"
+github "tilltue/TLPhotoPicker" "2.0.12"
 github "weichsel/ZIPFoundation" "0.9.10"
+github "xmartlabs/XLForm" "4.1.0"
 github "yahoojapan/SwiftyXMLParser" "5.2.0"
 github "yannickl/QRCodeReader.swift" "10.1.1"

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

@@ -17,13 +17,10 @@ Pod::Spec.new do |s|
   s.source   = { :git => 'https://github.com/SVGKit/SVGKit.git', :tag => s.version.to_s }
 
   s.source_files = 'Source/*.{h,m}', 'Source/**/*.{h,m}'
-  s.ios.exclude_files = 'Source/AppKit additions/*.{h,m}', 'Source/Exporters/SVGKExporterNSImage.{h,m}'
-  s.tvos.exclude_files = 'Source/AppKit additions/*.{h,m}', 'Source/Exporters/SVGKExporterNSImage.{h,m}'
-  s.osx.exclude_files = 'Source/Exporters/SVGKExporterUIImage.{h,m}'
+  s.exclude_files = 'Source/include/*.h'
   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 = {

+ 0 - 31
Carthage/Checkouts/SVGKit/SVGKitLibrary/SVGKit-iOS/SVGKit-Prefix.pch

@@ -1,31 +0,0 @@
-//
-// Prefix header for all source files of the 'SVGKit-iOS' target in the 'SVGKit-iOS' project
-//
-
-#ifdef __OBJC__
-#import <Foundation/Foundation.h>
-#import <CocoaLumberjack/CocoaLumberjack.h>
-#import "SVGKDefine.h"
-
-// These macro is only used inside framework project, does not expose to public header and effect user's define
-
-#define SVGKIT_LOG_CONTEXT 556
-
-#define SVGKitLogError(frmt, ...)   LOG_MAYBE(NO,                LOG_LEVEL_DEF, DDLogFlagError,   SVGKIT_LOG_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
-#define SVGKitLogWarn(frmt, ...)    LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagWarning, SVGKIT_LOG_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
-#define SVGKitLogInfo(frmt, ...)    LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagInfo,    SVGKIT_LOG_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
-#define SVGKitLogDebug(frmt, ...)   LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagDebug,   SVGKIT_LOG_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
-#define SVGKitLogVerbose(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagVerbose, SVGKIT_LOG_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
-
-#if DEBUG
-static const int ddLogLevel = DDLogLevelVerbose;
-#else
-static const int ddLogLevel = DDLogLevelWarning;
-#endif
-
-#if SVGKIT_MAC
-#define NSStringFromCGRect(rect) NSStringFromRect(rect)
-#define NSStringFromCGSize(size) NSStringFromSize(size)
-#define NSStringFromCGPoint(point) NSStringFromPoint(point)
-#endif
-#endif

+ 5 - 0
Carthage/Checkouts/SVGKit/Source/AppKit additions/SVGKImageRep.h

@@ -6,6 +6,9 @@
 //
 //
 
+#import "SVGKDefine.h"
+
+#if SVGKIT_MAC
 #import <Cocoa/Cocoa.h>
 @class SVGKImage;
 @class SVGKSource;
@@ -36,3 +39,5 @@
 + (void)unloadSVGKImageRep;
 
 @end
+
+#endif /* SVGKIT_MAC */

+ 4 - 1
Carthage/Checkouts/SVGKit/Source/AppKit additions/SVGKImageRep.m

@@ -7,11 +7,12 @@
 //
 
 #import "SVGKit.h"
+
+#if SVGKIT_MAC
 #import "SVGKSourceNSData.h"
 #import "SVGKSourceLocalFile.h"
 #import "SVGKSourceURL.h"
 #import "SVGKSourceString.h"
-#import "SVGKFastImageView.h"
 #import "SVGKImageRep.h"
 #import "SVGKImage+CGContext.h"
 #include <tgmath.h>
@@ -288,3 +289,5 @@
 }
 
 @end
+
+#endif /* SVGKIT_MAC */

+ 2 - 0
Carthage/Checkouts/SVGKit/Source/DOM classes/Core DOM/CSSStyleDeclaration.m

@@ -5,6 +5,8 @@
 #import "CSSPrimitiveValue.h"
 #import "CocoaLumberjack/DDFileLogger.h"
 
+#import "SVGKDefine_Private.h"
+
 @interface CSSStyleDeclaration()
 
 @property(nonatomic,strong) NSMutableDictionary* internalDictionaryOfStylesByCSSClass;

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/DOM classes/Core DOM/CSSValueList.m

@@ -1,5 +1,6 @@
 #import "CSSValueList.h"
 #import "CSSValue_ForSubclasses.h"
+#import "SVGKDefine_Private.h"
 
 @interface CSSValueList()
 

+ 2 - 0
Carthage/Checkouts/SVGKit/Source/DOM classes/Core DOM/Document.m

@@ -5,6 +5,8 @@
 
 #import "NodeList+Mutable.h" // needed for access to underlying array, because SVG doesnt specify how lists are made mutable
 
+#import "SVGKDefine_Private.h"
+
 @implementation Document
 
 @synthesize doctype;

+ 2 - 0
Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGClipPathElement.m

@@ -4,6 +4,8 @@
 
 #import "SVGHelperUtilities.h"
 
+#import "SVGKDefine_Private.h"
+
 @implementation SVGClipPathElement
 
 @synthesize clipPathUnits;

+ 2 - 0
Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGDocument.m

@@ -13,6 +13,8 @@
 
 #import "NamedNodeMap_Iterable.h" // needed for the allPrefixesByNamespace implementation
 
+#import "SVGKDefine_Private.h"
+
 @implementation SVGDocument
 
 

+ 2 - 0
Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGHelperUtilities.m

@@ -9,6 +9,8 @@
 #import "SVGSVGElement.h"
 #import "SVGGradientLayer.h"
 
+#import "SVGKDefine_Private.h"
+
 @implementation SVGHelperUtilities
 
 

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGLength.m

@@ -4,6 +4,7 @@
 #import "CSSPrimitiveValue_ConfigurablePixelsPerInch.h"
 
 #import "SVGUtils.h"
+#import "SVGKDefine_Private.h"
 
 #include <sys/types.h>
 #include <sys/sysctl.h>

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGRect.m

@@ -1,4 +1,5 @@
 #import "SVGRect.h"
+#import "SVGKDefine_Private.h"
 
 BOOL SVGRectIsInitialized( SVGRect rect )
 {

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGCircleElement.m

@@ -6,6 +6,7 @@
 //
 
 #import "SVGCircleElement.h"
+#import "SVGKDefine_Private.h"
 
 @implementation SVGCircleElement
 

+ 2 - 0
Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGElement.m

@@ -20,6 +20,8 @@
 
 #import "SVGTransformable.h"
 
+#import "SVGKDefine_Private.h"
+
 @interface SVGElement ()
 
 @property (nonatomic, copy) NSString *stringValue;

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGGradientElement.m

@@ -5,6 +5,7 @@
 #import "SVGGElement.h"
 #import "SVGLinearGradientElement.h"
 #import "SVGRadialGradientElement.h"
+#import "SVGKDefine_Private.h"
 
 @implementation SVGGradientElement
 

+ 2 - 0
Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGImageElement.m

@@ -9,6 +9,8 @@
 #import "SVGKSourceNSData.h"
 #import "SVGKInlineResource.h"
 
+#import "SVGKDefine_Private.h"
+
 CGImageRef SVGImageCGImage(UIImage *img)
 {
 #if SVGKIT_UIKIT

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGLinearGradientElement.m

@@ -9,6 +9,7 @@
 #import "SVGLinearGradientElement.h"
 #import "SVGElement_ForParser.h"
 #import "SVGGradientLayer.h"
+#import "SVGKDefine_Private.h"
 
 @interface SVGLinearGradientElement ()
 

+ 2 - 0
Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGPathElement.m

@@ -12,6 +12,8 @@
 
 #import "SVGElement_ForParser.h" // to resolve Xcode circular dependencies; in long term, parsing SHOULD NOT HAPPEN inside any class whose name starts "SVG" (because those are reserved classes for the SVG Spec)
 
+#import "SVGKDefine_Private.h"
+
 @interface SVGPathElement ()
 
 - (void) parseData:(NSString *)data;

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGRadialGradientElement.m

@@ -10,6 +10,7 @@
 #import "SVGElement_ForParser.h"
 #import "SVGUtils.h"
 #import "SVGGradientLayer.h"
+#import "SVGKDefine_Private.h"
 
 // `kCAGradientLayerRadial` this symbol is available since iOS 3.2/tvOS 9.0/macOS 10.6, but it's not externed to public header until Xcode 10 with iOS 12 SDK, so we define it for user who still use old SDK version.
 #define kCAGradientLayerRadial @"radial"

+ 2 - 0
Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGSVGElement.m

@@ -7,6 +7,8 @@
 
 #import "SVGElement_ForParser.h" // to resolve Xcode circular dependencies; in long term, parsing SHOULD NOT HAPPEN inside any class whose name starts "SVG" (because those are reserved classes for the SVG Spec)
 
+#import "SVGKDefine_Private.h"
+
 @interface SVGSVGElement()
 #pragma mark - elements REQUIRED to implement the spec but not included in SVG Spec due to bugs in the spec writing!
 @property(nonatomic,readwrite) SVGRect requestedViewport;

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGTextElement.m

@@ -6,6 +6,7 @@
 #import "SVGHelperUtilities.h"
 #import "SVGUtils.h"
 #import "SVGTextLayer.h"
+#import "SVGKDefine_Private.h"
 
 @implementation SVGTextElement
 

+ 6 - 0
Carthage/Checkouts/SVGKit/Source/Exporters/SVGKExporterNSImage.h

@@ -3,6 +3,10 @@
  
  Uses the default color format from UIGraphicsBeginImageContextWithOptions(...)
  */
+
+#import "SVGKDefine.h"
+
+#if SVGKIT_MAC
 #import <Foundation/Foundation.h>
 #import "SVGKImage.h"
 
@@ -29,3 +33,5 @@
 +(NSImage*) exportAsNSImage:(SVGKImage*) image antiAliased:(BOOL) shouldAntialias curveFlatnessFactor:(CGFloat) multiplyFlatness interpolationQuality:(CGInterpolationQuality) interpolationQuality;
 
 @end
+
+#endif /* SVGKIT_MAC */

+ 5 - 0
Carthage/Checkouts/SVGKit/Source/Exporters/SVGKExporterNSImage.m

@@ -1,7 +1,10 @@
 #import "SVGKExporterNSImage.h"
+
+#if SVGKIT_MAC
 #import "SVGUtils.h"
 #import "SVGKImage+CGContext.h" // needed for Context calls
 #import <objc/runtime.h>
+#import "SVGKDefine_Private.h"
 
 @implementation SVGKExporterNSImage
 
@@ -133,3 +136,5 @@ static NSImage * SVGKGraphicsGetImageFromCurrentImageContext(void) {
 }
 
 @end
+
+#endif /* SVGKIT_MAC */

+ 4 - 0
Carthage/Checkouts/SVGKit/Source/Exporters/SVGKExporterUIImage.m

@@ -1,5 +1,7 @@
 #import "SVGKExporterUIImage.h"
+#import "SVGKDefine_Private.h"
 
+#if SVGKIT_UIKIT
 #import "SVGKImage+CGContext.h" // needed for Context calls
 
 @implementation SVGKExporterUIImage
@@ -35,3 +37,5 @@
 }
 
 @end
+
+#endif /* SVGKIT_UIKIT */

+ 2 - 0
Carthage/Checkouts/SVGKit/Source/Exporters/SVGKImage+CGContext.m

@@ -11,6 +11,8 @@
 #import "SVGRect.h"
 #import "SVGSVGElement.h"
 
+#import "SVGKDefine_Private.h"
+
 @implementation SVGKImage (CGContext)
 
 -(CGContextRef) newCGContextAutosizedToFit

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/Foundation additions/NSCharacterSet+SVGKExtensions.m

@@ -7,6 +7,7 @@
 //
 
 #import "NSCharacterSet+SVGKExtensions.h"
+#import "SVGKDefine_Private.h"
 
 @implementation NSCharacterSet (SVGKExtensions)
 

+ 1 - 1
Carthage/Checkouts/SVGKit/Source/Foundation additions/NSData+NSInputStream.m

@@ -7,7 +7,7 @@
 //
 
 #import "NSData+NSInputStream.h"
-
+#import "SVGKDefine_Private.h"
 
 #define BUFSIZE 65536U
 

+ 2 - 0
Carthage/Checkouts/SVGKit/Source/Parsers/Parser Extensions/SVGKParserSVG.m

@@ -21,6 +21,8 @@
 
 #import "SVGDocument_Mutable.h"
 
+#import "SVGKDefine_Private.h"
+
 @interface SVGKParserSVG ()
 @property (nonatomic) NSArray *supportedNamespaces;
 @property (nonatomic) NSDictionary *elementMap;

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/Parsers/SVGKParseResult.m

@@ -1,4 +1,5 @@
 #import "SVGKParseResult.h"
+#import "SVGKDefine_Private.h"
 
 @implementation SVGKParseResult
 

+ 2 - 0
Carthage/Checkouts/SVGKit/Source/Parsers/SVGKParser.m

@@ -31,6 +31,8 @@
 #import "StyleSheetList+Mutable.h"
 #import "NSData+NSInputStream.h"
 
+#import "SVGKDefine_Private.h"
+
 @interface SVGKParser()
 @property(nonatomic,strong, readwrite) SVGKSource* source;
 @property(nonatomic,strong, readwrite) NSMutableArray* externalStylesheets;

+ 5 - 0
Carthage/Checkouts/SVGKit/Source/QuartzCore additions/CALayerWithClipRender.m

@@ -7,6 +7,11 @@
 //
 
 #import "CALayerWithClipRender.h"
+#import "SVGKDefine.h"
+
+#if SVGKIT_UIKIT
+#import <UIKit/UIKit.h>
+#endif
 
 @interface CALayer (ContentsTransform)
 

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/QuartzCore additions/CAShapeLayerWithHitTest.m

@@ -1,4 +1,5 @@
 #import "CAShapeLayerWithHitTest.h"
+#import "SVGKDefine_Private.h"
 
 /*! Used by the main ShapeElement (and all subclasses) to do perfect "containsPoint" calculations via Apple's API calls
  

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/QuartzCore additions/CGPathAdditions.m

@@ -6,6 +6,7 @@
 //
 
 #import "CGPathAdditions.h"
+#import <stdlib.h>
 
 void applier (void *info, const CGPathElement *element);
 

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/QuartzCore additions/SVGGradientLayer.m

@@ -10,6 +10,7 @@
 #import "SVGRadialGradientElement.h"
 #import "SVGLinearGradientElement.h"
 #import "CALayerWithClipRender.h"
+#import "SVGKDefine_Private.h"
 
 @implementation SVGGradientLayer
 

+ 2 - 0
Carthage/Checkouts/SVGKit/Source/SVGKImage.m

@@ -25,6 +25,8 @@
 #import "SVGKExporterUIImage.h" // needed for .UIImage property
 #endif
 
+#import "SVGKDefine_Private.h"
+
 #if ENABLE_GLOBAL_IMAGE_CACHE_FOR_SVGKIMAGE_IMAGE_NAMED
 @interface SVGKImageCacheLine : NSObject
 @property(nonatomic) int numberOfInstances;

+ 2 - 0
Carthage/Checkouts/SVGKit/Source/SVGKit.h

@@ -163,9 +163,11 @@ FOUNDATION_EXPORT const unsigned char SVGKitFramework_VersionString[];
 #import "SVGKImage.h"
 #import "SVGKSource.h"
 #import "NSCharacterSet+SVGKExtensions.h"
+#if SVGKIT_UIKIT
 #import "SVGKFastImageView.h"
 #import "SVGKImageView.h"
 #import "SVGKLayeredImageView.h"
+#endif
 #import "SVGKPattern.h"
 #import "SVGUtils.h"
 #if SVGKIT_MAC

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/Sources/SVGKSourceLocalFile.m

@@ -1,4 +1,5 @@
 #import "SVGKSourceLocalFile.h"
+#import "SVGKDefine_Private.h"
 
 @interface SVGKSourceLocalFile()
 @property (nonatomic, readwrite) BOOL wasRelative;

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/Sources/SVGKSourceNSData.m

@@ -1,6 +1,7 @@
 #import "SVGKSourceNSData.h"
 
 #import "SVGKSourceURL.h" // used for delegating when asked to construct relative links
+#import "SVGKDefine_Private.h"
 
 @implementation SVGKSourceNSData
 

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/Sources/SVGKSourceURL.m

@@ -1,4 +1,5 @@
 #import "SVGKSourceURL.h"
+#import "SVGKDefine_Private.h"
 
 @implementation SVGKSourceURL
 

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/UIKit additions/SVGKFastImageView.m

@@ -1,4 +1,5 @@
 #import "SVGKFastImageView.h"
+#import "SVGKDefine_Private.h"
 
 @interface SVGKFastImageView ()
 @property(nonatomic,readwrite) NSTimeInterval timeIntervalForLastReRenderOfSVGFromMemory;

+ 2 - 0
Carthage/Checkouts/SVGKit/Source/UIKit additions/SVGKLayeredImageView.m

@@ -5,6 +5,8 @@
 #import "SVGKSourceString.h"
 #import "SVGKInlineResource.h"
 
+#import "SVGKDefine_Private.h"
+
 @interface SVGKLayeredImageView()
 @property(nonatomic,strong) CAShapeLayer* internalBorderLayer;
 @end

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/Utils/SVGUtils.h

@@ -5,6 +5,7 @@
 //  Copyright Matt Rajca 2010-2011. All rights reserved.
 //
 
+#import <Foundation/Foundation.h>
 #import <CoreFoundation/CoreFoundation.h>
 #import <CoreGraphics/CoreGraphics.h>
 

+ 1 - 0
Carthage/Checkouts/SVGKit/Source/Utils/SVGUtils.m

@@ -6,6 +6,7 @@
 //
 
 #import "SVGUtils.h"
+#import "SVGKDefine_Private.h"
 
 #define MAX_ACCUM 64
 #define NUM_COLORS 148

+ 19 - 12
Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/Base.lproj/Main.storyboard

@@ -1,11 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="vXZ-lx-hvc">
-    <device id="retina4_7" orientation="portrait">
-        <adaptation id="fullscreen"/>
-    </device>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="vXZ-lx-hvc">
+    <device id="retina4_7" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -19,7 +17,7 @@
                         <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                         <subviews>
                             <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="50" translatesAutoresizingMaskIntoConstraints="NO" id="3bJ-bG-tue">
-                                <rect key="frame" x="73" y="144" width="229" height="380"/>
+                                <rect key="frame" x="73" y="57.5" width="229" height="552"/>
                                 <subviews>
                                     <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="zpy-9h-CPz">
                                         <rect key="frame" x="0.0" y="0.0" width="229" height="36"/>
@@ -29,16 +27,25 @@
                                             <action selector="pickerButtonTap" destination="vXZ-lx-hvc" eventType="touchUpInside" id="0Q7-5M-ogn"/>
                                         </connections>
                                     </button>
-                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="d6U-qB-bWX">
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WKj-AD-9tA">
                                         <rect key="frame" x="0.0" y="86" width="229" height="36"/>
                                         <fontDescription key="fontDescription" type="system" pointSize="20"/>
+                                        <state key="normal" title="Only Video Recording"/>
+                                        <connections>
+                                            <action selector="onlyVideoRecording:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="GbK-VR-G0G"/>
+                                            <action selector="pickerButtonTap" destination="vXZ-lx-hvc" eventType="touchUpInside" id="zYL-bG-qij"/>
+                                        </connections>
+                                    </button>
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="d6U-qB-bWX">
+                                        <rect key="frame" x="0.0" y="172" width="229" height="36"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="20"/>
                                         <state key="normal" title="Custom CameraCell (Live)"/>
                                         <connections>
                                             <action selector="pickerWithCustomCameraCell" destination="vXZ-lx-hvc" eventType="touchUpInside" id="fXi-av-gMq"/>
                                         </connections>
                                     </button>
                                     <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9kt-E5-QsD">
-                                        <rect key="frame" x="0.0" y="172" width="229" height="36"/>
+                                        <rect key="frame" x="0.0" y="258" width="229" height="36"/>
                                         <fontDescription key="fontDescription" type="system" pointSize="20"/>
                                         <state key="normal" title="Custom BlackStyle"/>
                                         <connections>
@@ -46,7 +53,7 @@
                                         </connections>
                                     </button>
                                     <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="icR-mj-SY4">
-                                        <rect key="frame" x="0.0" y="258" width="229" height="36"/>
+                                        <rect key="frame" x="0.0" y="344" width="229" height="36"/>
                                         <fontDescription key="fontDescription" type="system" pointSize="20"/>
                                         <state key="normal" title="with NavigationController">
                                             <color key="titleColor" red="0.1019607843" green="0.73725490199999999" blue="0.61176470589999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -56,7 +63,7 @@
                                         </connections>
                                     </button>
                                     <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="VP9-SK-f4B">
-                                        <rect key="frame" x="0.0" y="344" width="229" height="36"/>
+                                        <rect key="frame" x="0.0" y="430" width="229" height="36"/>
                                         <fontDescription key="fontDescription" type="system" pointSize="20"/>
                                         <state key="normal" title="with custom rules">
                                             <color key="titleColor" red="0.27450980390000002" green="0.31372549020000001" blue="0.37647058820000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -66,7 +73,7 @@
                                         </connections>
                                     </button>
                                     <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="W1Y-V8-qUq">
-                                        <rect key="frame" x="0.0" y="344" width="229" height="36"/>
+                                        <rect key="frame" x="0.0" y="516" width="229" height="36"/>
                                         <fontDescription key="fontDescription" type="system" pointSize="20"/>
                                         <state key="normal" title="with Custom Layout"/>
                                         <connections>
@@ -76,7 +83,7 @@
                                 </subviews>
                             </stackView>
                             <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="u8O-io-kHd">
-                                <rect key="frame" x="137.5" y="534" width="100" height="112"/>
+                                <rect key="frame" x="137.5" y="619.5" width="100" height="112"/>
                                 <subviews>
                                     <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="get image message" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9CM-MS-96X">
                                         <rect key="frame" x="3" y="0.0" width="94" height="12"/>

+ 18 - 0
Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/ViewController.swift

@@ -31,6 +31,24 @@ class ViewController: UIViewController,TLPhotosPickerViewControllerDelegate {
         self.present(viewController, animated: true, completion: nil)
     }
     
+    @IBAction func onlyVideoRecording(_ sender: Any) {
+        let viewController = CustomPhotoPickerViewController()
+        viewController.delegate = self
+        viewController.didExceedMaximumNumberOfSelection = { [weak self] (picker) in
+            self?.showExceededMaximumAlert(vc: picker)
+        }
+        var configure = TLPhotosPickerConfigure()
+        configure.numberOfColumn = 3
+        configure.allowedPhotograph = false
+        configure.allowedVideoRecording = true
+        configure.mediaType = .video
+        viewController.configure = configure
+        viewController.selectedAssets = self.selectedAssets
+        viewController.logDelegate = self
+
+        self.present(viewController, animated: true, completion: nil)
+    }
+    
     @IBAction func pickerWithCustomCameraCell() {
         let viewController = CustomPhotoPickerViewController()
         viewController.delegate = self

+ 12 - 2
Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLPhotosPickerViewController.swift

@@ -67,6 +67,7 @@ public struct TLPhotosPickerConfigure {
     public var allowedLivePhotos = true
     public var allowedVideo = true
     public var allowedAlbumCloudShared = false
+    public var allowedPhotograph = true
     public var allowedVideoRecording = true
     public var recordingVideoQuality: UIImagePickerController.QualityType = .typeMedium
     public var maxVideoDuration:TimeInterval? = nil
@@ -598,14 +599,21 @@ extension TLPhotosPickerViewController: UIImagePickerControllerDelegate, UINavig
         guard !maxCheck() else { return }
         let picker = UIImagePickerController()
         picker.sourceType = .camera
-        picker.mediaTypes = [kUTTypeImage as String]
+        var mediaTypes: [String] = []
+        if self.configure.allowedPhotograph {
+            mediaTypes.append(kUTTypeImage as String)
+        }
         if self.configure.allowedVideoRecording {
-            picker.mediaTypes.append(kUTTypeMovie as String)
+            mediaTypes.append(kUTTypeMovie as String)
             picker.videoQuality = self.configure.recordingVideoQuality
             if let duration = self.configure.maxVideoDuration {
                 picker.videoMaximumDuration = duration
             }
         }
+        guard mediaTypes.count > 0 else {
+            return
+        }
+        picker.mediaTypes = mediaTypes
         picker.allowsEditing = false
         picker.delegate = self
         self.present(picker, animated: true, completion: nil)
@@ -632,6 +640,7 @@ extension TLPhotosPickerViewController: UIImagePickerControllerDelegate, UINavig
                 let newAssetRequest = PHAssetChangeRequest.creationRequestForAsset(from: image)
                 placeholderAsset = newAssetRequest.placeholderForCreatedAsset
             }, completionHandler: { [weak self] (success, error) in
+                guard self?.maxCheck() == false else { return }
                 if success, let `self` = self, let identifier = placeholderAsset?.localIdentifier {
                     guard let asset = PHAsset.fetchAssets(withLocalIdentifiers: [identifier], options: nil).firstObject else { return }
                     var result = TLPHAsset(asset: asset)
@@ -648,6 +657,7 @@ extension TLPhotosPickerViewController: UIImagePickerControllerDelegate, UINavig
                 let newAssetRequest = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: info[.mediaURL] as! URL)
                 placeholderAsset = newAssetRequest?.placeholderForCreatedAsset
             }) { [weak self] (sucess, error) in
+                guard self?.maxCheck() == false else { return }
                 if sucess, let `self` = self, let identifier = placeholderAsset?.localIdentifier {
                     guard let asset = PHAsset.fetchAssets(withLocalIdentifiers: [identifier], options: nil).firstObject else { return }
                     var result = TLPHAsset(asset: asset)

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

+ 37 - 37
File Provider Extension/FileProviderData.swift

@@ -152,43 +152,6 @@ class fileProviderData: NSObject {
         return foundAccount
     }
     
-    // MARK: -
-    
-    func updateFavoriteForWorkingSet() {
-        
-        var updateWorkingSet = false
-        let oldListFavoriteIdentifierRank = listFavoriteIdentifierRank
-        listFavoriteIdentifierRank = NCManageDatabase.sharedInstance.getTableMetadatasDirectoryFavoriteIdentifierRank(account: account)
-        
-        // (ADD)
-        for (identifier, _) in listFavoriteIdentifierRank {
-            
-            guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", identifier)) else { continue }
-            guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadata, homeServerUrl: homeServerUrl) else { continue }
-            let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier)
-                
-            fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
-            updateWorkingSet = true
-        }
-        
-        // (REMOVE)
-        for (identifier, _) in oldListFavoriteIdentifierRank {
-            
-            if !listFavoriteIdentifierRank.keys.contains(identifier) {
-                
-                guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", identifier)) else { continue }
-                let itemIdentifier = fileProviderUtility.sharedInstance.getItemIdentifier(metadata: metadata)
-                
-                fileProviderSignalDeleteWorkingSetItemIdentifier[itemIdentifier] = itemIdentifier
-                updateWorkingSet = true
-            }
-        }
-        
-        if updateWorkingSet {
-            signalEnumerator(for: [.workingSet])
-        }
-    }
-    
     // MARK: -
 
     // Convinent method to signal the enumeration for containers.
@@ -206,4 +169,41 @@ class fileProviderData: NSObject {
             }
         }
     }
+    
+    /*
+     func updateFavoriteForWorkingSet() {
+         
+         var updateWorkingSet = false
+         let oldListFavoriteIdentifierRank = listFavoriteIdentifierRank
+         listFavoriteIdentifierRank = NCManageDatabase.sharedInstance.getTableMetadatasDirectoryFavoriteIdentifierRank(account: account)
+         
+         // (ADD)
+         for (identifier, _) in listFavoriteIdentifierRank {
+             
+             guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", identifier)) else { continue }
+             guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadata, homeServerUrl: homeServerUrl) else { continue }
+             let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier)
+                 
+             fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
+             updateWorkingSet = true
+         }
+         
+         // (REMOVE)
+         for (identifier, _) in oldListFavoriteIdentifierRank {
+             
+             if !listFavoriteIdentifierRank.keys.contains(identifier) {
+                 
+                 guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", identifier)) else { continue }
+                 let itemIdentifier = fileProviderUtility.sharedInstance.getItemIdentifier(metadata: metadata)
+                 
+                 fileProviderSignalDeleteWorkingSetItemIdentifier[itemIdentifier] = itemIdentifier
+                 updateWorkingSet = true
+             }
+         }
+         
+         if updateWorkingSet {
+             signalEnumerator(for: [.workingSet])
+         }
+     }
+     */
 }

+ 68 - 73
File Provider Extension/FileProviderEnumerator.swift

@@ -112,14 +112,9 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
                     
                 } else {
                     
-                    readFileOrFolder(serverUrl: serverUrl) {
-                        let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), page: 1, limit: fileProviderData.sharedInstance.itemForPage, sorted: "fileName", ascending: true)
-                        
+                    self.readFileOrFolder(serverUrl: serverUrl) { (metadatas) in
                         self.completeObserver(observer, numPage: 1, metadatas: metadatas)
-                    }
-                    
-                    // Update the WorkingSet -> Favorite
-                    fileProviderData.sharedInstance.updateFavoriteForWorkingSet()
+                    }                    
                 }
                 
             } else {
@@ -133,10 +128,8 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
                     }
                     
                 } else {
-            
-                    let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), page: numPage, limit: fileProviderData.sharedInstance.itemForPage, sorted: "fileName", ascending: true)
-                    
-                    completeObserver(observer, numPage: numPage, metadatas: metadatas)
+
+                    completeObserver(observer, numPage: numPage, metadatas: nil)
                 }
             }
         }
@@ -222,55 +215,43 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
         }
     }
         
-    func readFileOrFolder(serverUrl: String, completionHandler: @escaping () -> Void) {
+    func readFileOrFolder(serverUrl: String, completionHandler: @escaping (_ metadatas: [tableMetadata]?) -> Void) {
+        
+        var directoryEtag: String?
         
-        NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "0", showHiddenFiles: CCUtility.getShowHiddenFiles(), completionHandler: { (account, files, responseData, errorCode, errorDescription) in
+        if let tableDirectory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl)) {
+            directoryEtag = tableDirectory.etag
+        }
             
-            var needReadFolder = true
+        NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "0", showHiddenFiles: CCUtility.getShowHiddenFiles()) { (account, files, responseData, errorCode, errorDescription) in
         
-            if let tableDirectory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl)) {
-                if errorCode == 0 && files != nil && files!.count == 1 {
-                    if tableDirectory.etag == files![0].etag {
-                        needReadFolder = false
-                    }
-                }
-            }
+            if directoryEtag != files.first?.etag {
             
-            if needReadFolder {
-
-                NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", showHiddenFiles: CCUtility.getShowHiddenFiles(), completionHandler: { (account, files, responseData, errorCode, errorDescription) in
+                NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", showHiddenFiles: CCUtility.getShowHiddenFiles()) { (account, files, responseData, errorCode, errorDescription) in
                     
-                    if errorCode == 0 && files != nil {
-                        
-                       let fileFolder = files![0]
-                                                
-                        // Add directory
-                        NCManageDatabase.sharedInstance.addDirectory(encrypted: fileFolder.e2eEncrypted, favorite: fileFolder.favorite, ocId: fileFolder.ocId, fileId: fileFolder.fileId, etag: fileFolder.etag, permissions: fileFolder.permissions, serverUrl: serverUrl, richWorkspace: fileFolder.richWorkspace, account: account)
-                        
-                        // Save status transfer metadata
-                        let metadatasInDownload = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d OR status == %d OR status == %d)", account, serverUrl, k_metadataStatusWaitDownload, k_metadataStatusInDownload, k_metadataStatusDownloading, k_metadataStatusDownloadError))
-                        
-                        let metadatasInUpload = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d OR status == %d OR status == %d)", account, serverUrl, k_metadataStatusWaitUpload, k_metadataStatusInUpload, k_metadataStatusUploading, k_metadataStatusUploadError))
-
-                        // Delete metadata
-                        NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", account, serverUrl, k_metadataStatusNormal))
-
-                        // Add metadata
-                        NCManageDatabase.sharedInstance.addMetadatas(files: files, account: account)
-                         
-                        if metadatasInDownload != nil {
-                            NCManageDatabase.sharedInstance.addMetadatas(metadatasInDownload!)
-                        }
-                        if metadatasInUpload != nil {
-                            NCManageDatabase.sharedInstance.addMetadatas(metadatasInUpload!)
+                    if errorCode == 0 {
+                        DispatchQueue.global().async {
+                            NCManageDatabase.sharedInstance.convertNCCommunicationFilesToMetadatas(files, useMetadataFolder: true, account: account) { (metadataFolder, metadatasFolder, metadatas) in
+                                let metadatasResult = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", account, serverUrl, k_metadataStatusNormal))
+                                NCManageDatabase.sharedInstance.updateMetadatas(metadatas, metadatasResult: metadatasResult)
+                                for metadata in metadatasFolder {
+                                    let serverUrl = metadata.serverUrl + "/" + metadata.fileNameView
+                                    NCManageDatabase.sharedInstance.addDirectory(encrypted: metadata.e2eEncrypted, favorite: metadata.favorite, ocId: metadata.ocId, fileId: metadata.fileId, etag: nil, permissions: metadata.permissions, serverUrl: serverUrl, richWorkspace: metadata.richWorkspace, account: metadata.account)
+                                }
+                                let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), sorted: "fileName", ascending: true)
+                                completionHandler(metadatas)
+                            }
                         }
+                    } else {
+                        let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), sorted: "fileName", ascending: true)
+                        completionHandler(metadatas)
                     }
-                    completionHandler()
-                })
+                }
             } else {
-                completionHandler()
+                let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), sorted: "fileName", ascending: true)
+                completionHandler(metadatas)
             }
-        })
+        }
     }
     
     func getPagination(endpoint:String, serverUrl: String, page: Int, limit: Int, completionHandler: @escaping (_ metadatas: [tableMetadata]?) -> Void) {
@@ -280,34 +261,48 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
         if fileNamePath == "" {
             fileNamePath = "/"
         }
+        var directoryEtag: String?
         
-        NCCommunication.shared.iosHelper(fileNamePath: fileNamePath, serverUrl: serverUrl, offset: offset, limit: limit) { (account, files, errorCode, errorDescription) in
-            
-             if errorCode == 0 && files != nil  && files!.count >= 1 {
+        if let tableDirectory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl)) {
+            if page == 1 {
+                directoryEtag = tableDirectory.etag
+            }
+        }
+        
+        NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "0", showHiddenFiles: CCUtility.getShowHiddenFiles()) { (account, files, responseData, errorCode, errorDescription) in
+        
+            if errorCode == 0 && files.count == 1 && directoryEtag != files.first?.etag {
+                
+                if page == 1 {
+                    let metadataFolder = NCManageDatabase.sharedInstance.convertNCFileToMetadata(files[0], isEncrypted: false, account: account)
+                    NCManageDatabase.sharedInstance.addMetadata(metadataFolder)
+                    NCManageDatabase.sharedInstance.addDirectory(encrypted: metadataFolder.e2eEncrypted, favorite: metadataFolder.favorite, ocId: metadataFolder.ocId, fileId: metadataFolder.fileId, etag: metadataFolder.etag, permissions: metadataFolder.permissions, serverUrl: serverUrl, richWorkspace: metadataFolder.richWorkspace, account: metadataFolder.account)
+                }
                                 
-                NCManageDatabase.sharedInstance.convertNCCommunicationFilesToMetadatas(files!, useMetadataFolder: false, account: account) { (metadataFolder, metadatasFolder, metadatas) in
-                    
-                    // Prepare DB
-                    if offset == 0 {
-                        NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", account, serverUrl, k_metadataStatusNormal))
-                        let metadatasInDownload = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d OR status == %d OR status == %d)", account, serverUrl, k_metadataStatusWaitDownload, k_metadataStatusInDownload, k_metadataStatusDownloading, k_metadataStatusDownloadError))
-                        let metadatasInUpload = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d OR status == %d OR status == %d)", account, serverUrl, k_metadataStatusWaitUpload, k_metadataStatusInUpload, k_metadataStatusUploading, k_metadataStatusUploadError))
-                        if metadatasInDownload != nil {
-                            NCManageDatabase.sharedInstance.addMetadatas(metadatasInDownload!)
-                        }
-                        if metadatasInUpload != nil {
-                            NCManageDatabase.sharedInstance.addMetadatas(metadatasInUpload!)
+                NCCommunication.shared.iosHelper(fileNamePath: fileNamePath, serverUrl: serverUrl, offset: offset, limit: limit) { (account, files, errorCode, errorDescription) in
+                     
+                    if errorCode == 0 {
+                        DispatchQueue.global().async {
+                            NCManageDatabase.sharedInstance.convertNCCommunicationFilesToMetadatas(files, useMetadataFolder: false, account: account) { (metadataFolder, metadatasFolder, metadatas) in
+                                let metadatasResult = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", fileProviderData.sharedInstance.account, serverUrl, k_metadataStatusNormal), page: page, limit: fileProviderData.sharedInstance.itemForPage, sorted: "fileName", ascending: true)
+                                NCManageDatabase.sharedInstance.updateMetadatas(metadatas, metadatasResult: metadatasResult)
+                                for metadata in metadatasFolder {
+                                    let serverUrl = metadata.serverUrl + "/" + metadata.fileNameView
+                                    NCManageDatabase.sharedInstance.addDirectory(encrypted: metadata.e2eEncrypted, favorite: metadata.favorite, ocId: metadata.ocId, fileId: metadata.fileId, etag: nil, permissions: metadata.permissions, serverUrl: serverUrl, richWorkspace: nil, account: metadata.account)
+                                }
+                                let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), page: page, limit: fileProviderData.sharedInstance.itemForPage, sorted: "fileName", ascending: true)
+                                completionHandler(metadatas)
+                            }
                         }
+                    } else {
+                        let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), page: page, limit: fileProviderData.sharedInstance.itemForPage, sorted: "fileName", ascending: true)
+                        completionHandler(metadatas)
                     }
-                    
-                    NCManageDatabase.sharedInstance.addMetadatas(metadatas)
                 }
+            } else {
+                let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), sorted: "fileName", ascending: true)
+                completionHandler(metadatas)
             }
-            
-            let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), page: page, limit: fileProviderData.sharedInstance.itemForPage, sorted: "fileName", ascending: true)
-            
-            completionHandler(metadatas)
         }
     }
-    
 }

+ 68 - 41
File Provider Extension/FileProviderExtension+Actions.swift

@@ -40,35 +40,34 @@ extension FileProviderExtension {
                         
             if errorCode == 0 {
                 
-                let metadata = tableMetadata()
-                
-                metadata.account = account
-                metadata.directory = true
-                metadata.ocId = ocId!
-                metadata.fileId = ""
-                metadata.fileName = directoryName
-                metadata.fileNameView = directoryName
-                metadata.serverUrl = tableDirectory.serverUrl
-                metadata.typeFile = k_metadataTypeFile_directory
-                
-                guard let metadataUpdate = NCManageDatabase.sharedInstance.addMetadata(metadata) else {
-                    completionHandler(nil, NSFileProviderError(.noSuchItem))
-                    return
-                }
-                
-                guard let _ = NCManageDatabase.sharedInstance.addDirectory(encrypted: false, favorite: false, ocId: ocId!, fileId: "", etag: nil, permissions: nil, serverUrl: tableDirectory.serverUrl + "/" + directoryName, richWorkspace: nil, account: account) else {
-                    completionHandler(nil, NSFileProviderError(.noSuchItem))
-                    return
-                }
-                
-                guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadataUpdate, homeServerUrl: fileProviderData.sharedInstance.homeServerUrl) else {
-                    completionHandler(nil, NSFileProviderError(.noSuchItem))
-                    return
+                NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: "0", showHiddenFiles: CCUtility.getShowHiddenFiles()) { (account, files, responseData, errorCode, errorDescription) in
+                    
+                    if errorCode == 0 && files.count > 0 {
+                        
+                        let file = files.first!
+                        let metadata = NCManageDatabase.sharedInstance.convertNCFileToMetadata(file, isEncrypted: false, account: fileProviderData.sharedInstance.account)
+            
+                        NCManageDatabase.sharedInstance.addDirectory(encrypted: false, favorite: false, ocId: ocId!, fileId: metadata.fileId, etag: metadata.etag, permissions: metadata.permissions, serverUrl: serverUrlFileName, richWorkspace: metadata.richWorkspace, account: metadata.account)
+                        NCManageDatabase.sharedInstance.addMetadata(metadata)
+                        
+                        guard let metadataInsert = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocId!)) else {
+                            completionHandler(nil, NSFileProviderError(.noSuchItem))
+                            return
+                        }
+                        
+                        guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadataInsert, homeServerUrl: fileProviderData.sharedInstance.homeServerUrl) else {
+                            completionHandler(nil, NSFileProviderError(.noSuchItem))
+                            return
+                        }
+                     
+                        let item = FileProviderItem(metadata: metadataInsert, parentItemIdentifier: parentItemIdentifier)
+                        completionHandler(item, nil)
+                        
+                    } else {
+                        completionHandler(nil, NSFileProviderError(.serverUnreachable))
+                    }
                 }
                 
-                let item = FileProviderItem(metadata: metadataUpdate, parentItemIdentifier: parentItemIdentifier)
-                completionHandler(item, nil)
-                
             } else {
                 completionHandler(nil, NSFileProviderError(.serverUnreachable))
             }
@@ -82,7 +81,11 @@ extension FileProviderExtension {
             return
         }
         
+        let ocId = metadata.ocId
         let serverUrlFileName = metadata.serverUrl + "/" + metadata.fileName
+        let isDirectory = metadata.directory
+        let serverUrl = metadata.serverUrl;
+        let fileName = metadata.fileName;
         
         NCCommunication.shared.deleteFileOrFolder(serverUrlFileName) { (account, errorCode, errorDescription) in
             
@@ -95,13 +98,13 @@ extension FileProviderExtension {
                     print("error: \(error)")
                 }
                 
-                if metadata.directory {
-                    let dirForDelete = CCUtility.stringAppendServerUrl(metadata.serverUrl, addFileName: metadata.fileName)
+                if isDirectory {
+                    let dirForDelete = CCUtility.stringAppendServerUrl(serverUrl, addFileName: fileName)
                     NCManageDatabase.sharedInstance.deleteDirectoryAndSubDirectory(serverUrl: dirForDelete!, account: account)
                 }
                 
-                NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-                NCManageDatabase.sharedInstance.deleteLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
+                NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", ocId))
+                NCManageDatabase.sharedInstance.deleteLocalFile(predicate: NSPredicate(format: "ocId == %@", ocId))
                 
                 completionHandler(nil)
 
@@ -143,7 +146,7 @@ extension FileProviderExtension {
                     NCManageDatabase.sharedInstance.renameDirectory(ocId: ocIdFrom, serverUrl: serverUrlTo)                    
                 }
                 
-                _ = NCManageDatabase.sharedInstance.moveMetadata(ocId: ocIdFrom, serverUrlTo: serverUrlTo)
+                NCManageDatabase.sharedInstance.moveMetadata(ocId: ocIdFrom, serverUrlTo: serverUrlTo)
                 
                 guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdFrom)) else {
                     completionHandler(nil, NSFileProviderError(.noSuchItem))
@@ -174,13 +177,16 @@ extension FileProviderExtension {
         let fileNameFrom = metadata.fileNameView
         let fileNamePathFrom = metadata.serverUrl + "/" + fileNameFrom
         let fileNamePathTo = metadata.serverUrl + "/" + itemName
+        let ocId = metadata.ocId
         
         NCCommunication.shared.moveFileOrFolder(serverUrlFileNameSource: fileNamePathFrom, serverUrlFileNameDestination: fileNamePathTo, overwrite: false) { (account, errorCode, errorDescription) in
        
             if errorCode == 0 {
                 
                 // Rename metadata
-                guard let metadata = NCManageDatabase.sharedInstance.renameMetadata(fileNameTo: itemName, ocId: metadata.ocId) else {
+                NCManageDatabase.sharedInstance.renameMetadata(fileNameTo: itemName, ocId: ocId)
+                
+                guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocId)) else {
                     completionHandler(nil, NSFileProviderError(.noSuchItem))
                     return
                 }
@@ -200,7 +206,7 @@ extension FileProviderExtension {
                     
                     _ = fileProviderUtility.sharedInstance.moveFile(CCUtility.getDirectoryProviderStorageIconOcId(itemIdentifier.rawValue, etag: metadata.etag), toPath: CCUtility.getDirectoryProviderStorageIconOcId(itemIdentifier.rawValue, etag: metadata.etag))
                     
-                    NCManageDatabase.sharedInstance.setLocalFile(ocId: metadata.ocId, date: nil, exifDate: nil, exifLatitude: nil, exifLongitude: nil, fileName: itemName, etag: nil)
+                    NCManageDatabase.sharedInstance.setLocalFile(ocId: ocId, date: nil, exifDate: nil, exifLatitude: nil, exifLongitude: nil, fileName: itemName, etag: nil)
                 }
                 
                 guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadata, homeServerUrl: fileProviderData.sharedInstance.homeServerUrl) else {
@@ -208,7 +214,7 @@ extension FileProviderExtension {
                     return
                 }
                 
-                let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier)
+                let item = FileProviderItem(metadata: metadata.freeze(), parentItemIdentifier: parentItemIdentifier)
                 completionHandler(item, nil)
                 
             } else {
@@ -230,6 +236,8 @@ extension FileProviderExtension {
         }
         
         var favorite = false
+        let ocId = metadata.ocId
+        
         if favoriteRank == nil {
             fileProviderData.sharedInstance.listFavoriteIdentifierRank.removeValue(forKey: itemIdentifier.rawValue)
         } else {
@@ -244,20 +252,32 @@ extension FileProviderExtension {
             let fileNamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, activeUrl: fileProviderData.sharedInstance.accountUrl)!
             
             NCCommunication.shared.setFavorite(fileName: fileNamePath, favorite: favorite) { (account, errorCode, errorDescription) in
+                
                 if errorCode == 0 {
-                    // Change DB
-                    metadata.favorite = favorite
-                    guard let metadataUpdate = NCManageDatabase.sharedInstance.addMetadata(metadata) else {
+                    
+                    guard let metadataTemp = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocId)) else {
                         completionHandler(nil, NSFileProviderError(.noSuchItem))
                         return
                     }
-                    let item = FileProviderItem(metadata: metadataUpdate, parentItemIdentifier: parentItemIdentifier)
+                    let metadata = tableMetadata.init(value: metadataTemp)
+                    
+                    // Change DB
+                    metadata.favorite = favorite
+                    NCManageDatabase.sharedInstance.addMetadata(metadata)
+                    let item = FileProviderItem(metadata: metadata.freeze(), parentItemIdentifier: parentItemIdentifier)
                     
                     fileProviderData.sharedInstance.fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
                     fileProviderData.sharedInstance.signalEnumerator(for: [.workingSet])
 
                     completionHandler(item, nil)
+                    
                 } else {
+                    
+                    guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocId)) else {
+                        completionHandler(nil, NSFileProviderError(.noSuchItem))
+                        return
+                    }
+                    
                     // Errore, remove from listFavoriteIdentifierRank
                     fileProviderData.sharedInstance.listFavoriteIdentifierRank.removeValue(forKey: itemIdentifier.rawValue)
                     let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier)
@@ -273,13 +293,20 @@ extension FileProviderExtension {
     
     override func setTagData(_ tagData: Data?, forItemIdentifier itemIdentifier: NSFileProviderItemIdentifier, completionHandler: @escaping (NSFileProviderItem?, Error?) -> Void) {
         
-        guard let metadata = fileProviderUtility.sharedInstance.getTableMetadataFromItemIdentifier(itemIdentifier) else {
+        guard let metadataForTag = fileProviderUtility.sharedInstance.getTableMetadataFromItemIdentifier(itemIdentifier) else {
             completionHandler(nil, NSFileProviderError(.noSuchItem))
             return
         }
+        let ocId = metadataForTag.ocId
+        let account = metadataForTag.account
         
         // Add, Remove (nil)
-        NCManageDatabase.sharedInstance.addTag(metadata.ocId, tagIOS: tagData, account: metadata.account)
+        NCManageDatabase.sharedInstance.addTag(ocId, tagIOS: tagData, account: account)
+        
+        guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocId)) else {
+            completionHandler(nil, NSFileProviderError(.noSuchItem))
+            return
+        }
         
         guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadata, homeServerUrl: fileProviderData.sharedInstance.homeServerUrl) else {
             completionHandler(nil, NSFileProviderError(.noSuchItem))

+ 7 - 8
File Provider Extension/FileProviderExtension+NetworkingDelegate.swift

@@ -29,7 +29,8 @@ extension FileProviderExtension: NCNetworkingDelegate {
     func uploadComplete(fileName: String, serverUrl: String, ocId: String?, etag: String?, date: NSDate?, size: Int64, description: String?, task: URLSessionTask, errorCode: Int, errorDescription: String) {
                 
         guard let ocIdTemp = description else { return }
-        guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdTemp)) else { return }
+        guard let metadataTemp = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdTemp)) else { return }
+        let metadata = tableMetadata.init(value: metadataTemp)
         
         let url = URL(fileURLWithPath: CCUtility.getDirectoryProviderStorageOcId(ocIdTemp, fileNameView: fileName))
         DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
@@ -39,9 +40,7 @@ extension FileProviderExtension: NCNetworkingDelegate {
         
         if errorCode == 0 {
             
-            guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadata, homeServerUrl: fileProviderData.sharedInstance.homeServerUrl) else {
-                return
-            }
+            guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadata, homeServerUrl: fileProviderData.sharedInstance.homeServerUrl) else { return }
             var item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier)
             
             // New file
@@ -51,7 +50,7 @@ extension FileProviderExtension: NCNetworkingDelegate {
                 fileProviderData.sharedInstance.fileProviderSignalDeleteWorkingSetItemIdentifier[item.itemIdentifier] = item.itemIdentifier
                 fileProviderData.sharedInstance.signalEnumerator(for: [parentItemIdentifier, .workingSet])
             }
-            
+                        
             metadata.fileName = fileName
             metadata.serverUrl = serverUrl
             if let etag = etag { metadata.etag = etag }
@@ -61,8 +60,8 @@ extension FileProviderExtension: NCNetworkingDelegate {
             metadata.size = Double(size)
             metadata.status = Int(k_metadataStatusNormal)
                   
-            guard let metadataUpdated = NCManageDatabase.sharedInstance.addMetadata(metadata) else { return }
-            _ = NCManageDatabase.sharedInstance.addLocalFile(metadata: metadataUpdated)
+            NCManageDatabase.sharedInstance.addMetadata(metadata)
+            NCManageDatabase.sharedInstance.addLocalFile(metadata: metadata)
             
             // New file
             if ocId != ocIdTemp {
@@ -76,7 +75,7 @@ extension FileProviderExtension: NCNetworkingDelegate {
             }
             
             // Signal update
-            item = FileProviderItem(metadata: metadataUpdated, parentItemIdentifier: parentItemIdentifier)
+            item = FileProviderItem(metadata: metadata.freeze(), parentItemIdentifier: parentItemIdentifier)
             fileProviderData.sharedInstance.fileProviderSignalUpdateContainerItem[item.itemIdentifier] = item
             fileProviderData.sharedInstance.fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item
             fileProviderData.sharedInstance.signalEnumerator(for: [parentItemIdentifier, .workingSet])

+ 17 - 10
File Provider Extension/FileProviderExtension.swift

@@ -211,10 +211,11 @@ class FileProviderExtension: NSFileProviderExtension {
             return
         }
         
-        guard var metadata = fileProviderUtility.sharedInstance.getTableMetadataFromItemIdentifier(identifier) else {
+        guard let metadata = fileProviderUtility.sharedInstance.getTableMetadataFromItemIdentifier(identifier) else {
             completionHandler(NSFileProviderError(.noSuchItem))
             return
         }
+        
         let tableLocalFile = NCManageDatabase.sharedInstance.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
         if tableLocalFile != nil && CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) && tableLocalFile?.etag == metadata.etag  {
             completionHandler(nil)
@@ -226,8 +227,12 @@ class FileProviderExtension: NSFileProviderExtension {
         
         NCCommunication.shared.download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath,  requestHandler: { (request) in
             
-            metadata.status = Int(k_metadataStatusDownloading)
-            if let result = NCManageDatabase.sharedInstance.addMetadata(metadata) { metadata = result }
+            if var metadata = fileProviderUtility.sharedInstance.getTableMetadataFromItemIdentifier(identifier) {
+                metadata = tableMetadata.init(value: metadata)
+                metadata.status = Int(k_metadataStatusDownloading)
+                NCManageDatabase.sharedInstance.addMetadata(metadata)
+            }
+            
             downloadRequest = request
             self.outstandingSessionTasks[url] = task
             
@@ -242,6 +247,11 @@ class FileProviderExtension: NSFileProviderExtension {
         }) { (account, etag, date, length, error, errorCode, errorDescription) in
             
             self.outstandingSessionTasks.removeValue(forKey: url)
+            guard var metadata = fileProviderUtility.sharedInstance.getTableMetadataFromItemIdentifier(identifier) else {
+                completionHandler(NSFileProviderError(.noSuchItem))
+                return
+            }
+            metadata = tableMetadata.init(value: metadata)
             
             if errorCode == 0  {
                 
@@ -250,7 +260,7 @@ class FileProviderExtension: NSFileProviderExtension {
                 metadata.etag = etag ?? ""
                 
                 NCManageDatabase.sharedInstance.addLocalFile(metadata: metadata)
-                if let result = NCManageDatabase.sharedInstance.addMetadata(metadata) { metadata = result }
+                NCManageDatabase.sharedInstance.addMetadata(metadata)
                 
                 completionHandler(nil)
                 
@@ -356,15 +366,12 @@ class FileProviderExtension: NSFileProviderExtension {
                 
                 fileURL.stopAccessingSecurityScopedResource()
                                 
-                let metadata = NCManageDatabase.sharedInstance.createMetadata(account: fileProviderData.sharedInstance.account, fileName: fileName, ocId: ocIdTemp, serverUrl: tableDirectory.serverUrl, url: "", contentType: "")
+                let metadata = NCManageDatabase.sharedInstance.createMetadata(account: fileProviderData.sharedInstance.account, fileName: fileName, ocId: ocIdTemp, serverUrl: tableDirectory.serverUrl, urlBase: fileProviderData.sharedInstance.accountUrl, url: "", contentType: "")
                 metadata.session = NCCommunicationCommon.shared.sessionIdentifierExtension
                 metadata.size = size
                 metadata.status = Int(k_metadataStatusInUpload)
                 
-                guard let metadataForUpload = NCManageDatabase.sharedInstance.addMetadata(metadata) else {
-                    completionHandler(nil, NSFileProviderError(.noSuchItem))
-                    return
-                }
+                NCManageDatabase.sharedInstance.addMetadata(metadata)
                 
                 let serverUrlFileName = tableDirectory.serverUrl + "/" + fileName
                 let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(ocIdTemp, fileNameView: fileName)!
@@ -374,7 +381,7 @@ class FileProviderExtension: NSFileProviderExtension {
                     NSFileProviderManager.default.register(task, forItemWithIdentifier: NSFileProviderItemIdentifier(ocIdTemp)) { (error) in }
                 }
                 
-                let item = FileProviderItem(metadata: metadataForUpload, parentItemIdentifier: parentItemIdentifier)
+                let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier)
                 completionHandler(item, nil)
             }
         }

+ 0 - 4
File Provider Extension/FileProviderItem.swift

@@ -43,10 +43,6 @@ class FileProviderItem: NSObject, NSFileProviderItem {
     
     var typeIdentifier: String {
         let results = NCCommunicationCommon.shared.getInternalContenType(fileName: metadata.fileNameView, contentType: "", directory: metadata.directory)
-        metadata.contentType = results.contentType
-        metadata.iconName = results.iconName
-        metadata.typeFile = results.typeFile
-        
         return results.typeIdentifier
     }
     

+ 24 - 30
Nextcloud.xcodeproj/project.pbxproj

@@ -47,6 +47,8 @@
 		F7063DF12199E56F003F38DA /* CocoaLumberjackSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7063DF02199E56E003F38DA /* CocoaLumberjackSwift.framework */; };
 		F707C26521A2DC5200F6181E /* NCStoreReview.swift in Sources */ = {isa = PBXBuildFile; fileRef = F707C26421A2DC5200F6181E /* NCStoreReview.swift */; };
 		F70968A424212C4E00ED60E5 /* NCLivePhoto.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70968A324212C4E00ED60E5 /* NCLivePhoto.swift */; };
+		F70A58BE24D0349500DED00D /* NCCapabilitiesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70A58BD24D0349500DED00D /* NCCapabilitiesViewController.swift */; };
+		F70A58C024D0545100DED00D /* NCCapabilitiesViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F70A58BF24D0545100DED00D /* NCCapabilitiesViewController.storyboard */; };
 		F70BFC7420E0FA7D00C67599 /* NCUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70BFC7320E0FA7C00C67599 /* NCUtility.swift */; };
 		F70BFC7520E0FA7D00C67599 /* NCUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70BFC7320E0FA7C00C67599 /* NCUtility.swift */; };
 		F70CAE3A1F8CF31A008125FD /* NCEndToEndEncryption.m in Sources */ = {isa = PBXBuildFile; fileRef = F70CAE391F8CF31A008125FD /* NCEndToEndEncryption.m */; };
@@ -244,7 +246,6 @@
 		F7AE00F8230E81CB007ACF8A /* NCBrowserWeb.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7AE00F7230E81CB007ACF8A /* NCBrowserWeb.swift */; };
 		F7AE00FA230E81EB007ACF8A /* NCBrowserWeb.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7AE00F9230E81EB007ACF8A /* NCBrowserWeb.storyboard */; };
 		F7AF7633246BEDFE00B86E3C /* TOPasscodeViewController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7AF7632246BEDFE00B86E3C /* TOPasscodeViewController.framework */; };
-		F7B0C0CD1EE7E7750033AC24 /* CCSynchronize.m in Sources */ = {isa = PBXBuildFile; fileRef = F7B0C0CC1EE7E7750033AC24 /* CCSynchronize.m */; };
 		F7B0C1751EE839A30033AC24 /* NCAutoUpload.m in Sources */ = {isa = PBXBuildFile; fileRef = F7B0C1741EE839A30033AC24 /* NCAutoUpload.m */; };
 		F7B174C822FAC0A8000B7579 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F7B174C722FAC0A8000B7579 /* AppDelegate.m */; };
 		F7B2DEF01F976854007CF4D2 /* NYMnemonic.m in Sources */ = {isa = PBXBuildFile; fileRef = F7B2DEEF1F976785007CF4D2 /* NYMnemonic.m */; };
@@ -388,6 +389,8 @@
 		F707C26421A2DC5200F6181E /* NCStoreReview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCStoreReview.swift; sourceTree = "<group>"; };
 		F70968A324212C4E00ED60E5 /* NCLivePhoto.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCLivePhoto.swift; sourceTree = "<group>"; };
 		F70A07C8205285FB00DC1231 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Localizable.strings"; sourceTree = "<group>"; };
+		F70A58BD24D0349500DED00D /* NCCapabilitiesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCCapabilitiesViewController.swift; sourceTree = "<group>"; };
+		F70A58BF24D0545100DED00D /* NCCapabilitiesViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCCapabilitiesViewController.storyboard; sourceTree = "<group>"; };
 		F70BFC7320E0FA7C00C67599 /* NCUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCUtility.swift; sourceTree = "<group>"; };
 		F70CAE381F8CF31A008125FD /* NCEndToEndEncryption.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NCEndToEndEncryption.h; sourceTree = "<group>"; };
 		F70CAE391F8CF31A008125FD /* NCEndToEndEncryption.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NCEndToEndEncryption.m; sourceTree = "<group>"; };
@@ -620,8 +623,6 @@
 		F7AE00F7230E81CB007ACF8A /* NCBrowserWeb.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCBrowserWeb.swift; sourceTree = "<group>"; };
 		F7AE00F9230E81EB007ACF8A /* NCBrowserWeb.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCBrowserWeb.storyboard; sourceTree = "<group>"; };
 		F7AF7632246BEDFE00B86E3C /* TOPasscodeViewController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = TOPasscodeViewController.framework; path = Carthage/Build/iOS/TOPasscodeViewController.framework; sourceTree = "<group>"; };
-		F7B0C0CB1EE7E7750033AC24 /* CCSynchronize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCSynchronize.h; sourceTree = "<group>"; };
-		F7B0C0CC1EE7E7750033AC24 /* CCSynchronize.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCSynchronize.m; sourceTree = "<group>"; };
 		F7B0C1731EE839A30033AC24 /* NCAutoUpload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NCAutoUpload.h; sourceTree = "<group>"; };
 		F7B0C1741EE839A30033AC24 /* NCAutoUpload.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NCAutoUpload.m; sourceTree = "<group>"; };
 		F7B174C722FAC0A8000B7579 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
@@ -1132,6 +1133,8 @@
 				F7ACE4291BAC0268006C0017 /* Acknowledgements.h */,
 				F7ACE42B1BAC0268006C0017 /* Acknowledgements.rtf */,
 				F7ACE42A1BAC0268006C0017 /* Acknowledgements.m */,
+				F70A58BF24D0545100DED00D /* NCCapabilitiesViewController.storyboard */,
+				F70A58BD24D0349500DED00D /* NCCapabilitiesViewController.swift */,
 				F7A321AB1E9E6AD50069AD1B /* CCAdvanced.h */,
 				F7A321AC1E9E6AD50069AD1B /* CCAdvanced.m */,
 				F7ACE42C1BAC0268006C0017 /* CCManageAccount.h */,
@@ -1157,15 +1160,6 @@
 			path = BrowserWeb;
 			sourceTree = "<group>";
 		};
-		F7B0C0CA1EE7E7750033AC24 /* Synchronize */ = {
-			isa = PBXGroup;
-			children = (
-				F7B0C0CB1EE7E7750033AC24 /* CCSynchronize.h */,
-				F7B0C0CC1EE7E7750033AC24 /* CCSynchronize.m */,
-			);
-			path = Synchronize;
-			sourceTree = "<group>";
-		};
 		F7B0C1701EE8397E0033AC24 /* AutoUpload */ = {
 			isa = PBXGroup;
 			children = (
@@ -1441,7 +1435,6 @@
 				F7ACE4281BAC0268006C0017 /* Settings */,
 				F728CE741BF6322C00E69702 /* Share */,
 				F7169A161EE590930086BD69 /* Shares */,
-				F7B0C0CA1EE7E7750033AC24 /* Synchronize */,
 				F7E9C41320F4CA870040CF18 /* Transfers */,
 				F78F74322163753B00C2ADAD /* Trash */,
 				F70784811A2C8A0D00AC9FFF /* UploadFromOtherUpp */,
@@ -1807,6 +1800,7 @@
 				F78ACD4B21903F850088454D /* NCTrashListCell.xib in Resources */,
 				F700510122DF63AC003A3356 /* NCShare.storyboard in Resources */,
 				F787704F22E7019900F287A9 /* NCShareLinkCell.xib in Resources */,
+				F70A58C024D0545100DED00D /* NCCapabilitiesViewController.storyboard in Resources */,
 				F749C10D23C4A5340027D966 /* NCIntro.storyboard in Resources */,
 				F747BA1F22354D2000971601 /* NCCreateFormUploadVoiceNote.storyboard in Resources */,
 				F7B2DEF11F976859007CF4D2 /* english.txt in Resources */,
@@ -1980,11 +1974,11 @@
 				F7E09CE323E3088000FB3E9E /* NCMainRefreshControl.swift in Sources */,
 				F77B0DF41D118A16002130FE /* CCMain.m in Sources */,
 				F7AE00F8230E81CB007ACF8A /* NCBrowserWeb.swift in Sources */,
+				F70A58BE24D0349500DED00D /* NCCapabilitiesViewController.swift in Sources */,
 				370D26AF248A3D7A00121797 /* NCImageCellProtocol.swift in Sources */,
 				F7E9C41B20F4CA870040CF18 /* CCTransfers.m in Sources */,
 				37C83A0F24532BA600618A3B /* CCMain+Swift.swift in Sources */,
 				F77B0DF51D118A16002130FE /* CCUtility.m in Sources */,
-				F7B0C0CD1EE7E7750033AC24 /* CCSynchronize.m in Sources */,
 				F710D1FE24057E5E00A6033D /* NCActionSheetHeader.swift in Sources */,
 				F790110E21415BF600D7B136 /* NCViewerRichdocument.swift in Sources */,
 				370D26AD248A3BB800121797 /* CCCellMainTransfer.swift in Sources */,
@@ -2213,7 +2207,7 @@
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 18;
+				CURRENT_PROJECT_VERSION = 16;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2232,7 +2226,7 @@
 				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
 				LIBRARY_SEARCH_PATHS = "\"Libraries external\"/**";
-				MARKETING_VERSION = 3.0.1;
+				MARKETING_VERSION = 3.0.2;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
 				OTHER_LDFLAGS = "-ObjC";
@@ -2264,7 +2258,7 @@
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 18;
+				CURRENT_PROJECT_VERSION = 16;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2283,7 +2277,7 @@
 				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
 				LIBRARY_SEARCH_PATHS = "\"Libraries external\"/**";
-				MARKETING_VERSION = 3.0.1;
+				MARKETING_VERSION = 3.0.2;
 				MTL_FAST_MATH = YES;
 				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.Nextcloud.Notification-Service-Extension";
@@ -2307,7 +2301,7 @@
 				CODE_SIGN_ENTITLEMENTS = iOSClient/Brand/Share.entitlements;
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
-				CURRENT_PROJECT_VERSION = 18;
+				CURRENT_PROJECT_VERSION = 16;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2326,7 +2320,7 @@
 				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
 				LIBRARY_SEARCH_PATHS = "\"Libraries external\"/**";
-				MARKETING_VERSION = 3.0.1;
+				MARKETING_VERSION = 3.0.2;
 				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_BUNDLE_IDENTIFIER = it.twsweb.Nextcloud.Share;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -2351,7 +2345,7 @@
 				CODE_SIGN_ENTITLEMENTS = iOSClient/Brand/Share.entitlements;
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
-				CURRENT_PROJECT_VERSION = 18;
+				CURRENT_PROJECT_VERSION = 16;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2370,7 +2364,7 @@
 				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
 				LIBRARY_SEARCH_PATHS = "\"Libraries external\"/**";
-				MARKETING_VERSION = 3.0.1;
+				MARKETING_VERSION = 3.0.2;
 				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_BUNDLE_IDENTIFIER = it.twsweb.Nextcloud.Share;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -2401,7 +2395,7 @@
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 18;
+				CURRENT_PROJECT_VERSION = 16;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2420,7 +2414,7 @@
 				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
 				LIBRARY_SEARCH_PATHS = "\"Libraries external\"/**";
-				MARKETING_VERSION = 3.0.1;
+				MARKETING_VERSION = 3.0.2;
 				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.Nextcloud.File-Provider-Extension";
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -2451,7 +2445,7 @@
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 18;
+				CURRENT_PROJECT_VERSION = 16;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2470,7 +2464,7 @@
 				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
 				LIBRARY_SEARCH_PATHS = "\"Libraries external\"/**";
-				MARKETING_VERSION = 3.0.1;
+				MARKETING_VERSION = 3.0.2;
 				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.Nextcloud.File-Provider-Extension";
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -2493,7 +2487,7 @@
 				CODE_SIGN_ENTITLEMENTS = iOSClient/Brand/iOSClient.entitlements;
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
-				CURRENT_PROJECT_VERSION = 18;
+				CURRENT_PROJECT_VERSION = 16;
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				ENABLE_BITCODE = YES;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2509,7 +2503,7 @@
 				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
 				LIBRARY_SEARCH_PATHS = "";
-				MARKETING_VERSION = 3.0.1;
+				MARKETING_VERSION = 3.0.2;
 				OTHER_LDFLAGS = "-ObjC";
 				OTHER_SWIFT_FLAGS = "";
 				PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.$(PRODUCT_NAME:rfc1034identifier)";
@@ -2538,7 +2532,7 @@
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
 				COPY_PHASE_STRIP = NO;
-				CURRENT_PROJECT_VERSION = 18;
+				CURRENT_PROJECT_VERSION = 16;
 				DEVELOPMENT_TEAM = 6JLRKY9ZV7;
 				ENABLE_BITCODE = YES;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -2553,7 +2547,7 @@
 				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
 				LIBRARY_SEARCH_PATHS = "";
-				MARKETING_VERSION = 3.0.1;
+				MARKETING_VERSION = 3.0.2;
 				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.$(PRODUCT_NAME:rfc1034identifier)";
 				PRODUCT_NAME = "$(TARGET_NAME)";

+ 3 - 3
Share/NCSelectDestination.m

@@ -165,7 +165,7 @@
 
 - (void)readFolder
 {
-    [[NCNetworking shared] readFolderWithServerUrl:_serverUrl account:activeAccount completion:^(NSString *account, tableMetadata *metadataFolder, NSArray *metadatas, NSInteger errorCode, NSString *errorDescription) {
+    [[NCNetworking shared] readFolderWithServerUrl:_serverUrl account:activeAccount completion:^(NSString *account, tableMetadata *metadataFolder, NSArray *metadatas, NSArray *metadatasChanged, NSInteger errorCode, NSString *errorDescription) {
         
         if (errorCode == 0) {
             self.move.enabled = true;
@@ -225,7 +225,7 @@
         }
     }
     
-    NSArray *result = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:predicateDataSource page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO];
+    NSArray *result = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:predicateDataSource page:0 limit:0 sorted:@"fileName" ascending:NO];
     
     if (result)
         return [result count];
@@ -284,7 +284,7 @@
 
 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
 {
-    tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataAtIndexWithPredicate:predicateDataSource sorted:@"fileName" ascending:YES index:indexPath.row];
+    tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataAtIndexWithPredicate:predicateDataSource sorted:@"fileName" ascending:YES index:indexPath.row ];
     
     if (metadata.directory) {
         

+ 1 - 0
Share/ShareViewController.h

@@ -32,6 +32,7 @@
 @interface ShareViewController : UIViewController <UITableViewDelegate, MBProgressHUDDelegate, NCSelectDestinationDelegate, UITextFieldDelegate>
 
 @property (nonatomic, strong) NSString *activeAccount;
+@property (nonatomic, strong) NSString *activeUrl;
 @property (nonatomic, strong) NSString *serverUrl;
 @property (nonatomic, retain) NSMutableArray *filesName;
 

+ 4 - 3
Share/ShareViewController.m

@@ -68,6 +68,7 @@
         [[NCCommunicationCommon shared] setupWithAccount:tableAccount.account user:tableAccount.user userId:tableAccount.userID password:[CCUtility getPassword:tableAccount.account] url:tableAccount.url userAgent:[CCUtility getUserAgent] capabilitiesGroup:[NCBrandOptions sharedInstance].capabilitiesGroups webDavRoot:webDavRoot davRoot:nil nextcloudVersion:serverVersionMajor delegate:[NCNetworking shared]];
        
         _activeAccount = tableAccount.account;
+        _activeUrl = tableAccount.url;
         
         if ([_activeAccount isEqualToString:[CCUtility getActiveAccountExt]]) {
             
@@ -281,15 +282,15 @@
                
                 [CCUtility copyFileAtPath:fileNameLocal toPath:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileNameForUpload]];
                
-                tableMetadata *metadata = [[NCManageDatabase sharedInstance] createMetadataWithAccount:self.activeAccount fileName:fileNameForUpload ocId:ocId serverUrl:self.serverUrl url:@"" contentType:@""];
+                tableMetadata *metadata = [[NCManageDatabase sharedInstance] createMetadataWithAccount:self.activeAccount fileName:fileNameForUpload ocId:ocId serverUrl:self.serverUrl urlBase:self.activeUrl url:@"" contentType:@""];
                                
                 metadata.date = date;
                 metadata.etag = etag;
                 metadata.serverUrl = self.serverUrl;
                 metadata.size = size;
                 
-                metadata = [[NCManageDatabase sharedInstance] addMetadata:metadata];
-                (void)[[NCManageDatabase sharedInstance] addLocalFileWithMetadata:metadata];
+                [[NCManageDatabase sharedInstance] addMetadata:metadata];
+                [[NCManageDatabase sharedInstance] addLocalFileWithMetadata:metadata];
                
                 [self.shareTable performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
                 [self performSelector:@selector(selectPost) withObject:nil];

+ 3 - 4
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))
                     }
                 }
             }
@@ -423,9 +423,8 @@ extension activityTableViewCell: UICollectionViewDelegate {
                                                        
                             CCUtility.moveFile(atPath: atPath, toPath: toPath)
                                                        
-                            if let metadata = NCManageDatabase.sharedInstance.addMetadata(metadata!) {
-                                self.appDelegate.activeMain.performSegue(withIdentifier: "segueDetail", sender: metadata)
-                            }
+                            NCManageDatabase.sharedInstance.addMetadata(metadata!)
+                            self.appDelegate.activeMain.performSegue(withIdentifier: "segueDetail", sender: metadata)
                         }
                     }
                     

+ 8 - 10
iOSClient/AppDelegate.m

@@ -23,7 +23,6 @@
 
 #import "AppDelegate.h"
 #import "CCGraphics.h"
-#import "CCSynchronize.h"
 #import "CCMain.h"
 #import "NCBridgeSwift.h"
 #import "NCAutoUpload.h"
@@ -222,6 +221,8 @@
         [self.window.rootViewController presentViewController:vc animated:YES completion:nil];
     }
     #endif
+    
+    //[[NCNetworking shared] verifyUploadZombie];
 }
 
 //
@@ -712,7 +713,7 @@
     if (self.activeAccount.length == 0 || self.maintenanceMode) return;
             
     NSInteger counterDownload = [[NCOperationQueue shared] downloadCount];
-    NSInteger counterUpload = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"status == %d OR status == %d OR status == %d", k_metadataStatusWaitUpload, k_metadataStatusInUpload, k_metadataStatusUploading] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:YES].count;
+    NSInteger counterUpload = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"status == %d OR status == %d OR status == %d", k_metadataStatusWaitUpload, k_metadataStatusInUpload, k_metadataStatusUploading] page:0 limit:0 sorted:@"fileName" ascending:NO].count;
     NSInteger total = counterDownload + counterUpload;
     
     [UIApplication sharedApplication].applicationIconBadgeNumber = total;
@@ -839,7 +840,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];
     }
 }
 
@@ -894,7 +895,7 @@
         if (isTooLight) {
             NCBrandColor.sharedInstance.brandElement = [NCBrandColor.sharedInstance.brandElement darkerBy:10];
         } else if (isTooDark) {
-            NCBrandColor.sharedInstance.brandElement = [NCBrandColor.sharedInstance.brandElement lighterBy:15];
+            NCBrandColor.sharedInstance.brandElement = [NCBrandColor.sharedInstance.brandElement lighterBy:25];
         }
     
     } else {
@@ -905,7 +906,7 @@
         if (isTooLight) {
             NCBrandColor.sharedInstance.brandElement = [NCBrandColor.sharedInstance.customer darkerBy:10];
         } else if (isTooDark) {
-            NCBrandColor.sharedInstance.brandElement = [NCBrandColor.sharedInstance.customer lighterBy:15];
+            NCBrandColor.sharedInstance.brandElement = [NCBrandColor.sharedInstance.customer lighterBy:25];
         } else {
             NCBrandColor.sharedInstance.brandElement = NCBrandColor.sharedInstance.customer;
         }
@@ -984,7 +985,7 @@
     // after 20 sec
     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 20 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
         
-         NSInteger results = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"session != ''"] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:YES].count;
+        NSInteger results = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"session != ''"] page:0 limit:0 sorted:@"fileName" ascending:NO].count;
         
         if (results > 0) {
             completionHandler(UIBackgroundFetchResultNewData);
@@ -1115,7 +1116,7 @@
                                                     // Push
                                                     NSString *fileName = [[path stringByDeletingLastPathComponent] lastPathComponent];
                                                     NSString *serverUrl = [CCUtility deletingLastPathComponentFromServerUrl:[NSString stringWithFormat:@"%@%@/%@", matchedAccount.url, k_webDAV, [path stringByDeletingLastPathComponent]]];
-                                                    tableMetadata *metadata = [[NCManageDatabase sharedInstance] createMetadataWithAccount:matchedAccount.account fileName:fileName ocId:[[NSUUID UUID] UUIDString] serverUrl:serverUrl url:@"" contentType:@""];
+                                                    tableMetadata *metadata = [[NCManageDatabase sharedInstance] createMetadataWithAccount:matchedAccount.account fileName:fileName ocId:[[NSUUID UUID] UUIDString] serverUrl:serverUrl urlBase: @"" url:@"" contentType:@""];
                                                     [self.activeMain performSegueDirectoryWithMetadata:metadata blinkFileNamePath:fileNamePath];
                                                     
                                                 } else {
@@ -1128,9 +1129,6 @@
                                                 }
                                             });
                                         });
-                                        
-                                        
-                                        
                                     }
                                 }
                             }

+ 9 - 4
iOSClient/AutoUpload/NCAutoUpload.m

@@ -333,10 +333,15 @@
 
 - (void)uploadAssetsNewAndFull:(NSString *)selector
 {
-     if (!appDelegate.activeAccount || appDelegate.maintenanceMode)
+    if (!appDelegate.activeAccount || appDelegate.maintenanceMode) {
          return;
+    }
     
     tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountActive];
+    if (tableAccount == nil) {
+        return;
+    }
+    
     NSMutableArray *metadataFull = [NSMutableArray new];
     NSString *autoUploadPath = [[NCManageDatabase sharedInstance] getAccountAutoUploadPath:appDelegate.activeUrl];
     NSString *serverUrl;
@@ -394,10 +399,10 @@
         else
             serverUrl = autoUploadPath;
         
-        tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND fileNameView == %@", appDelegate.activeAccount, serverUrl, fileName] freeze:true];
+        tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND fileNameView == %@", appDelegate.activeAccount, serverUrl, fileName]];
         if (!metadata) {
         
-            tableMetadata *metadataForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:[[NSUUID UUID] UUIDString] serverUrl:serverUrl url:@"" contentType:@""];
+            tableMetadata *metadataForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:[[NSUUID UUID] UUIDString] serverUrl:serverUrl urlBase:appDelegate.activeUrl url:@"" contentType:@""];
             
             metadataForUpload.assetLocalIdentifier = asset.localIdentifier;
             metadataForUpload.session = session;
@@ -423,7 +428,7 @@
                     if (url != nil) {
                         unsigned long long fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:url.path error:nil] fileSize];
                         
-                        tableMetadata *metadataMOVForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileNameMove ocId:ocId serverUrl:serverUrl url:@"" contentType:@""];
+                        tableMetadata *metadataMOVForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileNameMove ocId:ocId serverUrl:serverUrl urlBase:appDelegate.activeUrl url:@"" contentType:@""];
                         
                         metadataMOVForUpload.session = session;
                         metadataMOVForUpload.sessionSelector = selector;

+ 11 - 5
iOSClient/CCGlobal.h

@@ -158,12 +158,21 @@
 #define k_maxHTTPCache                                  10737418240 // 10GB
 
 // Error
-#define k_CCErrorInternalError                          -9999
+#define k_CCErrorInternalError                          -99999
+#define k_CCErrorFileNotSaved                           -99998
+#define k_CCErrorDecodeMetadata                         -99997
+#define k_CCErrorE2EENotEnabled                         -99996
+#define k_CCErrorE2EENotMove                            -99995
+#define k_CCErrorOffline                                -99994
+#define k_CCErrorCharactersForbidden                    -99993
+#define k_CCErrorCreationFile                           -99992
+
 
 // Search
 #define k_minCharsSearch                                2
 
 // Selector
+#define selectorSynchronize                             @"synchronize"
 #define selectorDownloadSynchronize                     @"downloadSynchronize"
 #define selectorLoadFileView                            @"loadFileView"
 #define selectorLoadFileViewFavorite                    @"loadFileViewFavorite"
@@ -172,10 +181,6 @@
 #define selectorLoadOffline                             @"loadOffline"
 #define selectorOpenIn                                  @"openIn"
 #define selectorOpenInDetail                            @"openInDetail"
-#define selectorReadFile                                @"readFile"
-#define selectorReadFileWithDownload                    @"readFileWithDownload"
-#define selectorReadFolder                              @"readFolder"
-#define selectorReadFolderWithDownload                  @"readFolderWithDownload"
 #define selectorSave                                    @"save"
 #define selectorUploadAutoUpload                        @"uploadAutoUpload"
 #define selectorUploadAutoUploadAll                     @"uploadAutoUploadAll"
@@ -233,6 +238,7 @@
 
 // E2EE
 #define k_max_filesize_E2EE                             524288000   // 500 MB
+#define k_E2EE_API                                      @"1.1"
 
 // Flow Version
 #define k_flow_version_available                        12

+ 99 - 127
iOSClient/Database/NCManageDatabase.swift

@@ -47,7 +47,7 @@ class NCManageDatabase: NSObject {
             let config = Realm.Configuration(
                 fileURL: dirGroup?.appendingPathComponent("\(k_appDatabaseNextcloud)/\(k_databaseDefault)"),
                 schemaVersion: UInt64(k_databaseSchemaVersion),
-                objectTypes: [tableMetadata.self, tableLocalFile.self, tableDirectory.self, tableTag.self, tableAccount.self, tableCapabilities.self]
+                objectTypes: [tableMetadata.self, tableLocalFile.self, tableDirectory.self, tableTag.self, tableAccount.self, tableCapabilities.self, tableE2eEncryption.self]
             )
             
             Realm.Configuration.defaultConfiguration = config
@@ -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 {}
@@ -872,6 +872,23 @@ class NCManageDatabase: NSObject {
         }
     }
     
+    @objc func getCapabilities(account: String) -> String? {
+                           
+        let realm = try! Realm()
+        realm.refresh()
+               
+        guard let result = realm.objects(tableCapabilities.self).filter("account == %@", account).first else {
+            return nil
+        }
+        guard let jsondata = result.jsondata else {
+            return nil
+        }
+               
+        let json = JSON(jsondata)
+        
+        return json.rawString()
+    }
+    
     @objc func getCapabilitiesServerString(account: String, elements: Array<String>) -> String? {
 
         let realm = try! Realm()
@@ -994,7 +1011,7 @@ class NCManageDatabase: NSObject {
         
         let results = realm.objects(tableComments.self).filter("account == %@ AND objectId == %@", account, objectId).sorted(byKeyPath: "creationDateTime", ascending: false)
         
-        return Array(results.map { tableComments.init(value:$0) })
+        return Array(results.map { $0.freeze() })
     }
     
     //MARK: -
@@ -1061,7 +1078,7 @@ class NCManageDatabase: NSObject {
         let results = realm.objects(tableDirectEditingCreators.self).filter("account == %@", account)
         
         if (results.count > 0) {
-            return Array(results.map { tableDirectEditingCreators.init(value:$0) })
+            return Array(results.map { $0.freeze() })
         } else {
             return nil
         }
@@ -1074,7 +1091,7 @@ class NCManageDatabase: NSObject {
         let results = realm.objects(tableDirectEditingCreators.self).filter(predicate)
         
         if (results.count > 0) {
-            return Array(results.map { tableDirectEditingCreators.init(value:$0) })
+            return Array(results.map { $0.freeze() })
         } else {
             return nil
         }
@@ -1086,7 +1103,7 @@ class NCManageDatabase: NSObject {
         let results = realm.objects(tableDirectEditingEditors.self).filter("account == %@", account)
         
         if (results.count > 0) {
-            return Array(results.map { tableDirectEditingEditors.init(value:$0) })
+            return Array(results.map { $0.freeze() })
         } else {
             return nil
         }
@@ -1099,8 +1116,7 @@ class NCManageDatabase: NSObject {
         return tableDirectory.init(value: directory)
     }
     
-    @discardableResult
-    @objc func addDirectory(encrypted: Bool, favorite: Bool, ocId: String, fileId: String, etag: String?, permissions: String?, serverUrl: String, richWorkspace: String?, account: String) -> tableDirectory? {
+    @objc func addDirectory(encrypted: Bool, favorite: Bool, ocId: String, fileId: String, etag: String?, permissions: String?, serverUrl: String, richWorkspace: String?, account: String) {
         
         let realm = try! Realm()
         realm.beginWrite()
@@ -1134,10 +1150,7 @@ class NCManageDatabase: NSObject {
             try realm.commitWrite()
         } catch let error {
             print("[LOG] Could not write to database: ", error)
-            return nil
         }
-    
-        return tableDirectory.init(value: addObject)
     }
     
     @objc func deleteDirectoryAndSubDirectory(serverUrl: String, account: String) {
@@ -1572,8 +1585,7 @@ class NCManageDatabase: NSObject {
         return tableLocalFile.init(value: localFile)
     }
     
-    @discardableResult
-    @objc func addLocalFile(metadata: tableMetadata) -> tableLocalFile? {
+    @objc func addLocalFile(metadata: tableMetadata) {
         
         let realm = try! Realm()
         let addObject = tableLocalFile()
@@ -1595,10 +1607,7 @@ class NCManageDatabase: NSObject {
             }
         } catch let error {
             print("[LOG] Could not write to database: ", error)
-            return nil
         }
-        
-        return tableLocalFile.init(value: addObject)
     }
     
     @objc func deleteLocalFile(predicate: NSPredicate) {
@@ -1660,22 +1669,17 @@ class NCManageDatabase: NSObject {
         guard let result = realm.objects(tableLocalFile.self).filter(predicate).first else {
             return nil
         }
-
-        return tableLocalFile.init(value: result)
+        
+        return result.freeze()
     }
     
-    @objc func getTableLocalFiles(predicate: NSPredicate, sorted: String, ascending: Bool) -> [tableLocalFile]? {
+    @objc func getTableLocalFiles(predicate: NSPredicate, sorted: String, ascending: Bool) -> [tableLocalFile] {
         
         let realm = try! Realm()
         realm.refresh()
         
         let results = realm.objects(tableLocalFile.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
-        
-        if (results.count > 0) {
-            return Array(results.map { tableLocalFile.init(value:$0) })
-        } else {
-            return nil
-        }
+        return Array(results.map { $0.freeze() })
     }
     
     @objc func setLocalFile(ocId: String, offline: Bool) {
@@ -1795,7 +1799,7 @@ class NCManageDatabase: NSObject {
         completion(metadataFolder, metadataFolders, metadatas)
     }
     
-    @objc func createMetadata(account: String, fileName: String, ocId: String, serverUrl: String, url: String, contentType: String) -> tableMetadata {
+    @objc func createMetadata(account: String, fileName: String, ocId: String, serverUrl: String, urlBase: String, url: String, contentType: String) -> tableMetadata {
         
         let metadata = tableMetadata()
         let results = NCCommunicationCommon.shared.getInternalContenType(fileName: fileName, contentType: contentType, directory: false)
@@ -1813,12 +1817,12 @@ class NCManageDatabase: NSObject {
         metadata.typeFile = results.typeFile
         metadata.uploadDate = Date() as NSDate
         metadata.url = url
+        metadata.urlBase = urlBase
         
         return metadata
     }
     
-    @discardableResult
-    @objc func addMetadata(_ metadata: tableMetadata) -> tableMetadata? {
+    @objc func addMetadata(_ metadata: tableMetadata) {
 
         let realm = try! Realm()
 
@@ -1828,35 +1832,24 @@ class NCManageDatabase: NSObject {
             }
         } catch let error {
             print("[LOG] Could not write to database: ", error)
-            return nil
         }
-                
-        return tableMetadata.init(value: metadata)
     }
     
-    @discardableResult
-    @objc func addMetadatas(_ metadatas: [tableMetadata]) -> [tableMetadata]? {
+    @objc func addMetadatas(_ metadatas: [tableMetadata]) {
         
-        var directoryToClearDate: [String: String] = [:]
-
         let realm = try! Realm()
 
         do {
             try realm.write {
                 for metadata in metadatas {
-                    directoryToClearDate[metadata.serverUrl] = metadata.account
                     realm.add(metadata, update: .all)
                 }
             }
         } catch let error {
             print("[LOG] Could not write to database: ", error)
-            return nil
         }
-        
-        
-        return Array(metadatas.map { tableMetadata.init(value:$0) })
     }
-
+    
     @objc func addMetadatas(files: [NCCommunicationFile]?, account: String) {
     
         guard let files = files else { return }
@@ -1915,19 +1908,12 @@ class NCManageDatabase: NSObject {
     }
     
     @objc func deleteMetadata(predicate: NSPredicate) {
-        
-        var directoryToClearDate: [String: String] = [:]
-        
+                
         let realm = try! Realm()
 
         realm.beginWrite()
 
         let results = realm.objects(tableMetadata.self).filter(predicate)
-        
-        for result in results {
-            directoryToClearDate[result.serverUrl] = result.account
-        }
-        
         realm.delete(results)
         
         do {
@@ -1938,8 +1924,7 @@ class NCManageDatabase: NSObject {
         }
     }
     
-    @discardableResult
-    @objc func moveMetadata(ocId: String, serverUrlTo: String) -> tableMetadata? {
+    @objc func moveMetadata(ocId: String, serverUrlTo: String) {
         
         var result: tableMetadata?
         let realm = try! Realm()
@@ -1953,14 +1938,7 @@ class NCManageDatabase: NSObject {
             }
         } catch let error {
             print("[LOG] Could not write to database: ", error)
-            return nil
         }
-        
-        if result == nil {
-            return nil
-        }
-        
-        return tableMetadata.init(value: result!)
     }
     
     @objc func addMetadataServerUrl(ocId: String, serverUrl: String) {
@@ -1980,8 +1958,7 @@ class NCManageDatabase: NSObject {
         }
     }
     
-    @discardableResult
-    @objc func renameMetadata(fileNameTo: String, ocId: String) -> tableMetadata? {
+    @objc func renameMetadata(fileNameTo: String, ocId: String) {
         
         var result: tableMetadata?
         let realm = try! Realm()
@@ -1996,30 +1973,60 @@ class NCManageDatabase: NSObject {
             }
         } catch let error {
             print("[LOG] Could not write to database: ", error)
-            return nil
-        }
-        
-        if result == nil {
-            return nil
         }
-        
-        return tableMetadata.init(value: result!)
     }
-    
-    @objc func updateMetadata(_ metadata: tableMetadata) -> tableMetadata? {
+
+    @discardableResult
+    @objc func updateMetadatas(_ metadatas: [tableMetadata], metadatasResult: [tableMetadata] ,withVerifyLocal local: Bool = false) -> [tableMetadata] {
         
         let realm = try! Realm()
-
+        var ocIdsUdated : [String] = []
+        var metadatasUdated : [tableMetadata] = []
+        
         do {
             try realm.write {
-                realm.add(metadata, update: .all)
+                // DELETE
+                for metadataResult in metadatasResult {
+                    if metadatas.firstIndex(where: { $0.ocId == metadataResult.ocId }) == nil {
+                        if let result = realm.objects(tableMetadata.self).filter(NSPredicate(format: "ocId == %@", metadataResult.ocId)).first {
+                            realm.delete(result)
+                        }
+                    }
+                }
+                // UPDATE/NEW
+                for metadata in metadatas {
+                    var updated = false
+                    if let result = metadatasResult.first(where: { $0.ocId == metadata.ocId }) {
+                        // update
+                        if result.status == k_metadataStatusNormal && result.etag != metadata.etag {
+                            ocIdsUdated.append(metadata.ocId)
+                            realm.add(metadata, update: .all)
+                            updated = true
+                        }
+                    } else {
+                        // new
+                        ocIdsUdated.append(metadata.ocId)
+                        realm.add(metadata, update: .all)
+                        updated = true
+                    }
+                    if local && !updated {
+                        if realm.objects(tableLocalFile.self).filter(NSPredicate(format: "ocId == %@", metadata.ocId)).first == nil {
+                           ocIdsUdated.append(metadata.ocId)
+                        }
+                    }
+                }
             }
         } catch let error {
             print("[LOG] Could not write to database: ", error)
-            return nil
         }
-                
-        return tableMetadata.init(value: metadata)
+        
+        for ocId in ocIdsUdated {
+            if let result = realm.objects(tableMetadata.self).filter(NSPredicate(format: "ocId == %@", ocId)).first {
+                metadatasUdated.append(result.freeze())
+            }
+        }
+        
+        return metadatasUdated
     }
     
     func setMetadataSession(ocId: String, session: String? = nil, sessionError: String? = nil, sessionSelector: String? = nil, sessionTaskIdentifier: Int? = nil, status: Int? = nil, etag: String? = nil, setFavorite: Bool = false) {
@@ -2128,41 +2135,19 @@ class NCManageDatabase: NSObject {
             return nil
         }
         
-        return tableMetadata.init(value: result)
+        return result.freeze()
     }
     
-    @objc func getMetadata(predicate: NSPredicate, freeze: Bool) -> tableMetadata? {
+    @objc func getMetadata(predicate: NSPredicate, sorted: String, ascending: Bool) -> tableMetadata? {
         
         let realm = try! Realm()
         realm.refresh()
         
-        guard let result = realm.objects(tableMetadata.self).filter(predicate).first else {
-            return nil
-        }
-        
-        if freeze {
-            return result.freeze()
-        } else {
-            return result
-        }
-    }
-    
-    @objc func getMetadata(predicate: NSPredicate, sorted: String, ascending: Bool, freeze: Bool = false) -> tableMetadata? {
-        
-        let realm = try! Realm()
-        realm.refresh()
-        
-        let results = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
-        
-        if (results.count > 0) {
-            if freeze {
-                return results[0].freeze()
-            } else {
-                return tableMetadata.init(value: results[0])
-            }
-        } else {
+        guard let result = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending).first else {
             return nil
         }
+       
+        return result.freeze()
     }
     
     @objc func getMetadatasViewer(predicate: NSPredicate, sorted: String, ascending: Bool) -> [tableMetadata]? {
@@ -2198,28 +2183,25 @@ class NCManageDatabase: NSObject {
         }
         
         if (finals.count > 0) {
-            return Array(finals.map { tableMetadata.init(value:$0) })
+            return Array(finals.map { tableMetadata.init(value:$0.freeze()) })
         } else {
             return nil
         }
     }
     
-    @objc func getMetadatas(predicate: NSPredicate, page: Int = 0, limit: Int = 0, sorted: String = "fileName", ascending: Bool = false, freeze: Bool = false) -> [tableMetadata]? {
+    @objc func getMetadatas(predicate: NSPredicate, page: Int = 0, limit: Int = 0, sorted: String = "fileName", ascending: Bool = false) -> [tableMetadata] {
         
         let realm = try! Realm()
         realm.refresh()
+        var metadatas: [tableMetadata] = []
         
         let results = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
         
         if results.count > 0 {
             if page == 0 || limit == 0 {
-                if freeze {
-                    return Array(results.freeze())
-                } else {
-                    return Array(results.map { tableMetadata.init(value:$0) })
-                }
+                return Array(results.freeze())
             } else {
-                var metadatas: [tableMetadata] = []
+                
                 let nFrom = (page - 1) * limit
                 let nTo = nFrom + (limit - 1)
                 
@@ -2227,17 +2209,11 @@ class NCManageDatabase: NSObject {
                     if n == results.count {
                         break
                     }
-                    if freeze {
-                        metadatas.append(results[n].freeze())
-                    } else {
-                        metadatas.append(tableMetadata.init(value: results[n]))
-                    }
+                    metadatas.append(results[n].freeze())
                 }
-                return metadatas
             }
-        } else {
-            return nil
         }
+        return metadatas
     }
     
     @objc func getMetadataAtIndex(predicate: NSPredicate, sorted: String, ascending: Bool, index: Int) -> tableMetadata? {
@@ -2248,13 +2224,13 @@ class NCManageDatabase: NSObject {
         let results = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending)
         
         if (results.count > 0  && results.count > index) {
-            return tableMetadata.init(value: results[index])
+            return tableMetadata.init(value: results[index].freeze())
         } else {
             return nil
         }
     }
     
-    @objc func getMetadataInSessionFromFileName(_ fileName: String, serverUrl: String, taskIdentifier: Int, freeze: Bool) -> tableMetadata? {
+    @objc func getMetadataInSessionFromFileName(_ fileName: String, serverUrl: String, taskIdentifier: Int) -> tableMetadata? {
         
         let realm = try! Realm()
         realm.refresh()
@@ -2263,11 +2239,7 @@ class NCManageDatabase: NSObject {
             return nil
         }
         
-        if freeze {
-            return result.freeze()
-        } else {
-            return tableMetadata.init(value: result)
-        }
+        return result.freeze()
     }
     
     @objc func getTableMetadatasDirectoryFavoriteIdentifierRank(account: String) -> [String: NSNumber] {
@@ -2381,10 +2353,10 @@ class NCManageDatabase: NSObject {
             return nil
         }
         
-        return tableMetadata.init(value: result)
+        return result.freeze()
     }
     
-    @objc func getMetadatasMedia(predicate: NSPredicate, sort: String, ascending: Bool = false, completion: @escaping (_ metadatas: [tableMetadata])->()) {
+    func getMetadatasMedia(predicate: NSPredicate, sort: String, ascending: Bool = false, completion: @escaping (_ metadatas: [tableMetadata])->()) {
                 
         DispatchQueue.global().async {
             autoreleasepool {

+ 0 - 1
iOSClient/Favorites/CCFavorites.h

@@ -41,7 +41,6 @@
 @property (nonatomic, strong) NSString *titleViewControl;
 
 - (void)shouldPerformSegue:(tableMetadata *)metadata selector:(NSString *)selector;
-- (void)listingFavorites;
 - (void)actionDelete:(NSIndexPath *)indexPath;
 
 @end

+ 16 - 69
iOSClient/Favorites/CCFavorites.m

@@ -23,7 +23,6 @@
 
 #import "CCFavorites.h"
 #import "AppDelegate.h"
-#import "CCSynchronize.h"
 
 #import "NCBridgeSwift.h"
 
@@ -98,6 +97,13 @@
     [self changeTheming];
 }
 
+- (void)viewWillAppear:(BOOL)animated
+{
+    [super viewDidAppear:animated];
+    
+    [self reloadDatasource];
+}
+
 - (void)viewDidAppear:(BOOL)animated
 {
     [super viewDidAppear:animated];
@@ -105,10 +111,10 @@
     // Active Main
     appDelegate.activeFavorites = self;
 
-    [self reloadDatasource];
-
-    if (self.serverUrl == nil) {
-        [self listingFavorites];
+    if (self.serverUrl == nil && appDelegate.activeAccount.length > 0) {
+        [[NCNetworking shared] listingFavoritescompletionWithCompletion:^(NSString *account, NSArray* metadatas, NSInteger errorCode, NSString *errorDescription) {
+             [self reloadDatasource];
+        }];
     }
 }
 
@@ -170,65 +176,6 @@
     return [[NSAttributedString alloc] initWithString:text attributes:attributes];
 }
 
-#pragma --------------------------------------------------------------------------------------------
-#pragma mark ===== listingFavorites =====
-#pragma--------------------------------------------------------------------------------------------
-
-- (void)listingFavorites
-{
-    // test
-    if (appDelegate.activeAccount.length == 0)
-        return;
-
-    [[NCCommunication shared] listingFavoritesWithShowHiddenFiles:[CCUtility getShowHiddenFiles] customUserAgent:nil addCustomHeaders:nil completionHandler:^(NSString *account, NSArray *files, NSInteger errorCode, NSString *errorMessage) {
-        if (errorCode == 0 && [account isEqualToString:appDelegate.activeAccount] && files != nil) {
-            [[NCManageDatabase sharedInstance] convertNCCommunicationFilesToMetadatas:files useMetadataFolder:false account:account completion:^(tableMetadata *metadataFolder, NSArray<tableMetadata *> *metadatasFolder, NSArray<tableMetadata *> *metadatas) {
-                NSString *father = @"";
-                NSMutableArray *filesOcId = [NSMutableArray new];
-                 
-                for (tableMetadata *metadata in metadatas) {
-                    // insert for test NOT favorite
-                    [filesOcId addObject:metadata.ocId];
-                    NSString *serverUrl = metadata.serverUrl;
-                    NSString *serverUrlSon = [CCUtility stringAppendServerUrl:serverUrl addFileName:metadata.fileName];
-                    if (![serverUrlSon containsString:father]) {
-                        if (metadata.directory) {
-                            if ([CCUtility getFavoriteOffline])
-                                [[CCSynchronize sharedSynchronize] readFolder:[CCUtility stringAppendServerUrl:serverUrl addFileName:metadata.fileName] selector:selectorReadFolderWithDownload account:account];
-                            else
-                                [[CCSynchronize sharedSynchronize] readFolder:[CCUtility stringAppendServerUrl:serverUrl addFileName:metadata.fileName] selector:selectorReadFolder account:account];
-                        } else {
-                            if ([CCUtility getFavoriteOffline])
-                                [[CCSynchronize sharedSynchronize] readFile:metadata.ocId fileName:metadata.fileName serverUrl:serverUrl selector:selectorReadFileWithDownload account:account];
-                            else
-                                [[CCSynchronize sharedSynchronize] readFile:metadata.ocId fileName:metadata.fileName serverUrl:serverUrl selector:selectorReadFile account:account];
-                        }
-                        father = serverUrlSon;
-                    }
-                    tableMetadata *metadataFavorite = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"ocId == %@", metadata.ocId]];
-                    if (metadataFavorite == nil) {
-                        [[NCManageDatabase sharedInstance] addMetadata:metadata];
-                    } else if (!metadataFavorite.favorite) {
-                        [[NCManageDatabase sharedInstance] setMetadataFavoriteWithOcId:metadata.ocId favorite:true];
-                    }
-                }
-                 
-                // Verify remove favorite
-                NSArray *allRecordFavorite = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND favorite == true", account] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO];
-                for (tableMetadata *metadata in allRecordFavorite)
-                    if (![filesOcId containsObject:metadata.ocId])
-                        [[NCManageDatabase sharedInstance] setMetadataFavoriteWithOcId:metadata.ocId favorite:NO];
-                
-                [self reloadDatasource];
-            }];
-        } else if (errorCode != 0) {
-            [[NCContentPresenter shared] messageNotification:@"_error_" description:errorMessage delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode];
-        } else {
-            NSLog(@"[LOG] It has been changed user during networking process, error.");
-        }
-    }];
-}
-
 - (void)tapActionComment:(UITapGestureRecognizer *)tapGesture
 {
     CGPoint location = [tapGesture locationInView:self.tableView];
@@ -431,11 +378,11 @@
     
     if (!_serverUrl) {
         
-        recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND favorite == true", appDelegate.activeAccount] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO];
+        recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND favorite == true", appDelegate.activeAccount] page:0 limit:0 sorted:@"fileName" ascending:NO];
         
     } else {
         
-        recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", appDelegate.activeAccount, self.serverUrl] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO];
+        recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", appDelegate.activeAccount, self.serverUrl] page:0 limit:0 sorted:@"fileName" ascending:NO];
     }
     
     sectionDataSource = [CCSectionMetadata creataDataSourseSectionMetadata:recordsTableMetadata listProgressMetadata:nil groupByField:nil filterTypeFileImage:NO filterTypeFileVideo:NO filterLivePhoto:YES sorted:sorted ascending:[CCUtility getAscendingSettings] activeAccount:appDelegate.activeAccount];
@@ -577,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 {
                     
@@ -590,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]) {
@@ -598,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 {

+ 8 - 16
iOSClient/Images.xcassets/avatarBN.imageset/Contents.json

@@ -1,23 +1,15 @@
 {
   "images" : [
     {
-      "idiom" : "universal",
-      "filename" : "avatarBN.png",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "avatarBN@2x.png",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "avatarBN@3x.png",
-      "scale" : "3x"
+      "filename" : "avatarBN.pdf",
+      "idiom" : "universal"
     }
   ],
   "info" : {
-    "version" : 1,
-    "author" : "xcode"
+    "author" : "xcode",
+    "version" : 1
+  },
+  "properties" : {
+    "preserves-vector-representation" : true
   }
-}
+}

二進制
iOSClient/Images.xcassets/avatarBN.imageset/avatarBN.pdf


二進制
iOSClient/Images.xcassets/avatarBN.imageset/avatarBN.png


二進制
iOSClient/Images.xcassets/avatarBN.imageset/avatarBN@2x.png


二進制
iOSClient/Images.xcassets/avatarBN.imageset/avatarBN@3x.png


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

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

二進制
iOSClient/Images.xcassets/capabilities.imageset/capabilities.pdf


+ 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
+  }
+}

二進制
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
+  }
+}

二進制
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"
-  }
-}

二進制
iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud.png


二進制
iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud@2x.png


二進制
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
                     }

+ 2 - 2
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)
         }
     }
     
@@ -138,7 +138,7 @@ extension NCLoginWeb: WKNavigationDelegate {
             if server != "" && user != "" && password != "" {
                 
                 let server: String = server.replacingOccurrences(of: "/server:", with: "")
-                let username: String = user.replacingOccurrences(of: "user:", with: "")
+                let username: String = user.replacingOccurrences(of: "user:", with: "").replacingOccurrences(of: "+", with: " ")
                 let password: String = password.replacingOccurrences(of: "password:", with: "")
                 
                 createAccount(server: server, username: username, password: password)

+ 68 - 71
iOSClient/Main/CCMain.m

@@ -23,7 +23,6 @@
 
 #import "CCMain.h"
 #import "AppDelegate.h"
-#import "CCSynchronize.h"
 #import "NCAutoUpload.h"
 #import "NCBridgeSwift.h"
 #import "PKDownloadButton.h"
@@ -138,6 +137,7 @@
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moveFile:) name:k_notificationCenter_moveFile object:nil];
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(copyFile:) name:k_notificationCenter_copyFile object:nil];
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeTheming) name:k_notificationCenter_changeTheming object:nil];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(createFolder:) name:k_notificationCenter_createFolder object:nil];
     
     // Search
     self.definesPresentationContext = YES;
@@ -432,6 +432,21 @@
 #pragma mark ==== NotificationCenter ====
 #pragma --------------------------------------------------------------------------------------------
 
+- (void)createFolder:(NSNotification *)notification
+{
+    NSDictionary *userInfo = notification.userInfo;
+    NSString *serverUrl = userInfo[@"serverUrl"];
+    NSInteger errorCode = [userInfo[@"errorCode"] integerValue];
+    
+    if (![serverUrl isEqualToString:self.serverUrl]) { return; }
+    if (errorCode == 0) {
+        BOOL isFolderEncrypted = [CCUtility isFolderEncrypted:serverUrl e2eEncrypted:nil account:appDelegate.activeAccount];
+        if (isFolderEncrypted) {
+            [self readFolder:serverUrl];
+        }
+    }
+}
+
 - (void)deleteFile:(NSNotification *)notification
 {
     NSDictionary *userInfo = notification.userInfo;
@@ -458,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];
     }
 }
 
@@ -481,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];
     }
 }
 
@@ -504,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];
     }
 }
 
@@ -524,23 +539,17 @@
         } 
         
         if (metadata.directory && favorite) {
-                       
-            NSString *selector;
-                       
-            if ([CCUtility getFavoriteOffline])
-                selector = selectorReadFolderWithDownload;
-            else
-                selector = selectorReadFolder;
-                       
-            [[CCSynchronize sharedSynchronize] readFolder:[CCUtility stringAppendServerUrl:self.serverUrl addFileName:metadata.fileName] selector:selector account:appDelegate.activeAccount];
-        }
-                   
-        if (!metadata.directory && favorite && [CCUtility getFavoriteOffline]) {
-                   
+            if ([CCUtility getFavoriteOffline]) {
+                [[NCOperationQueue shared] synchronizationMetadata:metadata selector:selectorDownloadSynchronize];
+            } else {
+                [[NCOperationQueue shared] synchronizationMetadata:metadata selector:selectorSynchronize];
+            }
+        } else if (!metadata.directory && favorite && [CCUtility getFavoriteOffline]) {
             [[NCNetworking shared] downloadWithMetadata:metadata selector:selectorDownloadSynchronize setFavorite:true completion:^(NSInteger errorCode) { }];
         }
+        
     } 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];
     }
 }
 
@@ -764,7 +773,7 @@
                 
                 if ([data writeToFile:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileName] options:NSDataWritingAtomic error:&error]) {
                     
-                    tableMetadata *metadataForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:ocId serverUrl:serverUrl url:@"" contentType:@""];
+                    tableMetadata *metadataForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:ocId serverUrl:serverUrl urlBase:appDelegate.activeUrl url:@"" contentType:@""];
                     
                     metadataForUpload.session = NCCommunicationCommon.shared.sessionIdentifierBackground;
                     metadataForUpload.sessionSelector = selectorUploadFile;
@@ -787,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];
             }
         }];
     }
@@ -854,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_CCErrorFileNotSaved forced:false];
     }
     
     if ([metadata.typeFile isEqualToString: k_metadataTypeFile_video] && status == PHAuthorizationStatusAuthorized) {
@@ -863,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_CCErrorFileNotSaved forced:false];
         }
     }
     
@@ -880,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];
     }
 }
 
@@ -955,29 +964,12 @@
 {
     if (_isSelectedMode && [_selectedocIdsMetadatas count] == 0)
         return;
-
-    NSLog(@"[LOG] Start download selected ...");
-    
-    [_hud visibleHudTitle:NSLocalizedString(@"_downloading_progress_", nil) mode:MBProgressHUDModeIndeterminate color:nil];
     
     NSArray *selectedMetadatas = [self getMetadatasFromSelectedRows:[self.tableView indexPathsForSelectedRows]];
-    
-    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void) {
         
-        for (tableMetadata *metadata in selectedMetadatas) {
-            
-            if (metadata.directory) {
-                
-                [[CCSynchronize sharedSynchronize] readFolder:[CCUtility stringAppendServerUrl:metadata.serverUrl addFileName:metadata.fileName] selector:selectorReadFolderWithDownload account:appDelegate.activeAccount];
-                    
-            } else {
-                
-                [[CCSynchronize sharedSynchronize] readFile:metadata.ocId fileName:metadata.fileName serverUrl:metadata.serverUrl selector:selectorReadFileWithDownload account:appDelegate.activeAccount];
-            }
-        }
-        
-        [_hud hideHud];
-    });
+    for (tableMetadata *metadata in selectedMetadatas) {
+        [[NCOperationQueue shared] synchronizationMetadata:metadata selector:selectorDownloadSynchronize];
+    }
     
     [self tableViewSelect:false];
 }
@@ -1029,12 +1021,12 @@
         }
         
         // Check if is in upload
-        NSArray *isRecordInSessions = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND fileName == %@ AND session != ''", appDelegate.activeAccount, serverUrl, fileName] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:YES];
+        NSArray *isRecordInSessions = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND fileName == %@ AND session != ''", appDelegate.activeAccount, serverUrl, fileName] page:0 limit:0 sorted:@"fileName" ascending:NO];
         if ([isRecordInSessions count] > 0)
             continue;
         
         // Prepare record metadata
-        tableMetadata *metadataForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:[[NSUUID UUID] UUIDString] serverUrl:serverUrl url:@"" contentType:@""];
+        tableMetadata *metadataForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:[[NSUUID UUID] UUIDString] serverUrl:serverUrl urlBase:appDelegate.activeUrl url:@"" contentType:@""];
         
         metadataForUpload.assetLocalIdentifier = asset.localIdentifier;
         metadataForUpload.session = session;
@@ -1057,7 +1049,7 @@
             NSString *fileName = [NSString stringWithFormat:@"%@.mov", fileNameNoExt];
             unsigned long long fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:url.path error:nil] fileSize];
 
-            tableMetadata *metadataMOVForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:[[NSUUID UUID] UUIDString] serverUrl:serverUrl url:@"" contentType:@""];
+            tableMetadata *metadataMOVForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:[[NSUUID UUID] UUIDString] serverUrl:serverUrl urlBase:appDelegate.activeUrl url:@"" contentType:@""];
             
             metadataMOVForUpload.session = session;
             metadataMOVForUpload.sessionSelector = selectorUploadFile;
@@ -1117,7 +1109,7 @@
     [refreshControl endRefreshing];
     [self tableViewReloadData];
     
-    [[NCNetworking shared] readFolderWithServerUrl:serverUrl account:appDelegate.activeAccount completion:^(NSString *account, tableMetadata *metadataFolder, NSArray *metadatas, NSInteger errorCode, NSString *errorDescription) {
+    [[NCNetworking shared] readFolderWithServerUrl:serverUrl account:appDelegate.activeAccount completion:^(NSString *account, tableMetadata *metadataFolder, NSArray *metadatas, NSArray *metadatasChanged, NSInteger errorCode, NSString *errorDescription) {
         
         if (errorCode == 0 ) {
             
@@ -1125,9 +1117,13 @@
             BOOL isFolderEncrypted = [CCUtility isFolderEncrypted:serverUrl e2eEncrypted:_metadataFolder.e2eEncrypted account:appDelegate.activeAccount];
             [self setTitle];
             
-            // File is changed ??
             dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
-                [[CCSynchronize sharedSynchronize] verifyChangeMedatas:metadatas serverUrl:serverUrl account:account withDownload:NO];
+                for (tableMetadata *metadata in metadatasChanged) {
+                    tableLocalFile *localFile = [[NCManageDatabase sharedInstance] getTableLocalFileWithPredicate:[NSPredicate predicateWithFormat:@"ocId == %@", metadata.ocId]];
+                    if (localFile != nil) {
+                        [[NCNetworking shared] downloadWithMetadata:metadata selector:selectorDownloadSynchronize setFavorite:false completion:^(NSInteger errorCode) { }];
+                    }
+                }
             });
             
             // E2EE Is encrypted folder get metadata
@@ -1141,26 +1137,29 @@
                             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:-999];
+                                [[NCContentPresenter shared] messageNotification:@"_error_e2ee_" description:@"_e2e_error_decode_metadata_" delay:k_dismissAfterSecond type:messageTypeError errorCode:k_CCErrorDecodeMetadata 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];
                     }];
                     
                 } 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_CCErrorE2EENotEnabled 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;
+        [self reloadDatasource:serverUrl ocId:nil];
     }];
 }
 
@@ -1186,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];
         }
     }];
 }
@@ -1208,8 +1207,8 @@
              
              [[NCManageDatabase sharedInstance] convertNCCommunicationFilesToMetadatas:files useMetadataFolder:false account:account completion:^(tableMetadata *metadataFolder, NSArray<tableMetadata *> *metadatasFolder, NSArray<tableMetadata *> *metadatas) {
                  
-                 NSMutableArray *metadatasDB = (NSMutableArray *)[[NCManageDatabase sharedInstance] addMetadatas:metadatas];
-                 _searchResultMetadatas = [[NSMutableArray alloc] initWithArray:metadatasDB];
+                 [[NCManageDatabase sharedInstance] addMetadatas:metadatas];
+                 _searchResultMetadatas = [[NSMutableArray alloc] initWithArray:metadatas];
                  _metadataFolder = nil;
                  
                  [self reloadDatasource:_serverUrl ocId:nil];
@@ -1220,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];
          }
         
     }];
@@ -1251,7 +1251,7 @@
             
             // First : filter
                 
-            NSArray *records = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND fileNameView CONTAINS[cd] %@", appDelegate.activeAccount, _serverUrl, fileName] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO];
+            NSArray *records = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND fileNameView CONTAINS[cd] %@", appDelegate.activeAccount, _serverUrl, fileName] page:0 limit:0 sorted:@"fileName" ascending:NO];
                 
             [_searchResultMetadatas removeAllObjects];
             for (tableMetadata *record in records) {
@@ -1374,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:@"_e2e_error_not_move_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorE2EENotMove forced:true];
             return;
         }
         
@@ -1479,10 +1479,7 @@
         tableMetadata *metadataSection = [[NCMainCommon sharedInstance] getMetadataFromSectionDataSourceIndexPath:indexPath sectionDataSource:sectionDataSource];
         
         if (metadataSection) {
-            
-            tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"ocId == %@", metadataSection.ocId]];
-            if (metadata)
-                [[NCMainCommon sharedInstance] cancelTransferMetadata:metadata reloadDatasource:true uploadStatusForcedStart:false];
+            [[NCMainCommon sharedInstance] cancelTransferMetadata:metadataSection reloadDatasource:true uploadStatusForcedStart:false];
         }
     }
 }
@@ -1830,7 +1827,7 @@
                 [CCUtility copyFileAtPath:[CCUtility getDirectoryProviderStorageOcId:metadata.ocId fileNameView:metadata.fileNameView] toPath:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileName]];
                     
                 // Prepare record metadata
-                tableMetadata *metadataForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:ocId serverUrl:self.serverUrl url:@"" contentType:@""];
+                tableMetadata *metadataForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:ocId serverUrl:self.serverUrl urlBase:appDelegate.activeUrl url:@"" contentType:@""];
             
                 metadataForUpload.session = NCCommunicationCommon.shared.sessionIdentifierBackground;
                 metadataForUpload.sessionSelector = selectorUploadFile;
@@ -1853,7 +1850,7 @@
 
 - (BOOL)canOpenMenuAction:(tableMetadata *)metadata
 {
-    if (metadata == nil || _metadataFolder == nil || [[NCManageDatabase sharedInstance] isTableInvalidated:metadata] || metadata.status != k_metadataStatusNormal || [[NCManageDatabase sharedInstance] isTableInvalidated:_metadataFolder])
+    if (metadata == nil)
         return NO;
     
     // E2EE
@@ -2011,7 +2008,7 @@
     
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                 
-        NSArray *recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", appDelegate.activeAccount, serverUrl] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO];
+        NSArray *recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", appDelegate.activeAccount, serverUrl] page:0 limit:0 sorted:@"fileName" ascending:NO];
         
         // [CCUtility getGroupBySettings]
         CCSectionDataSourceMetadata *sectionDataSourceTemp = [CCSectionMetadata creataDataSourseSectionMetadata:recordsTableMetadata listProgressMetadata:nil groupByField:nil filterTypeFileImage:NO filterTypeFileVideo:NO filterLivePhoto:YES sorted:[CCUtility getOrderSettings] ascending:[CCUtility getAscendingSettings] activeAccount:appDelegate.activeAccount];
@@ -2461,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_CCErrorE2EENotEnabled forced:true];
                 
             } else {
             
@@ -2474,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_CCErrorOffline forced:true];
                     }
                     
                 } else if ([self.metadata.typeFile isEqualToString: k_metadataTypeFile_document] && [[NCUtility sharedInstance] isRichDocument:self.metadata]) {
@@ -2482,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_CCErrorOffline forced:true];
                     }
                     
                 } else {
@@ -2610,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_CCErrorE2EENotEnabled forced:true];
             return;
         }
         

部分文件因文件數量過多而無法顯示