Browse Source

Merge branch 'develop'

Marino Faggiana 7 years ago
parent
commit
53228abc01
74 changed files with 1296 additions and 741 deletions
  1. 59 0
      Libraries external/Realm/Realm.framework/CHANGELOG.md
  2. 44 24
      Libraries external/Realm/Realm.framework/Headers/RLMObject.h
  3. 17 0
      Libraries external/Realm/Realm.framework/Headers/RLMSyncUser.h
  4. BIN
      Libraries external/Realm/Realm.framework/Info.plist
  5. 8 4
      Libraries external/Realm/Realm.framework/LICENSE
  6. 2 9
      Libraries external/Realm/Realm.framework/PrivateHeaders/RLMAccessor.h
  7. 2 18
      Libraries external/Realm/Realm.framework/PrivateHeaders/RLMObjectStore.h
  8. 1 1
      Libraries external/Realm/Realm.framework/PrivateHeaders/RLMRealm_Private.h
  9. BIN
      Libraries external/Realm/Realm.framework/Realm
  10. 4 4
      Libraries external/Realm/RealmSwift.framework/Headers/RealmSwift-Swift.h
  11. BIN
      Libraries external/Realm/RealmSwift.framework/Info.plist
  12. BIN
      Libraries external/Realm/RealmSwift.framework/Modules/RealmSwift.swiftmodule/arm.swiftdoc
  13. BIN
      Libraries external/Realm/RealmSwift.framework/Modules/RealmSwift.swiftmodule/arm.swiftmodule
  14. BIN
      Libraries external/Realm/RealmSwift.framework/Modules/RealmSwift.swiftmodule/arm64.swiftdoc
  15. BIN
      Libraries external/Realm/RealmSwift.framework/Modules/RealmSwift.swiftmodule/arm64.swiftmodule
  16. BIN
      Libraries external/Realm/RealmSwift.framework/Modules/RealmSwift.swiftmodule/i386.swiftdoc
  17. BIN
      Libraries external/Realm/RealmSwift.framework/Modules/RealmSwift.swiftmodule/i386.swiftmodule
  18. BIN
      Libraries external/Realm/RealmSwift.framework/Modules/RealmSwift.swiftmodule/x86_64.swiftdoc
  19. BIN
      Libraries external/Realm/RealmSwift.framework/Modules/RealmSwift.swiftmodule/x86_64.swiftmodule
  20. BIN
      Libraries external/Realm/RealmSwift.framework/RealmSwift
  21. 4 0
      Nextcloud.xcodeproj/project.pbxproj
  22. 5 1
      Picker/DocumentPickerViewController.swift
  23. 11 2
      Share/CCloadItemData.swift
  24. 6 11
      Share/ShareViewController.m
  25. 26 12
      iOSClient/Actions/CCActions.swift
  26. 1 1
      iOSClient/Activity/CCActivity.m
  27. 0 1
      iOSClient/AppDelegate.h
  28. 13 26
      iOSClient/AppDelegate.m
  29. 28 32
      iOSClient/AutoUpload/NCAutoUpload.m
  30. 1 0
      iOSClient/Brand/NCBrand.swift
  31. 2 2
      iOSClient/Brand/Picker.plist
  32. 2 2
      iOSClient/Brand/PickerFileProvider.plist
  33. 2 2
      iOSClient/Brand/Share.plist
  34. 2 2
      iOSClient/Brand/iOSClient.plist
  35. 14 14
      iOSClient/CCGlobal.h
  36. 27 12
      iOSClient/Create/CCCreateCloud.swift
  37. 14 14
      iOSClient/Database/NCDatabase.swift
  38. 112 25
      iOSClient/Database/NCManageDatabase.swift
  39. 45 32
      iOSClient/Favorites/CCFavorites.m
  40. 2 1
      iOSClient/Main/CCDetail.m
  41. 212 180
      iOSClient/Main/CCMain.m
  42. 21 33
      iOSClient/Main/CCMore.swift
  43. 9 1
      iOSClient/Move/CCMove.m
  44. 2 1
      iOSClient/Networking/CCNetworking.h
  45. 164 137
      iOSClient/Networking/CCNetworking.m
  46. 41 11
      iOSClient/Networking/OCNetworking.m
  47. 5 9
      iOSClient/Notification/CCNotification.swift
  48. 2 1
      iOSClient/PeekPop/CCPeekPop.m
  49. 43 35
      iOSClient/Photos/CCPhotos.m
  50. 18 34
      iOSClient/Settings/CCManageAutoUpload.m
  51. 3 1
      iOSClient/Settings/CCSettings.m
  52. 202 0
      iOSClient/Settings/NCManageAutoUploadFileName.swift
  53. 16 9
      iOSClient/Shares/NCShares.m
  54. BIN
      iOSClient/Supporting Files/cs-CZ.lproj/Localizable.strings
  55. BIN
      iOSClient/Supporting Files/de.lproj/Localizable.strings
  56. BIN
      iOSClient/Supporting Files/el.lproj/Localizable.strings
  57. BIN
      iOSClient/Supporting Files/en-GB.lproj/Localizable.strings
  58. 11 1
      iOSClient/Supporting Files/en.lproj/Localizable.strings
  59. BIN
      iOSClient/Supporting Files/es-AR.lproj/Localizable.strings
  60. BIN
      iOSClient/Supporting Files/es-MX.lproj/Localizable.strings
  61. BIN
      iOSClient/Supporting Files/es.lproj/Localizable.strings
  62. BIN
      iOSClient/Supporting Files/fr.lproj/Localizable.strings
  63. BIN
      iOSClient/Supporting Files/is.lproj/Localizable.strings
  64. BIN
      iOSClient/Supporting Files/it.lproj/Localizable.strings
  65. BIN
      iOSClient/Supporting Files/nb-NO.lproj/Localizable.strings
  66. BIN
      iOSClient/Supporting Files/nl.lproj/Localizable.strings
  67. BIN
      iOSClient/Supporting Files/pl.lproj/Localizable.strings
  68. BIN
      iOSClient/Supporting Files/pt-BR.lproj/Localizable.strings
  69. BIN
      iOSClient/Supporting Files/ru.lproj/Localizable.strings
  70. BIN
      iOSClient/Supporting Files/tr.lproj/Localizable.strings
  71. BIN
      iOSClient/Supporting Files/zh-Hans.lproj/Localizable.strings
  72. 16 9
      iOSClient/Synchronize/CCSynchronize.m
  73. 3 1
      iOSClient/Utility/CCUtility.h
  74. 74 26
      iOSClient/Utility/CCUtility.m

+ 59 - 0
Libraries external/Realm/Realm.framework/CHANGELOG.md

@@ -1,3 +1,62 @@
+2.8.3 Release notes (2017-06-20)
+=============================================================
+
+### Bugfixes
+
+* Properly update RealmOptional properties when adding an object with `add(update: true)`.
+* Add some missing quotes in error messages.
+* Fix a performance regression when creating objects with primary keys.
+
+2.8.2 Release notes (2017-06-16)
+=============================================================
+
+### Bugfixes
+
+* Fix an issue where synchronized Realms would eventually disconnect from the
+  remote server if the user object used to define their sync configuration
+  was destroyed.
+* Restore support for changing primary keys in migrations (broken in 2.8.0).
+* Revert handling of adding objects with nil properties to a Realm to the
+  pre-2.8.0 behavior.
+
+2.8.1 Release notes (2017-06-12)
+=============================================================
+
+Add support for building with Xcode 9 Beta 1.
+
+### Bugfixes
+
+* Fix setting a float property to NaN.
+* Fix a crash when using compact on launch in combination with collection
+  notifications.
+
+2.8.0 Release notes (2017-06-02)
+=============================================================
+
+### API Breaking Changes
+
+* None.
+
+### Enhancements
+
+* Enable encryption on watchOS.
+* Add `-[RLMSyncUser changePassword:forUserID:completion:]` API to change an
+  arbitrary user's password if the current user has administrative privileges
+  and using Realm's 'password' authentication provider.
+  Requires any edition of the Realm Object Server 1.6.0 or later.
+
+### Bugfixes
+
+* Suppress `-Wdocumentation` warnings in Realm C++ headers when using CocoaPods
+  with Xcode 8.3.2.
+* Throw an appropriate error rather than crashing when an RLMArray is assigned
+  to an RLMArray property of a different type.
+* Fix crash in large (>4GB) encrypted Realm files.
+* Improve accuracy of sync progress notifications.
+* Fix an issue where synchronized Realms did not connect to the remote server
+  in certain situations, such as when an application was offline when the Realms
+  were opened but later regained network connectivity.
+
 2.7.0 Release notes (2017-05-03)
 =============================================================
 

+ 44 - 24
Libraries external/Realm/Realm.framework/Headers/RLMObject.h

@@ -137,11 +137,13 @@ NS_ASSUME_NONNULL_BEGIN
  on them.
 
  The `value` argument can be a key-value coding compliant object, an array or dictionary returned from the methods in
- `NSJSONSerialization`, or an array containing one element for each managed property. An exception will be thrown if
- any required properties are not present and those properties were not defined with default values.
+ `NSJSONSerialization`, or an array containing one element for each managed property.
+ 
+ An exception will be thrown if any required properties are not present and those properties
+ were not defined with default values.
 
- When passing in an array as the `value` argument, all properties must be present, valid and in the same order as the
- properties defined in the model.
+ If the `value` argument is an array, all properties must be present, valid and in the same
+ order as the properties defined in the model.
 
  @param value    The value used to populate the object.
 
@@ -156,11 +158,13 @@ NS_ASSUME_NONNULL_BEGIN
  on them.
 
  The `value` argument can be a key-value coding compliant object, an array or dictionary returned from the methods in
- `NSJSONSerialization`, or an array containing one element for each managed property. An exception will be thrown if any
- required properties are not present and those properties were not defined with default values.
+ `NSJSONSerialization`, or an array containing one element for each managed property.
+ 
+ An exception will be thrown if any required properties are not present and those properties
+ were not defined with default values.
 
- When passing in an array as the `value` argument, all properties must be present, valid and in the same order as the
- properties defined in the model.
+ If the `value` argument is an array, all properties must be present, valid and in the same
+ order as the properties defined in the model.
 
  @param realm    The Realm which should manage the newly-created object.
  @param value    The value used to populate the object.
@@ -179,16 +183,24 @@ NS_ASSUME_NONNULL_BEGIN
  If nested objects are included in the argument, `createOrUpdateInDefaultRealmWithValue:` will be
  recursively called on them if they have primary keys, `createInDefaultRealmWithValue:` if they do not.
 
- If the argument is a Realm object already managed by the default Realm, the argument's type is the same
- as the receiver, and the objects have identical values for their managed properties, this method does nothing.
+ The `value` argument is used to populate the object. It can be a Realm object, a key-value coding
+ compliant object, an array or dictionary returned from the methods in `NSJSONSerialization`, or an
+ array containing one element for each managed property.
 
- The `value` argument is used to populate the object. It can be a key-value coding compliant object, an array or
- dictionary returned from the methods in `NSJSONSerialization`, or an array containing one element for each managed
- property. An exception will be thrown if any required properties are not present and those properties were not defined
- with default values.
+ If the object is being created, an exception will be thrown if any required properties
+ are not present and those properties were not defined with default values.
+ 
+ If the `value` argument is a Realm object already managed by the default Realm, the
+ argument's type is the same as the receiver, and the objects have identical values for
+ their managed properties, this method does nothing.
 
- When passing in an array as the `value` argument, all properties must be present, valid and in the same order as the
- properties defined in the model.
+ If the object is being updated, all properties defined in its schema will be set by copying from
+ `value` using key-value coding. If the `value` argument does not respond to `valueForKey:` for a
+ given property name (or getter name, if defined), that value will remain untouched.
+ Nullable properties on the object can be set to nil by using `NSNull` as the updated value.
+
+ If the `value` argument is an array, all properties must be present, valid and in the same
+ order as the properties defined in the model.
 
  @param value    The value used to populate the object.
 
@@ -206,16 +218,24 @@ NS_ASSUME_NONNULL_BEGIN
  If nested objects are included in the argument, `createOrUpdateInRealm:withValue:` will be
  recursively called on them if they have primary keys, `createInRealm:withValue:` if they do not.
 
- If the argument is a Realm object already managed by the given Realm, the argument's type is the same
- as the receiver, and the objects have identical values for their managed properties, this method does nothing.
+ The `value` argument is used to populate the object. It can be a Realm object, a key-value coding
+ compliant object, an array or dictionary returned from the methods in `NSJSONSerialization`, or an
+ array containing one element for each managed property.
+
+ If the object is being created, an exception will be thrown if any required properties
+ are not present and those properties were not defined with default values.
+
+ If the `value` argument is a Realm object already managed by the given Realm, the
+ argument's type is the same as the receiver, and the objects have identical values for
+ their managed properties, this method does nothing.
 
- The `value` argument is used to populate the object. It can be a key-value coding compliant object, an array or
- dictionary returned from the methods in `NSJSONSerialization`, or an array containing one element for each managed
- property. An exception will be thrown if any required properties are not present and those properties were not defined
- with default values.
+ If the object is being updated, all properties defined in its schema will be set by copying from
+ `value` using key-value coding. If the `value` argument does not respond to `valueForKey:` for a
+ given property name (or getter name, if defined), that value will remain untouched.
+ Nullable properties on the object can be set to nil by using `NSNull` as the updated value.
 
- When passing in an array as the `value` argument, all properties must be present, valid and in the same order as the
- properties defined in the model.
+ If the `value` argument is an array, all properties must be present, valid and in the same
+ order as the properties defined in the model.
 
  @param realm    The Realm which should own the object.
  @param value    The value used to populate the object.

+ 17 - 0
Libraries external/Realm/Realm.framework/Headers/RLMSyncUser.h

@@ -156,6 +156,23 @@ NS_SWIFT_UNAVAILABLE("Use the full version of this API.");
  */
 - (void)changePassword:(NSString *)newPassword completion:(RLMPasswordChangeStatusBlock)completion;
 
+/**
+ Change an arbitrary user's password asynchronously.
+
+ @note    The current user must be an admin user for this operation to succeed.
+
+ @warning Changing a user's password using an authentication server that doesn't
+          use HTTPS is a major security flaw, and should only be done while
+          testing.
+
+ @param newPassword The user's new password.
+ @param userID      The identity of the user whose password should be changed.
+ @param completion  Completion block invoked when login has completed or failed.
+                    The callback will be invoked on a background queue provided
+                    by `NSURLSession`.
+ */
+- (void)changePassword:(NSString *)newPassword forUserID:(NSString *)userID completion:(RLMPasswordChangeStatusBlock)completion;
+
 // This set of permissions APIs uses immutable `RLMSyncPermissionValue` objects to
 // retrieve and apply permissions. It is intended to replace the set of APIs which
 // directly access Realms and Realm model objects to work with permissions.

BIN
Libraries external/Realm/Realm.framework/Info.plist


+ 8 - 4
Libraries external/Realm/Realm.framework/LICENSE

@@ -4,7 +4,7 @@ TABLE OF CONTENTS
 2. Realm Components
 3. Export Compliance
 
--------------------------------------------------------------------------------
+1. -------------------------------------------------------------------------------
 
                                  Apache License
                            Version 2.0, January 2004
@@ -181,17 +181,19 @@ TABLE OF CONTENTS
       incurred by, or claims asserted against, such Contributor by reason
       of your accepting any such warranty or additional liability.
 
+2. -------------------------------------------------------------------------------
+
 REALM COMPONENTS
 
 This software contains components with separate copyright and license terms.
 Your use of these components is subject to the terms and conditions of the
 following licenses.
 
-For the Realm Core component
+For the Realm Platform Extensions component
 
-  Realm Core Binary License
+  Realm Platform Extensions License
 
-  Copyright (c) 2011-2016 Realm Inc All rights reserved
+  Copyright (c) 2011-2017 Realm Inc All rights reserved
 
   Redistribution and use in binary form, with or without modification, is
   permitted provided that the following conditions are met:
@@ -222,6 +224,8 @@ For the Realm Core component
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE.
 
+3. -------------------------------------------------------------------------------
+
 EXPORT COMPLIANCE
 
 You understand that the Software may contain cryptographic functions that may be

+ 2 - 9
Libraries external/Realm/Realm.framework/PrivateHeaders/RLMAccessor.h

@@ -18,14 +18,7 @@
 
 #import <Foundation/Foundation.h>
 
-
-@class RLMObjectSchema, RLMProperty, RLMObjectBase, RLMProperty;
-
-#ifdef __cplusplus
-typedef NSUInteger RLMCreationOptions;
-#else
-typedef NS_OPTIONS(NSUInteger, RLMCreationOptions);
-#endif
+@class RLMObjectSchema, RLMProperty, RLMObjectBase;
 
 NS_ASSUME_NONNULL_BEGIN
 
@@ -45,7 +38,7 @@ FOUNDATION_EXTERN id __nullable RLMDynamicGet(RLMObjectBase *obj, RLMProperty *p
 FOUNDATION_EXTERN id __nullable RLMDynamicGetByName(RLMObjectBase *obj, NSString *propName, bool asList);
 
 // by property/column
-void RLMDynamicSet(RLMObjectBase *obj, RLMProperty *prop, id val, RLMCreationOptions options);
+void RLMDynamicSet(RLMObjectBase *obj, RLMProperty *prop, id val);
 
 //
 // Class modification

+ 2 - 18
Libraries external/Realm/Realm.framework/PrivateHeaders/RLMObjectStore.h

@@ -34,23 +34,6 @@ NS_ASSUME_NONNULL_BEGIN
 void RLMRealmCreateAccessors(RLMSchema *schema);
 
 
-//
-// Options for object creation
-//
-typedef NS_OPTIONS(NSUInteger, RLMCreationOptions) {
-    // Normal object creation
-    RLMCreationOptionsNone = 0,
-    // If the property is a link or array property, upsert the linked objects
-    // if they have a primary key, and insert them otherwise.
-    RLMCreationOptionsCreateOrUpdate = 1 << 0,
-    // Allow unmanaged objects to be promoted to managed objects
-    // if false objects are copied during object creation
-    RLMCreationOptionsPromoteUnmanaged = 1 << 1,
-    // Use the SetDefault instruction.
-    RLMCreationOptionsSetDefault = 1 << 2,
-};
-
-
 //
 // Adding, Removing, Getting Objects
 //
@@ -72,7 +55,8 @@ NS_RETURNS_RETAINED;
 id _Nullable RLMGetObject(RLMRealm *realm, NSString *objectClassName, id _Nullable key) NS_RETURNS_RETAINED;
 
 // create object from array or dictionary
-RLMObjectBase *RLMCreateObjectInRealmWithValue(RLMRealm *realm, NSString *className, id _Nullable value, bool createOrUpdate)
+RLMObjectBase *RLMCreateObjectInRealmWithValue(RLMRealm *realm, NSString *className,
+                                               id _Nullable value, bool createOrUpdate)
 NS_RETURNS_RETAINED;
     
 

+ 1 - 1
Libraries external/Realm/Realm.framework/PrivateHeaders/RLMRealm_Private.h

@@ -23,7 +23,7 @@
 NS_ASSUME_NONNULL_BEGIN
 
 // Disable syncing files to disk. Cannot be re-enabled. Use only for tests.
-FOUNDATION_EXTERN void RLMDisableSyncToDisk();
+FOUNDATION_EXTERN void RLMDisableSyncToDisk(void);
 
 FOUNDATION_EXTERN NSData * _Nullable RLMRealmValidatedEncryptionKey(NSData *key);
 

BIN
Libraries external/Realm/Realm.framework/Realm


+ 4 - 4
Libraries external/Realm/RealmSwift.framework/Headers/RealmSwift-Swift.h

@@ -149,8 +149,8 @@ typedef unsigned int swift_uint4  __attribute__((__ext_vector_type__(4)));
 /// You then instantiate and use your custom subclasses instead of using the <code>Object</code> class directly.
 /// \code
 /// class Dog: Object {
-///     dynamic var name: String = ""
-///     dynamic var adopted: Bool = false
+///     @objc dynamic var name: String = ""
+///     @objc dynamic var adopted: Bool = false
 ///     let siblings = List<Dog>()
 /// }
 ///
@@ -194,7 +194,7 @@ typedef unsigned int swift_uint4  __attribute__((__ext_vector_type__(4)));
 /// <code>Int</code>, <code>Int8</code>, <code>Int16</code>, <code>Int32</code>, <code>Int64</code>, <code>Float</code>, <code>Double</code>, <code>Bool</code>, and <code>List</code> properties cannot. To store an optional
 /// number, use <code>RealmOptional<Int></code>, <code>RealmOptional<Float></code>, <code>RealmOptional<Double></code>, or <code>RealmOptional<Bool></code> instead,
 /// which wraps an optional numeric value.
-/// All property types except for <code>List</code> and <code>RealmOptional</code> <em>must</em> be declared as <code>dynamic var</code>. <code>List</code> and
+/// All property types except for <code>List</code> and <code>RealmOptional</code> <em>must</em> be declared as <code>@objc dynamic var</code>. <code>List</code> and
 /// <code>RealmOptional</code> properties must be declared as non-dynamic <code>let</code> properties. Swift <code>lazy</code> properties are not allowed.
 /// Note that none of the restrictions listed above apply to properties that are configured to be ignored by Realm.
 /// <h3>Querying</h3>
@@ -297,7 +297,7 @@ SWIFT_CLASS("_TtC10RealmSwift18LinkingObjectsBase")
 @property (nonatomic, readonly, copy) NSString * _Nonnull propertyName;
 @property (nonatomic, readonly, strong) RLMResults<RLMObject *> * _Nonnull rlmResults;
 - (nonnull instancetype)initFromClassName:(NSString * _Nonnull)objectClassName property:(NSString * _Nonnull)propertyName OBJC_DESIGNATED_INITIALIZER;
-- (NSInteger)countByEnumeratingWithState:(NSFastEnumerationState * _Nonnull)state objects:(id _Nullable * _Null_unspecified)buffer count:(NSInteger)len SWIFT_WARN_UNUSED_RESULT;
+- (NSInteger)countByEnumeratingWithState:(NSFastEnumerationState * _Nonnull)state objects:(id _Nullable * _Nonnull)buffer count:(NSInteger)len SWIFT_WARN_UNUSED_RESULT;
 - (nonnull instancetype)init SWIFT_UNAVAILABLE;
 @end
 

BIN
Libraries external/Realm/RealmSwift.framework/Info.plist


BIN
Libraries external/Realm/RealmSwift.framework/Modules/RealmSwift.swiftmodule/arm.swiftdoc


BIN
Libraries external/Realm/RealmSwift.framework/Modules/RealmSwift.swiftmodule/arm.swiftmodule


BIN
Libraries external/Realm/RealmSwift.framework/Modules/RealmSwift.swiftmodule/arm64.swiftdoc


BIN
Libraries external/Realm/RealmSwift.framework/Modules/RealmSwift.swiftmodule/arm64.swiftmodule


BIN
Libraries external/Realm/RealmSwift.framework/Modules/RealmSwift.swiftmodule/i386.swiftdoc


BIN
Libraries external/Realm/RealmSwift.framework/Modules/RealmSwift.swiftmodule/i386.swiftmodule


BIN
Libraries external/Realm/RealmSwift.framework/Modules/RealmSwift.swiftmodule/x86_64.swiftdoc


BIN
Libraries external/Realm/RealmSwift.framework/Modules/RealmSwift.swiftmodule/x86_64.swiftmodule


BIN
Libraries external/Realm/RealmSwift.framework/RealmSwift


+ 4 - 0
Nextcloud.xcodeproj/project.pbxproj

@@ -220,6 +220,7 @@
 		F750374F1DBFA91A008FB480 /* NSArray+PureLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = F75037461DBFA91A008FB480 /* NSArray+PureLayout.m */; };
 		F75037511DBFA91A008FB480 /* NSLayoutConstraint+PureLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = F75037481DBFA91A008FB480 /* NSLayoutConstraint+PureLayout.m */; };
 		F75797AE1E81356C00187A1B /* CTAssetsPicker.strings in Resources */ = {isa = PBXBuildFile; fileRef = F75797AC1E81356C00187A1B /* CTAssetsPicker.strings */; };
+		F75AC2431F1F62450073EC19 /* NCManageAutoUploadFileName.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75AC2421F1F62450073EC19 /* NCManageAutoUploadFileName.swift */; };
 		F75ADF451DC75FFE008A7347 /* CCLogin.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F75ADF441DC75FFE008A7347 /* CCLogin.storyboard */; };
 		F75AE3C71E9D12900088BB09 /* SwiftyAvatar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F75AE3C61E9D12900088BB09 /* SwiftyAvatar.swift */; };
 		F75EDFAC1E8C106900E6F369 /* FirebaseAnalytics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F75EDFA61E8C106900E6F369 /* FirebaseAnalytics.framework */; };
@@ -1116,6 +1117,7 @@
 		F7540F2B1D5B238600C3FFA8 /* x509_vfy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = x509_vfy.h; sourceTree = "<group>"; };
 		F7540F2C1D5B238600C3FFA8 /* x509v3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = x509v3.h; sourceTree = "<group>"; };
 		F75797AD1E81356C00187A1B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/CTAssetsPicker.strings; sourceTree = "<group>"; };
+		F75AC2421F1F62450073EC19 /* NCManageAutoUploadFileName.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCManageAutoUploadFileName.swift; sourceTree = "<group>"; };
 		F75ADF441DC75FFE008A7347 /* CCLogin.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = CCLogin.storyboard; sourceTree = "<group>"; };
 		F75AE3C61E9D12900088BB09 /* SwiftyAvatar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftyAvatar.swift; sourceTree = "<group>"; };
 		F75B91DF1ECAE17800199C96 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/CTAssetsPicker.strings; sourceTree = "<group>"; };
@@ -2903,6 +2905,7 @@
 				F7ACE42A1BAC0268006C0017 /* Acknowledgements.m */,
 				F7ACE42B1BAC0268006C0017 /* Acknowledgements.rtf */,
 				F7A321AB1E9E6AD50069AD1B /* CCAdvanced.h */,
+				F75AC2421F1F62450073EC19 /* NCManageAutoUploadFileName.swift */,
 				F7A321AC1E9E6AD50069AD1B /* CCAdvanced.m */,
 				F7ACE42C1BAC0268006C0017 /* CCManageAccount.h */,
 				F7ACE42D1BAC0268006C0017 /* CCManageAccount.m */,
@@ -4620,6 +4623,7 @@
 				F762CB091EACB66200B38484 /* XLFormViewController.m in Sources */,
 				F762CB161EACB66200B38484 /* XLFormTextView.m in Sources */,
 				F7D424681F063B82009C9782 /* CTAssetsGridViewFooter.m in Sources */,
+				F75AC2431F1F62450073EC19 /* NCManageAutoUploadFileName.swift in Sources */,
 				F7D424701F063B82009C9782 /* CTAssetsPickerNoAssetsView.m in Sources */,
 				F7D424591F063B82009C9782 /* PHImageManager+CTAssetsPickerController.m in Sources */,
 				F7ECBA6D1E239DCD003E6328 /* CCCreateCloud.swift in Sources */,

+ 5 - 1
Picker/DocumentPickerViewController.swift

@@ -325,7 +325,7 @@ class DocumentPickerViewController: UIDocumentPickerExtensionViewController, CCN
             // Add record
             let fileID = metadata.fileID
             let fileName = metadata.fileName
-            _ = NCManageDatabase.sharedInstance.addMetadata(metadata, activeUrl: activeUrl!, serverUrl: metadataNet.serverUrl)
+            _ = NCManageDatabase.sharedInstance.addMetadata(metadata)
             
             // if plist do not exists, download it
             if CCUtility.isCryptoPlistString(fileName) && FileManager.default.fileExists(atPath: "\(directoryUser!)/\(fileName)") == false {
@@ -462,7 +462,11 @@ class DocumentPickerViewController: UIDocumentPickerExtensionViewController, CCN
             
         case selectorLoadPlist :
             
+            let autoUploadFileName = NCManageDatabase.sharedInstance.getAccountAutoUploadFileName()
+            let autoUploadDirectory = NCManageDatabase.sharedInstance.getAccountAutoUploadDirectory(activeUrl!)
+            
             var metadata : tableMetadata? = CCUtility.insertInformationPlist(self.metadata, directoryUser: directoryUser)!
+            metadata = CCUtility.insertTypeFileIconName(metadata, serverUrl: serverUrl, autoUploadFileName: autoUploadFileName, autoUploadDirectory: autoUploadDirectory)
             metadata = NCManageDatabase.sharedInstance.updateMetadata(metadata!, activeUrl: activeUrl!)
             
             if metadata != nil {

+ 11 - 2
Share/CCloadItemData.swift

@@ -87,10 +87,19 @@ class CCloadItemData: NSObject {
                                         
                                         print("item as url: \(String(describing: item))")
                                         
-                                        let pathExtention = URL(fileURLWithPath: url.lastPathComponent).pathExtension
-                                        let fileName = "\(dateFormatter.string(from: Date()))\(conuter).\(pathExtention)"
+                                        let fileName = url.lastPathComponent
+                                        // OLD fileName with date
+                                        //let pathExtention = URL(fileURLWithPath: url.lastPathComponent).pathExtension
+                                        //let fileName = "\(dateFormatter.string(from: Date()))\(conuter).\(pathExtention)"
                                         let filenamePath = directoryUser + "/" + fileName
                                         
+                                        do {
+                                            try FileManager.default.removeItem(atPath: filenamePath)
+                                        }
+                                        catch let error as NSError {
+                                            print("Ooops! Something went wrong: \(error)")
+                                        }
+                                        
                                         do {
                                             try FileManager.default.copyItem(atPath: url.path, toPath:filenamePath)
                                             

+ 6 - 11
Share/ShareViewController.m

@@ -165,9 +165,11 @@
 
     // Theming
     tableCapabilities *capabilities = [[NCManageDatabase sharedInstance] getCapabilites];
-    if ([NCBrandOptions sharedInstance].use_themingColor && capabilities.themingColor.length > 0)
-        [NCBrandColor sharedInstance].brand = [CCGraphics colorFromHexString:capabilities.themingColor];
-
+    if ([NCBrandOptions sharedInstance].use_themingColor && capabilities.themingColor.length > 0) {
+        UIColor *newColor = [CCGraphics colorFromHexString:capabilities.themingColor];
+        if (newColor)
+            [NCBrandColor sharedInstance].brand = newColor;
+    }
     self.navigationController.navigationBar.barTintColor = [NCBrandColor sharedInstance].brand;
     self.navigationController.navigationBar.tintColor = [NCBrandColor sharedInstance].navigationBarText;
     
@@ -256,9 +258,7 @@
         
         [self addNetworkingQueue:metadataNet];
         
-        [self.hud visibleHudTitle:NSLocalizedString(@"_uploading_", nil) mode:MBProgressHUDModeDeterminateHorizontalBar color:self.view.tintColor];
-       
-        [self.hud AddButtonCancelWithTarget:self selector:@"cancelTransfer"];
+        [self.hud visibleHudTitle:NSLocalizedString(@"_uploading_", nil) mode:MBProgressHUDModeDeterminate color:[NCBrandColor sharedInstance].brand];
     }
     else
         [self closeShareViewController];
@@ -286,11 +286,6 @@
     [self navigationBarToolBar];
 }
 
-- (void)cancelTransfer
-{
-    [_networkingOperationQueue cancelAllOperations];
-}
-
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark ======================= NetWorking ==================================
 #pragma --------------------------------------------------------------------------------------------

+ 26 - 12
iOSClient/Actions/CCActions.swift

@@ -85,7 +85,10 @@ class CCActions: NSObject {
 
     func deleteFileOrFolder(_ metadata: tableMetadata, delegate: AnyObject) {
         
-        let serverUrl = NCManageDatabase.sharedInstance.getServerUrl(metadata.directoryID)
+        guard let serverUrl = NCManageDatabase.sharedInstance.getServerUrl(metadata.directoryID) else {
+            return
+        }
+        
         let metadataNet: CCMetadataNet = CCMetadataNet.init(account: appDelegate.activeAccount)
 
         // fix CCActions.swift line 88 2.17.2 (00005)
@@ -138,8 +141,8 @@ class CCActions: NSObject {
         
         let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "fileID == %@", metadataNet.fileID))
         
-        if metadata != nil {
-            self.deleteFile(metadata: metadata!, serverUrl: metadataNet.serverUrl)
+        if let metadata = metadata {
+            self.deleteFile(metadata: metadata, serverUrl: metadataNet.serverUrl)
         }
         
         metadataNet.delegate?.deleteFileOrFolderSuccess(metadataNet)
@@ -174,7 +177,9 @@ class CCActions: NSObject {
         
         let fileName = CCUtility.removeForbiddenCharactersServer(fileName)!
         
-        let serverUrl = NCManageDatabase.sharedInstance.getServerUrl(metadata.directoryID)
+        guard let serverUrl = NCManageDatabase.sharedInstance.getServerUrl(metadata.directoryID) else {
+            return
+        }
         
         if fileName.characters.count == 0 {
             return
@@ -250,10 +255,9 @@ class CCActions: NSObject {
         } else {
  
             let ocNetworking = OCnetworking.init(delegate: nil, metadataNet: nil, withUser: appDelegate.activeUser, withPassword: appDelegate.activePassword, withUrl: appDelegate.activeUrl, isCryptoCloudMode: false);
-            let error = ocNetworking?.readFileSync("\(serverUrl)/\(fileName)");
-            
+
             // Verify if exists the fileName TO
-            if error == nil {
+            guard (ocNetworking?.readFileSync("\(String(describing: serverUrl))/\(fileName)")) != nil else {
                 
                 let alertController = UIAlertController(title: NSLocalizedString("_error_", comment: ""), message: NSLocalizedString("_file_already_exists_", comment: ""), preferredStyle: UIAlertControllerStyle.alert)
                 
@@ -267,7 +271,7 @@ class CCActions: NSObject {
                 
                 return;
             }
-            
+
             // Plain
             
             metadataNet.action = actionMoveFileOrFolder
@@ -341,14 +345,18 @@ class CCActions: NSObject {
     
     func search(_ serverUrl: String, fileName: String, depth: String, date: Date?, selector: String, delegate: AnyObject) {
         
+        guard let directoryID = NCManageDatabase.sharedInstance.getDirectoryID(serverUrl) else {
+            return
+        }
+        
         // Search DAV API
             
         let metadataNet: CCMetadataNet = CCMetadataNet.init(account: appDelegate.activeAccount)
-            
+        
         metadataNet.action = actionSearch
         metadataNet.date = date
         metadataNet.delegate = delegate
-        metadataNet.directoryID = NCManageDatabase.sharedInstance.getDirectoryID(serverUrl)
+        metadataNet.directoryID = directoryID
         metadataNet.fileName = fileName
         metadataNet.options = depth
         metadataNet.priority = Operation.QueuePriority.high.rawValue
@@ -375,7 +383,10 @@ class CCActions: NSObject {
     func downloadTumbnail(_ metadata: tableMetadata, delegate: AnyObject) {
         
         let metadataNet: CCMetadataNet = CCMetadataNet.init(account: appDelegate.activeAccount)
-        let serverUrl = NCManageDatabase.sharedInstance.getServerUrl(metadata.directoryID)
+        
+        guard let serverUrl = NCManageDatabase.sharedInstance.getServerUrl(metadata.directoryID) else {
+            return
+        }
         
         metadataNet.action = actionDownloadThumbnail
         metadataNet.delegate = delegate
@@ -408,8 +419,11 @@ class CCActions: NSObject {
     func settingFavorite(_ metadata: tableMetadata, favorite: Bool, delegate: AnyObject) {
         
         let metadataNet: CCMetadataNet = CCMetadataNet.init(account: appDelegate.activeAccount)
-        let serverUrl = NCManageDatabase.sharedInstance.getServerUrl(metadata.directoryID)
         
+        guard let serverUrl = NCManageDatabase.sharedInstance.getServerUrl(metadata.directoryID) else {
+            return
+        }
+                
         metadataNet.action = actionSettingFavorite
         metadataNet.delegate = delegate
         metadataNet.fileID = metadata.fileID

+ 1 - 1
iOSClient/Activity/CCActivity.m

@@ -272,7 +272,7 @@
 
         if ([activity.type isEqualToString:k_activityTypeInfo]) {
         
-            actionLabel.textColor = [NCBrandColor sharedInstance].brand;
+            actionLabel.textColor = [NCBrandColor sharedInstance].nextcloud;
         
             if (activity.idActivity == 0)
                 typeImage.image = [UIImage imageNamed:@"activityTypeInfo"];

+ 0 - 1
iOSClient/AppDelegate.h

@@ -46,7 +46,6 @@
 // Timer Process
 @property (nonatomic, strong) NSTimer *timerProcessAutoUpload;
 @property (nonatomic, strong) NSTimer *timerUpdateApplicationIconBadgeNumber;
-@property (nonatomic, strong) NSTimer *timerVerifySessionInProgress;
 
 // For LMMediaPlayerView
 @property (strong, nonatomic) UIWindow *window;

+ 13 - 26
iOSClient/AppDelegate.m

@@ -249,7 +249,7 @@
     
     // Start Timer
     self.timerProcessAutoUpload = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(processAutoUpload) userInfo:nil repeats:YES];
-    self.timerVerifySessionInProgress = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(verifyDownloadUploadInProgress) userInfo:nil repeats:YES];
+    
     self.timerUpdateApplicationIconBadgeNumber = [NSTimer scheduledTimerWithTimeInterval:k_timerUpdateApplicationIconBadgeNumber target:self selector:@selector(updateApplicationIconBadgeNumber) userInfo:nil repeats:YES];
 
     // Registration Push Notification
@@ -279,10 +279,6 @@
 //
 - (void)applicationWillEnterForeground:(UIApplication *)application
 {    
-    // facciamo partire il timer per il controllo delle sessioni e dei Lock
-    [self.timerVerifySessionInProgress invalidate];
-    self.timerVerifySessionInProgress = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(verifyDownloadUploadInProgress) userInfo:nil repeats:YES];
-    
     // refresh active Main
     if (_activeMain) {
         [_activeMain reloadDatasource];
@@ -830,13 +826,13 @@
     item.selectedImage = [UIImage imageNamed:@"tabBarFiles"];
     
     // Favorites
-    item = [tabBarController.tabBar.items objectAtIndex: k_tabBarApplicationIndexOffline];
+    item = [tabBarController.tabBar.items objectAtIndex: k_tabBarApplicationIndexFavorite];
     [item setTitle:NSLocalizedString(@"_favorites_", nil)];
     item.image = [UIImage imageNamed:@"tabBarFavorite"];
     item.selectedImage = [UIImage imageNamed:@"tabBarFavorite"];
     
-    // Hide (PLUS)
-    item = [tabBarController.tabBar.items objectAtIndex: k_tabBarApplicationIndexHide];
+    // (PLUS)
+    item = [tabBarController.tabBar.items objectAtIndex: k_tabBarApplicationIndexPlusHide];
     item.title = nil;
     item.image = nil;
     item.enabled = false;
@@ -963,10 +959,14 @@
         
         UITabBarItem *tbItem = [tbc.tabBar.items objectAtIndex:0];
         
-        if (total > 0)
+        if (total > 0) {
             [tbItem setBadgeValue:[NSString stringWithFormat:@"%li", (unsigned long)total]];
-        else
+        } else {
             [tbItem setBadgeValue:nil];
+            
+            NSDictionary* userInfo = @{@"fileID": @"", @"serverUrl": @"", @"cryptated": [NSNumber numberWithFloat:0], @"progress": [NSNumber numberWithFloat:0]};
+            [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"NotificationProgressTask" object:nil userInfo:userInfo];
+        }
     }
 }
 
@@ -1033,7 +1033,7 @@
         newColor = [NCBrandColor sharedInstance].customer;
     }
     
-    if (self.activeAccount.length > 0 && ![newColor isEqual:[NCBrandColor sharedInstance].brand]) {
+    if (self.activeAccount.length > 0 && ![newColor isEqual:[NCBrandColor sharedInstance].brand] && newColor) {
         
         [NCBrandColor sharedInstance].brand = newColor;
         [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"changeTheming" object:nil];
@@ -1394,20 +1394,6 @@
     return queueNumUploadWWan;
 }
 
-- (void)verifyDownloadUploadInProgress
-{
-    [self.timerVerifySessionInProgress invalidate];
-    
-    // Test Maintenance - Account
-    if (self.maintenanceMode == NO || self.activeAccount.length > 0) {
-    
-        [[CCNetworking sharedNetworking] verifyDownloadInProgress];
-        [[CCNetworking sharedNetworking] verifyUploadInProgress];
-    }
-    
-    self.timerVerifySessionInProgress = [NSTimer scheduledTimerWithTimeInterval:k_timerVerifySession target:self selector:@selector(verifyDownloadUploadInProgress) userInfo:nil repeats:YES];
-}
-
 // Notification change session
 - (void)sessionChanged:(NSNotification *)notification
 {
@@ -1455,6 +1441,7 @@
     tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"fileID = %@", fileID]];
     if (!metadata) return;
     NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
+    if (!serverUrl) return;
     
     if ([[_listChangeTask objectForKey:fileID] isEqualToString:@"stopUpload"]) {
         
@@ -1579,7 +1566,7 @@
 #endif
     
     NSString *actualVersion = [CCUtility getVersion];
-    NSString *actualBuild = [CCUtility getBuild];
+    //NSString *actualBuild = [CCUtility getBuild];
     
     /* ---------------------- UPGRADE VERSION ----------------------- */
     

+ 28 - 32
iOSClient/AutoUpload/NCAutoUpload.m

@@ -380,8 +380,8 @@
         NSDate *assetDate = asset.creationDate;
         PHAssetMediaType assetMediaType = asset.mediaType;
         NSString *session;
-        NSString *fileName = [CCUtility createFileNameFromAsset:asset key:nil];
-        
+        NSString *fileName = [CCUtility createFileName:[asset valueForKey:@"filename"] fileDate:asset.creationDate fileType:asset.mediaType keyFileName:k_keyFileNameAutoUploadMask keyFileNameType:k_keyFileNameAutoUploadType];
+
         // Select type of session
         
         if (assetMediaType == PHAssetMediaTypeImage && tableAccount.autoUploadWWAnPhoto == NO) session = k_upload_session;
@@ -415,12 +415,16 @@
             else
                 metadataNet.selectorPost = selectorUploadRemovePhoto;
             
-            metadataNet.priority = NSOperationQueuePriorityLow;
         } else {
             metadataNet.selector = selectorUploadAutoUpload;
             metadataNet.selectorPost = nil;
-            metadataNet.priority = NSOperationQueuePriorityLow;
         }
+        
+        if (assetMediaType == PHAssetMediaTypeImage)
+            metadataNet.priority = k_priorityAutoUploadImage;
+        else
+            metadataNet.priority = k_priorityAutoUploadVideo;
+
         metadataNet.fileName = fileName;
         metadataNet.serverUrl = serverUrl;
         metadataNet.session = session;
@@ -480,7 +484,6 @@
 - (void)loadAutoUpload:(NSNumber *)maxConcurrent
 {
     CCMetadataNet *metadataNet;
-    PHFetchResult *result;
     
     // Stop Timer
     [app.timerProcessAutoUpload invalidate];
@@ -496,23 +499,16 @@
         metadataNet = [[NCManageDatabase sharedInstance] getQueueUploadWithSelector:selectorUploadAutoUpload];
         if (metadataNet) {
             
-            result = [PHAsset fetchAssetsWithLocalIdentifiers:@[metadataNet.assetLocalIdentifier] options:nil];
+            // Priority Error only in Foreground
+            if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground && metadataNet.priority <= k_priorityAutoUploadError)
+                continue;
             
-        } else
-            break;
-        
-        if (result.count > 0) {
-            
-            [[CCNetworking sharedNetworking] uploadFileFromAssetLocalIdentifier:metadataNet.assetLocalIdentifier fileName:metadataNet.fileName serverUrl:metadataNet.serverUrl cryptated:metadataNet.cryptated session:metadataNet.session taskStatus:metadataNet.taskStatus selector:metadataNet.selector selectorPost:metadataNet.selectorPost errorCode:metadataNet.errorCode delegate:app.activeMain];
+            [[CCNetworking sharedNetworking] uploadFileFromAssetLocalIdentifier:metadataNet delegate:app.activeMain];
             
             counterNewUpload++;
             
-        } else {
-            
-            [[NCManageDatabase sharedInstance] addActivityClient:metadataNet.fileName fileID:metadataNet.assetLocalIdentifier action:k_activityDebugActionUpload selector:selectorUploadAutoUploadAll note:@"Internal error image/video not found [0]" type:k_activityTypeFailure verbose:k_activityVerboseHigh activeUrl:app.activeUrl];
-            
-            [[NCManageDatabase sharedInstance] deleteQueueUploadWithAssetLocalIdentifier:metadataNet.assetLocalIdentifier selector:selectorUploadAutoUpload];
-        }
+        } else
+            break;
         
         counterUploadInQueueAndInLock = [app getNumberUploadInQueues] + [app getNumberUploadInQueuesWWan] + [[[NCManageDatabase sharedInstance] getLockQueueUpload] count];
     }
@@ -535,24 +531,17 @@
             metadataNet =  [[NCManageDatabase sharedInstance] getQueueUploadWithSelector:selectorUploadAutoUploadAll];
             if (metadataNet) {
                 
-                result = [PHAsset fetchAssetsWithLocalIdentifiers:@[metadataNet.assetLocalIdentifier] options:nil];
+                // Priority Error only in Foreground
+                if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground && metadataNet.priority <= k_priorityAutoUploadError)
+                    continue;
+
+                [[CCNetworking sharedNetworking] uploadFileFromAssetLocalIdentifier:metadataNet delegate:app.activeMain];
+                
+                counterNewUpload++;
         
             } else
                 break;
             
-            if (result.count > 0) {
-            
-                [[CCNetworking sharedNetworking] uploadFileFromAssetLocalIdentifier:metadataNet.assetLocalIdentifier fileName:metadataNet.fileName serverUrl:metadataNet.serverUrl cryptated:metadataNet.cryptated session:metadataNet.session taskStatus:metadataNet.taskStatus selector:metadataNet.selector selectorPost:metadataNet.selectorPost errorCode:metadataNet.errorCode delegate:app.activeMain];
-            
-                counterNewUpload++;
-                            
-            } else {
-            
-                [[NCManageDatabase sharedInstance] addActivityClient:metadataNet.fileName fileID:metadataNet.assetLocalIdentifier action:k_activityDebugActionUpload selector:selectorUploadAutoUploadAll note:@"Internal error image/video not found [0]" type:k_activityTypeFailure verbose:k_activityVerboseHigh activeUrl:app.activeUrl];
-            
-                [[NCManageDatabase sharedInstance] deleteQueueUploadWithAssetLocalIdentifier:metadataNet.assetLocalIdentifier selector:selectorUploadAutoUploadAll];
-            }
-        
             counterUploadInQueueAndInLock = [app getNumberUploadInQueues] + [app getNumberUploadInQueuesWWan] + [[[NCManageDatabase sharedInstance] getLockQueueUpload] count];
         }
     }
@@ -571,6 +560,13 @@
         }
     }
     
+    // verify Download/Upload 
+    if (counterNewUpload == 0) {
+        
+        [[CCNetworking sharedNetworking] verifyDownloadInProgress];
+        [[CCNetworking sharedNetworking] verifyUploadInProgress];
+    }
+
     // Start Timer
     app.timerProcessAutoUpload = [NSTimer scheduledTimerWithTimeInterval:k_timerProcessAutoUpload target:app selector:@selector(processAutoUpload) userInfo:nil repeats:YES];
 }

+ 1 - 0
iOSClient/Brand/NCBrand.swift

@@ -45,6 +45,7 @@ class NCBrandColor: NSObject {
     public var tabBar:                  UIColor = .white
     public var tableBackground:         UIColor = .white
     public var transferBackground:      UIColor = UIColor(red: 178.0/255.0, green: 244.0/255.0, blue: 258.0/255.0, alpha: 0.1)
+    public let nextcloud:               UIColor = UIColor(red: 0.0/255.0, green: 130.0/255.0, blue: 201.0/255.0, alpha: 1.0)
     
     override init() {
         self.brand = self.customer

+ 2 - 2
iOSClient/Brand/Picker.plist

@@ -17,9 +17,9 @@
 	<key>CFBundlePackageType</key>
 	<string>XPC!</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.17.4</string>
+	<string>2.17.5</string>
 	<key>CFBundleVersion</key>
-	<string>00038</string>
+	<string>00005</string>
 	<key>NSAppTransportSecurity</key>
 	<dict>
 		<key>NSAllowsArbitraryLoads</key>

+ 2 - 2
iOSClient/Brand/PickerFileProvider.plist

@@ -17,9 +17,9 @@
 	<key>CFBundlePackageType</key>
 	<string>XPC!</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.17.4</string>
+	<string>2.17.5</string>
 	<key>CFBundleVersion</key>
-	<string>00038</string>
+	<string>00005</string>
 	<key>NSExtension</key>
 	<dict>
 		<key>NSExtensionFileProviderDocumentGroup</key>

+ 2 - 2
iOSClient/Brand/Share.plist

@@ -17,9 +17,9 @@
 	<key>CFBundlePackageType</key>
 	<string>XPC!</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.17.4</string>
+	<string>2.17.5</string>
 	<key>CFBundleVersion</key>
-	<string>00038</string>
+	<string>00005</string>
 	<key>NSAppTransportSecurity</key>
 	<dict>
 		<key>NSAllowsArbitraryLoads</key>

+ 2 - 2
iOSClient/Brand/iOSClient.plist

@@ -46,7 +46,7 @@
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.17.4</string>
+	<string>2.17.5</string>
 	<key>CFBundleSignature</key>
 	<string>????</string>
 	<key>CFBundleURLTypes</key>
@@ -69,7 +69,7 @@
 		</dict>
 	</array>
 	<key>CFBundleVersion</key>
-	<string>00038</string>
+	<string>00005</string>
 	<key>Fabric</key>
 	<dict>
 		<key>APIKey</key>

+ 14 - 14
iOSClient/CCGlobal.h

@@ -130,7 +130,7 @@ extern NSString *const urlBaseUploadDB;
 
 #define k_maxConcurrentOperation                         10
 #define k_maxConcurrentOperationDownloadUpload           10
-#define k_maxConcurrentOperationDownloadUploadBackground 2
+#define k_maxConcurrentOperationDownloadUploadBackground 1
 
 // Error
 #define k_CCErrorTaskNil                                -9999
@@ -148,7 +148,6 @@ extern NSString *const urlBaseUploadDB;
 
 // Metadata.Net SELECTOR
 #define selectorAddFavorite                             @"addFavorite"
-#define selectorAddLocal                                @"addLocal"
 #define selectorCreateFolder                            @"createFolder"
 #define selectorDecryptFile                             @"decryptFile"
 #define selectorDelete                                  @"delete"
@@ -234,7 +233,6 @@ extern NSString *const urlBaseUploadDB;
 // Metadata : Type
 #define k_metadataType_file                             @"file"
 #define k_metadataType_template                         @"model"
-#define k_metadataType_local                            @"local"
 
 // Metadata : Filename Type
 #define k_metadataTypeFilenamePlain                     0
@@ -242,25 +240,21 @@ extern NSString *const urlBaseUploadDB;
 #define k_metadataTypeFilenameCrypto                    2
 
 // Metadata : Status
-
 #define k_metadataStatusNormal                          0
 #define k_metadataStatusHide                            1
 
+// TabBar button
 #define k_tabBarApplicationIndexFile                    0
-#define k_tabBarApplicationIndexOffline                 1
-#define k_tabBarApplicationIndexHide                    2
+#define k_tabBarApplicationIndexFavorite                1
+#define k_tabBarApplicationIndexPlusHide                2
 #define k_tabBarApplicationIndexPhotos                  3
 #define k_tabBarApplicationIndexMore                    4
 
+// Filename Mask and Type
 #define k_keyFileNameMask                               @"fileNameMask"
-
-// Type of page Offline
-#define k_pageOfflineFavorites                          @"Favorites"
-#define k_pageOfflineOffline                            @"Offline"
-#define k_pageOfflineLocal                              @"Local"
-
-#define k_pageControlCenterTransfer                     @"Transfer"
-#define k_pageControlCenterActivity                     @"Activity"
+#define k_keyFileNameType                               @"fileNameType"
+#define k_keyFileNameAutoUploadMask                     @"fileNameAutoUploadMask"
+#define k_keyFileNameAutoUploadType                     @"fileNameAutoUploadType"
 
 // Activity
 #define k_activityVerboseDefault                        0
@@ -283,6 +277,12 @@ extern NSString *const urlBaseUploadDB;
 #define k_activityDebugActionFeatures                   @"Features Supported By Server"
 #define k_activityDebugActionCapabilities               @"Capabilities Of Server"
 
+// Priority Auto Upload
+#define k_priorityAutoUploadImage                       0
+#define k_priorityAutoUploadVideo                       -1
+#define k_priorityAutoUploadError                       -2
+#define k_priorityAutoUploadStop                        -4
+
 // -----------------------------------------------------------------------------------------------------------
 // -----------------------------------------------------------------------------------------------------------
 

+ 27 - 12
iOSClient/Create/CCCreateCloud.swift

@@ -285,6 +285,15 @@ class CreateFormUploadAssets: XLFormViewController, CCMoveDelegate {
         }
         section.addFormRow(row)
 
+        // Section: Add File Name Type
+
+        section = XLFormSectionDescriptor.formSection()
+        form.addFormSection(section)
+
+        row = XLFormRowDescriptor(tag: "addFileNameType", rowType: XLFormRowDescriptorTypeBooleanSwitch, title: NSLocalizedString("_filenametype_photo_video_", comment: ""))
+        row.value = CCUtility.getFileNameType(k_keyFileNameType)
+        section.addFormRow(row)
+        
         // Section: Rename File Name
         
         section = XLFormSectionDescriptor.formSection()
@@ -339,13 +348,17 @@ class CreateFormUploadAssets: XLFormViewController, CCMoveDelegate {
                 
             }
         }
+        else if formRow.tag == "addFileNameType" {
+            CCUtility.setFileNameType((formRow.value! as AnyObject).boolValue, key: k_keyFileNameType)
+            self.reloadForm()
+        }
         else if formRow.tag == "maskFileName" {
             
-            let fileName : String? = formRow.value as? String
+            let fileName = formRow.value as? String
             
             self.form.delegate = nil
             
-            if fileName != nil {
+            if let fileName = fileName {
                 formRow.value = CCUtility.removeForbiddenCharactersServer(fileName)
             }
             
@@ -432,8 +445,10 @@ class CreateFormUploadAssets: XLFormViewController, CCMoveDelegate {
         case 1:
             return "    " + NSLocalizedString("_use_folder_photos_", comment: "")
         case 2:
-            return "    " + NSLocalizedString("_rename_filename_", comment: "")
+            return "    " + NSLocalizedString("_add_filenametype_", comment: "")
         case 3:
+            return "    " + NSLocalizedString("_rename_filename_", comment: "")
+        case 4:
             return NSLocalizedString("_preview_filename_", comment: "")
         default:
             return ""
@@ -462,13 +477,13 @@ class CreateFormUploadAssets: XLFormViewController, CCMoveDelegate {
     
         self.serverUrl = serverUrlTo
         
-        if title == nil {
+        if let title = title {
             
-            self.titleServerUrl = "/"
+            self.titleServerUrl = title
             
         } else {
             
-            self.titleServerUrl = title
+            self.titleServerUrl = "/"
         }
         
         self.reloadForm()
@@ -502,10 +517,11 @@ class CreateFormUploadAssets: XLFormViewController, CCMoveDelegate {
     func previewFileName(valueRename : String?) -> String {
         
         var returnString : String = ""
+        let asset = assets[0] as! PHAsset
         
-        if valueRename != nil {
+        if let valueRename = valueRename {
             
-            let valueRenameTrimming = valueRename!.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
+            let valueRenameTrimming = valueRename.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
             
             if valueRenameTrimming.characters.count > 0 {
                 
@@ -513,18 +529,17 @@ class CreateFormUploadAssets: XLFormViewController, CCMoveDelegate {
                 CCUtility.setFileNameMask(valueRenameTrimming, key: k_keyFileNameMask)
                 self.form.delegate = self
                 
-                returnString = CCUtility.createFileName(from: assets[0] as! PHAsset, key: k_keyFileNameMask)
-                
+                returnString = CCUtility.createFileName(asset.value(forKey: "filename"), fileDate: asset.creationDate, fileType: asset.mediaType, keyFileName: k_keyFileNameMask, keyFileNameType: k_keyFileNameType)
             } else {
                 
                 CCUtility.setFileNameMask("", key: k_keyFileNameMask)
-                returnString = CCUtility.createFileName(from: assets[0] as! PHAsset, key: nil)
+                returnString = CCUtility.createFileName(asset.value(forKey: "filename"), fileDate: asset.creationDate, fileType: asset.mediaType, keyFileName: nil, keyFileNameType: k_keyFileNameType)
             }
             
         } else {
             
             CCUtility.setFileNameMask("", key: k_keyFileNameMask)
-            returnString = CCUtility.createFileName(from: assets[0] as! PHAsset, key: nil)
+            returnString = CCUtility.createFileName(asset.value(forKey: "filename"), fileDate: asset.creationDate, fileType: asset.mediaType, keyFileName: nil, keyFileNameType: k_keyFileNameType)
         }
         
         return NSLocalizedString("_preview_filename_", comment: "") + ":" + "\n\n" + returnString

+ 14 - 14
iOSClient/Database/NCDatabase.swift

@@ -70,20 +70,6 @@ class tableActivity: Object {
     dynamic var verbose: Bool = false
 }
 
-class tableQueueUpload: Object {
-    
-    dynamic var account = ""
-    dynamic var assetLocalIdentifier = ""
-    dynamic var date = NSDate()
-    dynamic var fileName = ""
-    dynamic var lock: Bool = false
-    dynamic var priority: Int = 0
-    dynamic var selector = ""
-    dynamic var selectorPost = ""
-    dynamic var serverUrl = ""
-    dynamic var session = ""
-}
-
 class tableCapabilities: Object {
     
     dynamic var account = ""
@@ -221,6 +207,20 @@ class tablePhotoLibrary: Object {
     }
 }
 
+class tableQueueUpload: Object {
+    
+    dynamic var account = ""
+    dynamic var assetLocalIdentifier = ""
+    dynamic var date = NSDate()
+    dynamic var fileName = ""
+    dynamic var lock: Bool = false
+    dynamic var priority: Int = 0
+    dynamic var selector = ""
+    dynamic var selectorPost = ""
+    dynamic var serverUrl = ""
+    dynamic var session = ""
+}
+
 class tableShare: Object {
     
     dynamic var account = ""

+ 112 - 25
iOSClient/Database/NCManageDatabase.swift

@@ -33,6 +33,27 @@ class NCManageDatabase: NSObject {
     override init() {
         
         let dirGroup = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: NCBrandOptions.sharedInstance.capabilitiesGroups)
+        
+        let configCompact = Realm.Configuration(
+            
+            fileURL: dirGroup?.appendingPathComponent("\(appDatabaseNextcloud)/\(k_databaseDefault)"),
+            
+            shouldCompactOnLaunch: { totalBytes, usedBytes in
+            // totalBytes refers to the size of the file on disk in bytes (data + free space)
+            // usedBytes refers to the number of bytes used by data in the file
+            
+            // Compact if the file is over 100MB in size and less than 50% 'used'
+            let oneHundredMB = 100 * 1024 * 1024
+            return (totalBytes > oneHundredMB) && (Double(usedBytes) / Double(totalBytes)) < 0.5
+        })
+        
+        do {
+            // Realm is compacted on the first open if the configuration block conditions were met.
+            _ = try Realm(configuration: configCompact)
+        } catch {
+            // handle error compacting or opening Realm
+        }
+        
         let config = Realm.Configuration(
         
             fileURL: dirGroup?.appendingPathComponent("\(appDatabaseNextcloud)/\(k_databaseDefault)"),
@@ -200,26 +221,28 @@ class NCManageDatabase: NSObject {
         return result
     }
 
-    func getAccounts() -> [String] {
+    func getAccounts() -> [String]? {
         
         let realm = try! Realm()
         
         let results = realm.objects(tableAccount.self).sorted(byKeyPath: "account", ascending: true)
         
-        return Array(results.map { $0.account })
+        if results.count > 0 {
+            return Array(results.map { $0.account })
+        }
+        
+        return nil
     }
     
     func getAccount(predicate: NSPredicate) -> tableAccount? {
         
         let realm = try! Realm()
         
-        let result = realm.objects(tableAccount.self).filter(predicate).first
-        
-        if result != nil {
-            return tableAccount.init(value: result!)
-        } else {
-            return nil
+        if let result = realm.objects(tableAccount.self).filter(predicate).first {
+            return tableAccount.init(value: result)
         }
+        
+        return nil
     }
     
     func getAccountAutoUploadFileName() -> String {
@@ -765,10 +788,14 @@ class NCManageDatabase: NSObject {
         }
     }
     
-    func getDirectoryID(_ serverUrl: String) -> String {
+    func getDirectoryID(_ serverUrl: String?) -> String? {
         
         guard let tableAccount = self.getAccountActive() else {
-            return ""
+            return nil
+        }
+        
+        guard let serverUrl = serverUrl else {
+            return nil
         }
         
         let realm = try! Realm()
@@ -780,16 +807,20 @@ class NCManageDatabase: NSObject {
         return result.directoryID
     }
     
-    func getServerUrl(_ directoryID: String) -> String {
+    func getServerUrl(_ directoryID: String?) -> String? {
         
         guard let tableAccount = self.getAccountActive() else {
-            return ""
+            return nil
+        }
+        
+        guard let directoryID = directoryID else {
+            return nil
         }
         
         let realm = try! Realm()
         
         guard let result = realm.objects(tableDirectory.self).filter("account = %@ AND directoryID = %@", tableAccount.account, directoryID).first else {
-            return ""
+            return nil
         }
         
         return result.serverUrl
@@ -856,6 +887,7 @@ class NCManageDatabase: NSObject {
             try realm.write {
             
                 guard let result = realm.objects(tableDirectory.self).filter("account = %@ AND serverUrl = %@", tableAccount.account, serverUrl).first else {
+                    realm.cancelWrite()
                     return
                 }
                 
@@ -1065,6 +1097,7 @@ class NCManageDatabase: NSObject {
             try realm.write {
                 
                 guard let result = realm.objects(tableLocalFile.self).filter("fileID = %@", fileID).first else {
+                    realm.cancelWrite()
                     return
                 }
                 
@@ -1110,7 +1143,7 @@ class NCManageDatabase: NSObject {
     //MARK: -
     //MARK: Table Metadata
     
-    func addMetadata(_ metadata: tableMetadata, activeUrl: String, serverUrl: String) -> tableMetadata? {
+    func addMetadata(_ metadata: tableMetadata) -> tableMetadata? {
         
         guard self.getAccountActive() != nil else {
             return nil
@@ -1131,7 +1164,11 @@ class NCManageDatabase: NSObject {
         return tableMetadata.init(value: metadata)
     }
     
-    func addMetadatas(_ metadatas: [tableMetadata], activeUrl: String, serverUrl: String) -> [tableMetadata] {
+    func addMetadatas(_ metadatas: [tableMetadata], serverUrl: String) -> [tableMetadata]? {
+        
+        guard self.getAccountActive() != nil else {
+            return nil
+        }
         
         let realm = try! Realm()
         
@@ -1145,8 +1182,9 @@ class NCManageDatabase: NSObject {
             print("Could not write to database: ", error)
         }
         
-        let directoryID = self.getDirectoryID(serverUrl)
-        self.setDateReadDirectory(directoryID: directoryID)
+        if let directoryID = self.getDirectoryID(serverUrl) {
+            self.setDateReadDirectory(directoryID: directoryID)
+        }
         
         return Array(metadatas.map { tableMetadata.init(value:$0) })
     }
@@ -1213,18 +1251,13 @@ class NCManageDatabase: NSObject {
     
     func updateMetadata(_ metadata: tableMetadata, activeUrl: String) -> tableMetadata? {
         
-        let autoUploadFileName = self.getAccountAutoUploadFileName()
-        let autoUploadDirectory = self.getAccountAutoUploadDirectory(activeUrl)
-        let serverUrl = self.getServerUrl(metadata.directoryID)
         let directoryID = metadata.directoryID
         
-        let metadataWithIcon = CCUtility.insertTypeFileIconName(metadata, serverUrl: serverUrl, autoUploadFileName: autoUploadFileName, autoUploadDirectory: autoUploadDirectory)
-        
         let realm = try! Realm()
         
         do {
             try realm.write {
-                realm.add(metadataWithIcon!, update: true)
+                realm.add(metadata, update: true)
             }
         } catch let error {
             print("Could not write to database: ", error)
@@ -1672,7 +1705,7 @@ class NCManageDatabase: NSObject {
         
         realm.beginWrite()
         
-        guard let result = realm.objects(tableQueueUpload.self).filter("account = %@ AND selector = %@ AND lock == false", tableAccount.account, selector).first else {
+        guard let result = realm.objects(tableQueueUpload.self).filter("account = %@ AND selector = %@ AND lock == false", tableAccount.account, selector).sorted(byKeyPath: "priority", ascending: false).first else {
             realm.cancelWrite()
             return nil
         }
@@ -1740,6 +1773,53 @@ class NCManageDatabase: NSObject {
         }
     }
     
+    func getPriorityQueueUpload(assetLocalIdentifier: String) -> NSInteger {
+        
+        guard let tableAccount = self.getAccountActive() else {
+            return 0
+        }
+        
+        let realm = try! Realm()
+        
+        guard let result = realm.objects(tableQueueUpload.self).filter("account = %@ AND assetLocalIdentifier = %@", tableAccount.account, assetLocalIdentifier).first else {
+            return 0
+        }
+        
+        return result.priority
+    }
+
+    func setPriorityQueueUpload(assetLocalIdentifier: String, priority: NSInteger) -> Bool {
+        
+        guard let tableAccount = self.getAccountActive() else {
+            return false
+        }
+        
+        let realm = try! Realm()
+        
+        realm.beginWrite()
+        
+        guard let result = realm.objects(tableQueueUpload.self).filter("account = %@ AND assetLocalIdentifier = %@", tableAccount.account, assetLocalIdentifier).first else {
+            realm.cancelWrite()
+            return false
+        }
+        
+        // priority
+        if (result.priority <= Int(k_priorityAutoUploadError)) {
+            result.priority = result.priority - 1            
+        } else {
+            result.priority = priority
+        }
+        
+        do {
+            try realm.commitWrite()
+        } catch let error {
+            print("[LOG] Could not write to database: ", error)
+            return false
+        }
+        
+        return true
+    }
+    
     func deleteQueueUpload(assetLocalIdentifier: String, selector: String) {
         
         guard let tableAccount = self.getAccountActive() else {
@@ -2182,7 +2262,14 @@ class NCManageDatabase: NSObject {
             } else {
                 addLocalFile.date = NSDate()
             }
-            addLocalFile.etag = table.rev!
+            
+            if (table.rev != nil) {
+                addLocalFile.etag = table.rev!
+            } else {
+                realm.cancelWrite()
+                return
+            }
+            
             if table.exifDate != nil {
                 addLocalFile.exifDate = table.exifDate! as NSDate
             }

+ 45 - 32
iOSClient/Favorites/CCFavorites.m

@@ -191,7 +191,7 @@
     if (app.activeAccount.length == 0)
         return;
     
-    // verify is offline procedure is in progress selectorDownloadSynchronize
+    // verify if is already in progress selectorDownloadSynchronize
     if ([[app verifyExistsInQueuesDownloadSelector:selectorDownloadSynchronize] count] > 0)
         return;
     
@@ -201,6 +201,8 @@
 - (void)addFavoriteFolder:(NSString *)serverUrl
 {
     NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:serverUrl];
+    if (!directoryID) return;
+    
     NSString *selector;
     CCMetadataNet *metadataNet = [[CCMetadataNet alloc] initWithAccount:app.activeAccount];
     
@@ -332,42 +334,45 @@
     UIViewController *viewController;
     NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:_metadata.directoryID];
     
-    if ([metadata.model isEqualToString:@"cartadicredito"])
-        viewController = [[CCCartaDiCredito alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:NO serverUrl:serverUrl];
+    if (serverUrl) {
+        
+        if ([metadata.model isEqualToString:@"cartadicredito"])
+            viewController = [[CCCartaDiCredito alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:NO serverUrl:serverUrl];
     
-    if ([metadata.model isEqualToString:@"bancomat"])
-        viewController = [[CCBancomat alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:NO serverUrl:serverUrl];
+        if ([metadata.model isEqualToString:@"bancomat"])
+            viewController = [[CCBancomat alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:NO serverUrl:serverUrl];
     
-    if ([metadata.model isEqualToString:@"contocorrente"])
-        viewController = [[CCContoCorrente alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:NO serverUrl:serverUrl];
+        if ([metadata.model isEqualToString:@"contocorrente"])
+            viewController = [[CCContoCorrente alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:NO serverUrl:serverUrl];
     
-    if ([metadata.model isEqualToString:@"accountweb"])
-        viewController = [[CCAccountWeb alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:NO serverUrl:serverUrl];
+        if ([metadata.model isEqualToString:@"accountweb"])
+            viewController = [[CCAccountWeb alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:NO serverUrl:serverUrl];
     
-    if ([metadata.model isEqualToString:@"patenteguida"])
-        viewController = [[CCPatenteGuida alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:NO serverUrl:serverUrl];
+        if ([metadata.model isEqualToString:@"patenteguida"])
+            viewController = [[CCPatenteGuida alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:NO serverUrl:serverUrl];
     
-    if ([metadata.model isEqualToString:@"cartaidentita"])
-        viewController = [[CCCartaIdentita alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:NO serverUrl:serverUrl];
+        if ([metadata.model isEqualToString:@"cartaidentita"])
+            viewController = [[CCCartaIdentita alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:NO serverUrl:serverUrl];
     
-    if ([metadata.model isEqualToString:@"passaporto"])
-        viewController = [[CCPassaporto alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:NO serverUrl:serverUrl];
+        if ([metadata.model isEqualToString:@"passaporto"])
+            viewController = [[CCPassaporto alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:NO serverUrl:serverUrl];
     
-    if ([metadata.model isEqualToString:@"note"]) {
+        if ([metadata.model isEqualToString:@"note"]) {
         
-        viewController = [[CCNote alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:NO serverUrl:serverUrl];
+            viewController = [[CCNote alloc] initWithDelegate:self fileName:metadata.fileName uuid:metadata.uuid fileID:metadata.fileID isLocal:NO serverUrl:serverUrl];
         
-        UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
+            UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
         
-        [self presentViewController:navigationController animated:YES completion:nil];
+            [self presentViewController:navigationController animated:YES completion:nil];
         
-    } else {
+        } else {
         
-        UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
+            UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
         
-        [navigationController setModalPresentationStyle:UIModalPresentationFormSheet];
+            [navigationController setModalPresentationStyle:UIModalPresentationFormSheet];
         
-        [self presentViewController:navigationController animated:YES completion:nil];
+            [self presentViewController:navigationController animated:YES completion:nil];
+        }
     }
 }
 
@@ -556,7 +561,8 @@
         
         NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:_serverUrl];        
         
-        recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND directoryID = %@", app.activeAccount, directoryID] sorted:sorted ascending:[CCUtility getAscendingSettings]];
+        if (directoryID)
+            recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND directoryID = %@", app.activeAccount, directoryID] sorted:sorted ascending:[CCUtility getAscendingSettings]];
     }
         
     CCSectionDataSourceMetadata *sectionDataSource = [CCSectionMetadata creataDataSourseSectionMetadata:recordsTableMetadata listProgressMetadata:nil groupByField:nil replaceDateToExifDate:NO activeAccount:app.activeAccount];
@@ -627,6 +633,8 @@
     
     // Shared
     NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
+    if (!serverUrl)
+        return cell;
     NSString *shareLink = [app.sharesLink objectForKey:[serverUrl stringByAppendingString:metadata.fileName]];
     NSString *shareUserAndGroup = [app.sharesUserAndGroup objectForKey:[serverUrl stringByAppendingString:metadata.fileName]];
 
@@ -686,7 +694,7 @@
         if ([metadata.type isEqualToString: k_metadataType_template])
             cell.labelInfoFile.text = [NSString stringWithFormat:@"%@", date];
         
-        if ([metadata.type isEqualToString: k_metadataType_file] || [metadata.type isEqualToString: k_metadataType_local]) {
+        if ([metadata.type isEqualToString: k_metadataType_file]) {
             
             BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/%@", app.directoryUser, metadata.fileID]];
             
@@ -746,13 +754,15 @@
         // File do not exists
         NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:_metadata.directoryID];
 
-        if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/%@", app.directoryUser, _metadata.fileID]]) {
+        if (serverUrl) {
+            if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/%@", app.directoryUser, _metadata.fileID]]) {
             
-            [self downloadFileSuccess:_metadata.fileID serverUrl:serverUrl selector:selectorLoadFileView selectorPost:nil];
+                [self downloadFileSuccess:_metadata.fileID serverUrl:serverUrl selector:selectorLoadFileView selectorPost:nil];
             
-        } else {
+            } else {
             
-            [[CCNetworking sharedNetworking] downloadFile:_metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorLoadFileView selectorPost:nil session:k_download_session taskStatus:k_taskStatusResume delegate:self];
+                [[CCNetworking sharedNetworking] downloadFile:_metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorLoadFileView selectorPost:nil session:k_download_session taskStatus:k_taskStatusResume delegate:self];
+            }
         }
     }
     
@@ -771,10 +781,13 @@
     
     NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:_metadata.directoryID];
     
-    vc.serverUrl = [CCUtility stringAppendServerUrl:serverUrl addFileName:_metadata.fileNameData];
-    vc.titleViewControl = _metadata.fileNamePrint;
+    if (serverUrl) {
+        
+        vc.serverUrl = [CCUtility stringAppendServerUrl:serverUrl addFileName:_metadata.fileNameData];
+        vc.titleViewControl = _metadata.fileNamePrint;
     
-    [self.navigationController pushViewController:vc animated:YES];
+        [self.navigationController pushViewController:vc animated:YES];
+    }
 }
 
 #pragma --------------------------------------------------------------------------------------------

+ 2 - 1
iOSClient/Main/CCDetail.m

@@ -770,7 +770,8 @@
 {
     NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
     
-    [[CCNetworking sharedNetworking] downloadFile:metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorLoadViewImage selectorPost:nil session:k_download_session taskStatus:k_taskStatusResume delegate:nil];
+    if (serverUrl)
+        [[CCNetworking sharedNetworking] downloadFile:metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorLoadViewImage selectorPost:nil session:k_download_session taskStatus:k_taskStatusResume delegate:nil];
 }
 
 - (void)insertGeocoderLocation:(NSNotification *)notification

+ 212 - 180
iOSClient/Main/CCMain.m

@@ -41,7 +41,6 @@
     
     BOOL _isRoot;
     BOOL _isViewDidLoad;
-    BOOL _isOfflineServerUrl;
     
     BOOL _isPickerCriptate;              // if is cryptated image or video back from picker
     BOOL _isSelectedMode;
@@ -784,42 +783,45 @@
         serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:_metadata.directoryID];
     }
     
-    if ([tipo isEqualToString:@"cartadicredito"])
-        viewController = [[CCCartaDiCredito alloc] initWithDelegate:self fileName:fileName uuid:uuid fileID:fileID isLocal:NO serverUrl:serverUrl];
+    if (serverUrl) {
+        
+        if ([tipo isEqualToString:@"cartadicredito"])
+            viewController = [[CCCartaDiCredito alloc] initWithDelegate:self fileName:fileName uuid:uuid fileID:fileID isLocal:NO serverUrl:serverUrl];
     
-    if ([tipo isEqualToString:@"bancomat"])
-        viewController = [[CCBancomat alloc] initWithDelegate:self fileName:fileName uuid:uuid fileID:fileID  isLocal:NO serverUrl:serverUrl];
+        if ([tipo isEqualToString:@"bancomat"])
+            viewController = [[CCBancomat alloc] initWithDelegate:self fileName:fileName uuid:uuid fileID:fileID  isLocal:NO serverUrl:serverUrl];
     
-    if ([tipo isEqualToString:@"contocorrente"])
-        viewController = [[CCContoCorrente alloc] initWithDelegate:self fileName:fileName uuid:uuid fileID:fileID isLocal:NO serverUrl:serverUrl];
+        if ([tipo isEqualToString:@"contocorrente"])
+            viewController = [[CCContoCorrente alloc] initWithDelegate:self fileName:fileName uuid:uuid fileID:fileID isLocal:NO serverUrl:serverUrl];
     
-    if ([tipo isEqualToString:@"accountweb"])
-        viewController = [[CCAccountWeb alloc] initWithDelegate:self fileName:fileName uuid:uuid fileID:fileID isLocal:NO serverUrl:serverUrl];
+        if ([tipo isEqualToString:@"accountweb"])
+            viewController = [[CCAccountWeb alloc] initWithDelegate:self fileName:fileName uuid:uuid fileID:fileID isLocal:NO serverUrl:serverUrl];
     
-    if ([tipo isEqualToString:@"patenteguida"])
-        viewController = [[CCPatenteGuida alloc] initWithDelegate:self fileName:fileName uuid:uuid fileID:fileID isLocal:NO serverUrl:serverUrl];
+        if ([tipo isEqualToString:@"patenteguida"])
+            viewController = [[CCPatenteGuida alloc] initWithDelegate:self fileName:fileName uuid:uuid fileID:fileID isLocal:NO serverUrl:serverUrl];
     
-    if ([tipo isEqualToString:@"cartaidentita"])
-        viewController = [[CCCartaIdentita alloc] initWithDelegate:self fileName:fileName uuid:uuid fileID:fileID isLocal:NO serverUrl:serverUrl];
+        if ([tipo isEqualToString:@"cartaidentita"])
+            viewController = [[CCCartaIdentita alloc] initWithDelegate:self fileName:fileName uuid:uuid fileID:fileID isLocal:NO serverUrl:serverUrl];
     
-    if ([tipo isEqualToString:@"passaporto"])
-        viewController = [[CCPassaporto alloc] initWithDelegate:self fileName:fileName uuid:uuid fileID:fileID isLocal:NO serverUrl:serverUrl];
+        if ([tipo isEqualToString:@"passaporto"])
+            viewController = [[CCPassaporto alloc] initWithDelegate:self fileName:fileName uuid:uuid fileID:fileID isLocal:NO serverUrl:serverUrl];
     
-    if ([tipo isEqualToString:@"note"]) {
+        if ([tipo isEqualToString:@"note"]) {
         
-        viewController = [[CCNote alloc] initWithDelegate:self fileName:fileName uuid:uuid fileID:fileID isLocal:NO serverUrl:serverUrl];
+            viewController = [[CCNote alloc] initWithDelegate:self fileName:fileName uuid:uuid fileID:fileID isLocal:NO serverUrl:serverUrl];
         
-        UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
+            UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
         
-        [self presentViewController:navigationController animated:YES completion:nil];
+            [self presentViewController:navigationController animated:YES completion:nil];
         
-    } else {
+        } else {
     
-        UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
+            UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
         
-        [navigationController setModalPresentationStyle:UIModalPresentationFormSheet];
+            [navigationController setModalPresentationStyle:UIModalPresentationFormSheet];
         
-        [self presentViewController:navigationController animated:YES completion:nil];
+            [self presentViewController:navigationController animated:YES completion:nil];
+        }
     }
 }
 
@@ -978,7 +980,8 @@
                 
                 NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
                 
-                [[CCNetworking sharedNetworking] downloadFile:metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorSave selectorPost:nil session:k_download_session taskStatus: k_taskStatusResume delegate:self];
+                if (serverUrl)
+                    [[CCNetworking sharedNetworking] downloadFile:metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorSave selectorPost:nil session:k_download_session taskStatus: k_taskStatusResume delegate:self];
             }
         }
         
@@ -1408,19 +1411,6 @@
         }
     }
     
-    // addLocal
-    if ([selector isEqualToString:selectorAddLocal]) {
-        
-        [CCUtility copyFileAtPath:[NSString stringWithFormat:@"%@/%@", app.directoryUser, metadata.fileID] toPath:[NSString stringWithFormat:@"%@/%@", [CCUtility getDirectoryLocal], metadata.fileNamePrint]];
-        
-        UIImage *image = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.ico", app.directoryUser, metadata.fileID]];
-        [CCGraphics saveIcoWithEtag:metadata.fileNamePrint image:image writeToFile:nil copy:YES move:NO fromPath:[NSString stringWithFormat:@"%@/%@.ico", app.directoryUser, metadata.fileID] toPath:[NSString stringWithFormat:@"%@/.%@.ico", [CCUtility getDirectoryLocal], metadata.fileNamePrint]];
-        
-        [app messageNotification:@"_add_local_" description:@"_file_saved_local_" visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeSuccess errorCode:0];
-        
-        [self reloadDatasource:serverUrl];
-    }
-    
     // Open with...
     if ([selector isEqualToString:selectorOpenIn] && [[UIApplication sharedApplication] applicationState] == UIApplicationStateActive) {
         
@@ -1500,7 +1490,9 @@
                     countSelectorLoadPlist++;
             }
             
-            if ((countSelectorLoadPlist == 0 || countSelectorLoadPlist % k_maxConcurrentOperation == 0) && [metadata.directoryID isEqualToString:[[NCManageDatabase sharedInstance] getDirectoryID:_serverUrl]]) {
+            NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:_serverUrl];
+            
+            if ((countSelectorLoadPlist == 0 || countSelectorLoadPlist % k_maxConcurrentOperation == 0) && [metadata.directoryID isEqualToString:directoryID] && directoryID) {
             
                 dispatch_async(dispatch_get_main_queue(), ^{
                     [self reloadDatasource:serverUrl];
@@ -1548,8 +1540,11 @@
                 if (metadata.directory) {
                     
                     NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
-                    serverUrl = [CCUtility stringAppendServerUrl:serverUrl addFileName:metadata.fileName];
-                    [[CCSynchronize sharedSynchronize] synchronizedFolder:serverUrl selector:selectorReadFolderWithDownload];
+                    
+                    if (serverUrl) {
+                        serverUrl = [CCUtility stringAppendServerUrl:serverUrl addFileName:metadata.fileName];
+                        [[CCSynchronize sharedSynchronize] synchronizedFolder:serverUrl selector:selectorReadFolderWithDownload];
+                    }
                     
                 } else {
                     
@@ -1598,33 +1593,47 @@
 {
     // Auto Upload
     if([selector isEqualToString:selectorUploadAutoUpload] || [selector isEqualToString:selectorUploadAutoUploadAll]) {
+                
+        if ([[NCManageDatabase sharedInstance] getPriorityQueueUploadWithAssetLocalIdentifier:metadataNet.assetLocalIdentifier] > k_priorityAutoUploadStop) {
         
-        if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground) {
+            // Change priority Auto Upload
+            if ([[NCManageDatabase sharedInstance] setPriorityQueueUploadWithAssetLocalIdentifier:metadataNet.assetLocalIdentifier priority:k_priorityAutoUploadError]) {
             
-            // ONLY BACKGROUND
-            [[NCAutoUpload sharedInstance] performSelectorOnMainThread:@selector(loadAutoUpload:) withObject:[NSNumber numberWithInt:k_maxConcurrentOperationDownloadUploadBackground] waitUntilDone:NO];
+                // Activity
+                [[NCManageDatabase sharedInstance] addActivityClient:metadataNet.fileName fileID:metadataNet.assetLocalIdentifier action:k_activityDebugActionUpload selector:selector note:message type:k_activityTypeFailure verbose:k_activityVerboseDefault  activeUrl:app.activeUrl];
+            }
+            
+            [app messageNotification:@"_automatic_upload_file_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
             
         } else {
             
-            // ONLY FOREFROUND
-            [[NCAutoUpload sharedInstance] performSelectorOnMainThread:@selector(loadAutoUpload:) withObject:[NSNumber numberWithInt:k_maxConcurrentOperationDownloadUpload] waitUntilDone:NO];
+            // Delete record on Table Auto Upload
+            if ([selector isEqualToString:selectorUploadAutoUpload] || [selector isEqualToString:selectorUploadAutoUploadAll])
+                [[NCManageDatabase sharedInstance] deleteQueueUploadWithAssetLocalIdentifier:metadataNet.assetLocalIdentifier selector:selector];
+            
+            // Activity
+            [[NCManageDatabase sharedInstance] addActivityClient:metadataNet.fileName fileID:metadataNet.assetLocalIdentifier action:k_activityDebugActionUpload selector:selector note:@"Too many error, file deleted" type:k_activityTypeFailure verbose:k_activityVerboseDefault  activeUrl:app.activeUrl];
+            
+            [app messageNotification:@"_automatic_upload_file_" description:@"Too many error, file deleted, see Activity for more info" visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
         }
-    }
+        
+    } else {
     
-    // Read File test do not exists
-    if (errorCode == k_CCErrorFileUploadNotFound && fileID) {
+        // Read File test do not exists
+        if (errorCode == k_CCErrorFileUploadNotFound && fileID) {
        
-        tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"fileID = %@", fileID]];
+            tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"fileID = %@", fileID]];
         
-        // reUpload
-        if (metadata)
-            [[CCNetworking sharedNetworking] uploadFileMetadata:metadata taskStatus:k_taskStatusResume];
-    }
+            // reUpload
+            if (metadata)
+                [[CCNetworking sharedNetworking] uploadFileMetadata:metadata taskStatus:k_taskStatusResume];
+        }
     
-    // Print error
-    else if (errorCode != kCFURLErrorCancelled && errorCode != 403) {
+        // Print error
+        else if (errorCode != kCFURLErrorCancelled && errorCode != 403) {
         
-        [app messageNotification:@"_upload_file_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
+            [app messageNotification:@"_upload_file_" description:message visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:errorCode];
+        }
     }
     
     [self reloadDatasource:serverUrl];
@@ -1647,14 +1656,16 @@
         }
     }
     
-    if ([selectorPost isEqualToString:selectorReadFolderForced] ) {
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void) {
+        if ([selectorPost isEqualToString:selectorReadFolderForced] ) {
             
-        [self readFolder:serverUrl];
+            [self readFolder:serverUrl];
             
-    } else {
+        } else {
     
-        [self reloadDatasource:serverUrl];
-    }
+            [self reloadDatasource:serverUrl];
+        }
+    });
 }
 
 //
@@ -1677,16 +1688,18 @@
     
     NSString *autoUploadPath = [[NCManageDatabase sharedInstance] getAccountAutoUploadPath:app.activeUrl];
     NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:serverUrl];
+    if (!directoryID) return;
     
-    // Create the folder for Photos & if request the subfolders
-    if (![[NCAutoUpload sharedInstance] createFolderSubFolderAutoUploadFolderPhotos:autoUploadPath useSubFolder:useSubFolder assets:(PHFetchResult *)assets selector:selectorUploadFile])
-        return;
+    // if request create the folder for Photos &  the subfolders
+    if ([autoUploadPath isEqualToString:serverUrl])
+        if (![[NCAutoUpload sharedInstance] createFolderSubFolderAutoUploadFolderPhotos:autoUploadPath useSubFolder:useSubFolder assets:(PHFetchResult *)assets selector:selectorUploadFile])
+            return;
     
     NSLog(@"[LOG] Asset N. %lu", (unsigned long)[assets count]);
     
     for (PHAsset *asset in assets) {
         
-        NSString *fileName = [CCUtility createFileNameFromAsset:asset key: k_keyFileNameMask];
+        NSString *fileName = [CCUtility createFileName:[asset valueForKey:@"filename"] fileDate:asset.creationDate fileType:asset.mediaType keyFileName:k_keyFileNameMask keyFileNameType:k_keyFileNameType];
         
         NSDate *assetDate = asset.creationDate;
         NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
@@ -1928,7 +1941,7 @@
     }
     
     // insert in Database
-    metadatasToInsertInDB = (NSMutableArray *)[[NCManageDatabase sharedInstance] addMetadatas:metadatasToInsertInDB activeUrl:app.activeUrl serverUrl:metadataNet.serverUrl];
+    metadatasToInsertInDB = (NSMutableArray *)[[NCManageDatabase sharedInstance] addMetadatas:metadatasToInsertInDB serverUrl:metadataNet.serverUrl];
     
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
         
@@ -1945,7 +1958,8 @@
     if (_isSearchMode) {
         
         // Fix managed -> Unmanaged _searchResultMetadatas
-        _searchResultMetadatas = [[NSMutableArray alloc] initWithArray:metadatasToInsertInDB];
+        if (metadatasToInsertInDB)
+            _searchResultMetadatas = [[NSMutableArray alloc] initWithArray:metadatasToInsertInDB];
         
         [self reloadDatasource:metadataNet.serverUrl];
     }
@@ -2038,6 +2052,8 @@
         // First : filter
             
         NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:_serverUrl];
+        if (!directoryID) return;
+        
         NSPredicate *predicate = [NSPredicate predicateWithFormat:@"directoryID = %@ AND account = %@ AND fileNamePrint CONTAINS[cd] %@", directoryID, app.activeAccount, fileName];
         NSArray *records = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:predicate sorted:nil ascending:NO];
             
@@ -2203,7 +2219,8 @@
 {
     tableMetadata* metadata = [arguments objectAtIndex:0];
     NSString *fileName = [arguments objectAtIndex:1];
-    
+    NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
+    if (!serverUrl) return;
     CCTemplates *templates = [[CCTemplates alloc] init];
     
     NSMutableDictionary *field = [[CCCrypto sharedManager] getDictionaryEncrypted:metadata.fileName uuid:metadata.uuid isLocal:NO directoryUser:app.directoryUser];
@@ -2217,7 +2234,7 @@
         metadataNet.fileName = [CCUtility trasformedFileNamePlistInCrypto:fileNameModel];
         metadataNet.fileNamePrint = fileName;
         metadataNet.etag = metadata.etag;
-        metadataNet.serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
+        metadataNet.serverUrl = serverUrl;
         metadataNet.session = k_upload_session_foreground;
         metadataNet.taskStatus = k_taskStatusResume;
         
@@ -2257,7 +2274,8 @@
         NSString *directoryID = metadataNet.directoryID;
         NSString *directoryIDTo = metadataNet.directoryIDTo;
         NSString *serverUrlTo = [[NCManageDatabase sharedInstance] getServerUrl:directoryIDTo];
-
+        if (!serverUrlTo) return;
+        
         // FILE -> Metadata
         if (metadataNet.directory == NO)
             [[NCManageDatabase sharedInstance] moveMetadataWithFileName:fileName directoryID:directoryID directoryIDTo:directoryIDTo];
@@ -2306,6 +2324,12 @@
     NSInteger numFile = [[arguments objectAtIndex:2] integerValue];
     NSInteger ofFile = [[arguments objectAtIndex:3] integerValue];
     
+    NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
+    if (!serverUrl) return;
+    
+    NSString *directoryIDTo = [[NCManageDatabase sharedInstance] getDirectoryID:serverUrlTo];
+    if (!directoryIDTo) return;
+    
     // Plain
     if (metadata.cryptated == NO) {
             
@@ -2339,13 +2363,13 @@
         metadataNet.directory = metadata.directory;
         metadataNet.fileID = metadata.fileID;
         metadataNet.directoryID = metadata.directoryID;
-        metadataNet.directoryIDTo = [[NCManageDatabase sharedInstance] getDirectoryID:serverUrlTo];
+        metadataNet.directoryIDTo = directoryIDTo;
         metadataNet.fileName = metadata.fileName;
         metadataNet.fileNamePrint = metadataNet.fileNamePrint;
         metadataNet.fileNameTo = metadata.fileName;
         metadataNet.etag = metadata.etag;
         metadataNet.selector = selectorMove;
-        metadataNet.serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
+        metadataNet.serverUrl = serverUrl;
         metadataNet.serverUrlTo = serverUrlTo;
             
         [_queueSelector addObject:metadataNet.selector];
@@ -2362,10 +2386,10 @@
         metadataNet.directory = metadata.directory;
         metadataNet.fileID = metadata.fileID;
         metadataNet.directoryID = metadata.directoryID;
-        metadataNet.directoryIDTo = [[NCManageDatabase sharedInstance] getDirectoryID:serverUrlTo];
+        metadataNet.directoryIDTo = directoryIDTo;
         metadataNet.fileNamePrint = metadata.fileNamePrint;
         metadataNet.etag = metadata.etag;
-        metadataNet.serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
+        metadataNet.serverUrl = serverUrl;
         metadataNet.serverUrlTo = serverUrlTo;
             
         // data
@@ -2469,7 +2493,7 @@
         metadata.date = metadataNet.date;
         metadata.permissions = @"RDNVCK";
 
-        (void)[[NCManageDatabase sharedInstance] addMetadata:metadata activeUrl:app.activeUrl serverUrl:_serverUrl];
+        (void)[[NCManageDatabase sharedInstance] addMetadata:metadata];
         
         [self reloadDatasource];
     }
@@ -2485,8 +2509,11 @@
     if (autoUploadDirectory) metadataNet.serverUrl = [[NCManageDatabase sharedInstance] getAccountAutoUploadDirectory:app.activeUrl];
     else  metadataNet.serverUrl = _serverUrl;
     
+    NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:_serverUrl];
+    if (!directoryID) return;
+    
     metadataNet.action = actionCreateFolder;
-    metadataNet.directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:_serverUrl];
+    metadataNet.directoryID = directoryID;
     if (autoUploadDirectory)
         metadataNet.options = @"folderAutoUpload";
     metadataNet.fileID = [[NSUUID UUID] UUIDString];
@@ -2498,7 +2525,7 @@
         
     // Create Directory on metadata
     tableMetadata *metadata = [CCUtility createMetadataWithAccount:app.activeAccount date:[NSDate date] directory:YES fileID:metadataNet.fileID directoryID:metadataNet.directoryID fileName:metadataNet.fileName etag:@"" size:0 status:k_metadataStatusNormal];
-    (void)[[NCManageDatabase sharedInstance] addMetadata:metadata activeUrl:app.activeUrl serverUrl:_serverUrl];
+    (void)[[NCManageDatabase sharedInstance] addMetadata:metadata];
     
     [[NCManageDatabase sharedInstance] clearDateReadWithServerUrl:_serverUrl directoryID:nil];
     [self reloadDatasource];
@@ -2550,6 +2577,7 @@
 - (void)encyptedDecryptedFolder
 {
     NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:_metadata.directoryID];
+    if (!serverUrl) return;
     
     if (_metadata.cryptated) {
         
@@ -2643,7 +2671,8 @@
             
             NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
             
-            [[CCNetworking sharedNetworking] downloadFile:metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorEncryptFile selectorPost:nil session:k_download_session taskStatus: k_taskStatusResume delegate:self];
+            if(serverUrl)
+                [[CCNetworking sharedNetworking] downloadFile:metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorEncryptFile selectorPost:nil session:k_download_session taskStatus: k_taskStatusResume delegate:self];
         }
     }
     
@@ -2669,7 +2698,8 @@
             
             NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
             
-            [[CCNetworking sharedNetworking] downloadFile:metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorDecryptFile selectorPost:nil session:k_download_session taskStatus: k_taskStatusResume delegate:self];
+            if (serverUrl)
+                [[CCNetworking sharedNetworking] downloadFile:metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorDecryptFile selectorPost:nil session:k_download_session taskStatus: k_taskStatusResume delegate:self];
         }
     }
     
@@ -2685,7 +2715,8 @@
     
     NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:_metadata.directoryID];
     
-    [[CCNetworking sharedNetworking] downloadFile:_metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selector selectorPost:nil session:k_download_session taskStatus:k_taskStatusResume delegate:self];
+    if (serverUrl)
+        [[CCNetworking sharedNetworking] downloadFile:_metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selector selectorPost:nil session:k_download_session taskStatus:k_taskStatusResume delegate:self];
 }
 
 - (void)encryptedFile:(tableMetadata *)metadata
@@ -2693,11 +2724,10 @@
     NSString *fileNameFrom = [NSString stringWithFormat:@"%@/%@", app.directoryUser, metadata.fileID];
     NSString *fileNameTo = [NSString stringWithFormat:@"%@/%@", app.directoryUser, metadata.fileNamePrint];
     [[NSFileManager defaultManager] copyItemAtPath:fileNameFrom toPath:fileNameTo error:nil];
+    NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
     
-    if ([[NSFileManager defaultManager] fileExistsAtPath:fileNameTo]) {
+    if ([[NSFileManager defaultManager] fileExistsAtPath:fileNameTo] && serverUrl) {
         
-        NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
-                
         dispatch_async(dispatch_get_main_queue(), ^{
             [[CCNetworking sharedNetworking] uploadFile:metadata.fileName serverUrl:serverUrl cryptated:YES onlyPlist:NO session:k_upload_session taskStatus:k_taskStatusResume selector:nil selectorPost:nil errorCode:0 delegate:nil];
             [self performSelector:@selector(reloadDatasource) withObject:nil];
@@ -2713,12 +2743,11 @@
 {
     NSString *fileNameFrom = [NSString stringWithFormat:@"%@/%@", app.directoryUser, metadata.fileID];
     NSString *fileNameTo = [NSString stringWithFormat:@"%@/%@", app.directoryUser, metadata.fileNamePrint];
-        
+    NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
+    
     [[NSFileManager defaultManager] copyItemAtPath:fileNameFrom toPath:fileNameTo error:nil];
     
-    if ([[NSFileManager defaultManager] fileExistsAtPath:fileNameTo]) {
-        
-        NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
+    if ([[NSFileManager defaultManager] fileExistsAtPath:fileNameTo] && serverUrl) {
         
         dispatch_async(dispatch_get_main_queue(), ^{
             [[CCNetworking sharedNetworking] uploadFile:metadata.fileNamePrint serverUrl:serverUrl cryptated:NO onlyPlist:NO session:k_upload_session taskStatus:k_taskStatusResume selector:nil selectorPost:nil errorCode:0 delegate:nil];
@@ -2750,7 +2779,7 @@
         [self.navigationController setCCProgressPercentage:progress*100 andTintColor: [NCBrandColor sharedInstance].navigationBarProgress];
     
     // Check
-    if (!fileID)
+    if (!fileID || [fileID isEqualToString: @""])
         return;
     
     [app.listProgressMetadata setObject:[NSNumber numberWithFloat:progress] forKey:fileID];
@@ -3141,6 +3170,9 @@
 
 - (void)openWindowShare:(tableMetadata *)metadata
 {
+    NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
+    if (!serverUrl) return;
+    
     CCMetadataNet *metadataNet = [[CCMetadataNet alloc] initWithAccount:app.activeAccount];
     
     metadataNet.action = actionReadShareServer;
@@ -3148,7 +3180,7 @@
     metadataNet.fileName = metadata.fileName;
     metadataNet.fileNamePrint = metadata.fileNamePrint;
     metadataNet.selector = selectorOpenWindowShare;
-    metadataNet.serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
+    metadataNet.serverUrl = serverUrl;
     
     [app addNetworkingOperationQueue:app.netQueue delegate:self metadataNet:metadataNet];
     
@@ -3224,7 +3256,8 @@
     
         NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
         
-        [[CCNetworking sharedNetworking] downloadFile:metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorAddFavorite selectorPost:nil session:k_download_session taskStatus:k_taskStatusResume delegate:self];
+        if (serverUrl)
+            [[CCNetworking sharedNetworking] downloadFile:metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorAddFavorite selectorPost:nil session:k_download_session taskStatus:k_taskStatusResume delegate:self];
     }
 }
 
@@ -3233,32 +3266,6 @@
     [[CCActions sharedInstance] settingFavorite:metadata favorite:NO delegate:self];
 }
 
-#pragma --------------------------------------------------------------------------------------------
-#pragma mark ===== Local =====
-#pragma --------------------------------------------------------------------------------------------
-
-- (void)addLocal:(tableMetadata *)metadata
-{
-    if (metadata.errorPasscode || !metadata.uuid) return;
-    
-    NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
-
-    if ([metadata.type isEqualToString: k_metadataType_file])
-        [[CCNetworking sharedNetworking] downloadFile:metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorAddLocal selectorPost:nil session:k_download_session taskStatus:k_taskStatusResume delegate:self];
-    
-    if ([metadata.type isEqualToString: k_metadataType_template]) {
-        
-        [CCUtility copyFileAtPath:[NSString stringWithFormat:@"%@/%@", app.directoryUser, metadata.fileName] toPath:[NSString stringWithFormat:@"%@/%@", [CCUtility getDirectoryLocal], metadata.fileName]];
-        
-        [app messageNotification:@"_add_local_" description:@"_file_saved_local_" visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeSuccess errorCode:0];
-    }
-    
-    NSIndexPath *indexPath = [_sectionDataSource.fileIDIndexPath objectForKey:metadata.fileID];
-    
-    if ([self indexPathIsValid:indexPath])
-        [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationAutomatic];
-}
-
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark ===== Open in... =====
 #pragma --------------------------------------------------------------------------------------------
@@ -3266,6 +3273,7 @@
 - (void)openIn:(tableMetadata *)metadata
 {
     NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
+    if (!serverUrl) return;
 
     [[CCNetworking sharedNetworking] downloadFile:metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorOpenIn selectorPost:nil session:k_download_session taskStatus:k_taskStatusResume delegate:self];
     
@@ -3281,7 +3289,8 @@
 - (void)removeLocalFile:(tableMetadata *)metadata
 {
     NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:_metadata.directoryID];
-    
+    if (!serverUrl) return;
+
     [[NCManageDatabase sharedInstance] deleteLocalFileWithPredicate:[NSPredicate predicateWithFormat:@"fileID = %@", metadata.fileID]];
     
     [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/%@", app.directoryUser, metadata.fileID] error:nil];
@@ -3877,19 +3886,25 @@
             NSData *dataFileID = [dic objectForKey: k_metadataKeyedUnarchiver];
             NSString *fileID = [NSKeyedUnarchiver unarchiveObjectWithData:dataFileID];
 
-            tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"fileID = %@", fileID]];
+            if (fileID) {
+            
+                tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"fileID = %@", fileID]];
             
-            if (metadata) {
+                if (metadata) {
             
-                tableAccount *account = [[NCManageDatabase sharedInstance] getAccountWithPredicate:[NSPredicate predicateWithFormat:@"account = %@", metadata.account]];
+                    tableAccount *account = [[NCManageDatabase sharedInstance] getAccountWithPredicate:[NSPredicate predicateWithFormat:@"account = %@", metadata.account]];
 
-                if (account) {
+                    if (account) {
                 
-                    NSString *directoryUser = [CCUtility getDirectoryActiveUser:account.user activeUrl:account.url];
+                        NSString *directoryUser = [CCUtility getDirectoryActiveUser:account.user activeUrl:account.url];
             
-                    if (directoryUser) {
-                        if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/%@", directoryUser, fileID]]) {
-                            isValid = YES;
+                        if (directoryUser) {
+                            if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/%@", directoryUser, fileID]]) {
+                                isValid = YES;
+                            } else {
+                                isValid = NO;
+                                break;
+                            }
                         } else {
                             isValid = NO;
                             break;
@@ -3930,7 +3945,8 @@
         
         NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:_metadata.directoryID];
         
-        [[CCNetworking sharedNetworking] downloadFile:_metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorLoadCopy selectorPost:nil session:k_download_session taskStatus:k_taskStatusResume delegate:self];
+        if (serverUrl)
+            [[CCNetworking sharedNetworking] downloadFile:_metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorLoadCopy selectorPost:nil session:k_download_session taskStatus:k_taskStatusResume delegate:self];
     }
 }
 
@@ -3952,7 +3968,8 @@
 
             NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:_metadata.directoryID];
 
-            [[CCNetworking sharedNetworking] downloadFile:metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorLoadCopy selectorPost:nil session:k_download_session taskStatus:k_taskStatusResume delegate:self];
+            if (serverUrl)
+                [[CCNetworking sharedNetworking] downloadFile:metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorLoadCopy selectorPost:nil session:k_download_session taskStatus:k_taskStatusResume delegate:self];
         }
     }
     
@@ -4131,6 +4148,7 @@
 - (void)comandoLockPassword
 {
     NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:_metadata.directoryID];
+    if (!serverUrl) return;
     NSString *lockServerUrl = [CCUtility stringAppendServerUrl:serverUrl addFileName:_metadata.fileNameData];
 
     // se non è abilitato il Lock Passcode esci
@@ -4247,6 +4265,7 @@
 {
     // Directory locked ?
     NSString *lockServerUrl = [CCUtility stringAppendServerUrl:[[NCManageDatabase sharedInstance] getServerUrl:_metadata.directoryID] addFileName:_metadata.fileNameData];
+    if (!lockServerUrl) return;
     
     tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", app.activeAccount, lockServerUrl]];
     
@@ -4278,6 +4297,7 @@
 - (void)swipeMore:(NSIndexPath *)indexPath
 {
     NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:_metadata.directoryID];
+    if (!serverUrl) return;
     
     NSString *titoloCriptaDecripta, *titoloLock, *titleFavorite;
     
@@ -4688,7 +4708,7 @@
 - (void)reloadDatasource:(NSString *)serverUrl
 {
     // test
-    if (app.activeAccount.length == 0 || serverUrl.length == 0)
+    if (app.activeAccount.length == 0 || serverUrl.length == 0 || serverUrl == nil)
         return;
     
     // Search Mode
@@ -4752,10 +4772,15 @@
         if ([sorted isEqualToString:@"fileName"])
             sorted = @"fileNamePrint";
     
-        NSArray *recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND directoryID = %@ AND status = %i", app.activeAccount, [[NCManageDatabase sharedInstance] getDirectoryID:serverUrl], k_metadataStatusNormal] sorted:sorted ascending:[CCUtility getAscendingSettings]];
+        NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:serverUrl];
+        
+        if (directoryID) {
         
-        _sectionDataSource = [CCSectionDataSourceMetadata new];
-        _sectionDataSource = [CCSectionMetadata creataDataSourseSectionMetadata:recordsTableMetadata listProgressMetadata:nil groupByField:_directoryGroupBy replaceDateToExifDate:NO activeAccount:app.activeAccount];
+            NSArray *recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND directoryID = %@ AND status = %i", app.activeAccount, directoryID, k_metadataStatusNormal] sorted:sorted ascending:[CCUtility getAscendingSettings]];
+        
+            _sectionDataSource = [CCSectionDataSourceMetadata new];
+            _sectionDataSource = [CCSectionMetadata creataDataSourseSectionMetadata:recordsTableMetadata listProgressMetadata:nil groupByField:_directoryGroupBy replaceDateToExifDate:NO activeAccount:app.activeAccount];
+        }
         
     } else {
         
@@ -5049,6 +5074,8 @@
     }
     
     NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
+    if (!serverUrl)
+        return [tableView dequeueReusableCellWithIdentifier:@"CellMainTransfer"];
     
     if ([metadata.session isEqualToString:@""] || metadata.session == nil) typeCell = @"CellMain";
     else typeCell = @"CellMainTransfer";
@@ -5521,6 +5548,9 @@
     // settiamo il record file.
     _metadata = [self getMetadataFromSectionDataSource:indexPath];
     
+    if (!_metadata)
+        return;
+    
     // se non può essere selezionata deseleziona
     if ([cell isEditing] == NO)
         [tableView deselectRowAtIndexPath:indexPath animated:YES];
@@ -5533,11 +5563,8 @@
         return;
     }
     
-    // test crash
-    NSArray *metadatas = [_sectionDataSource.sectionArrayRow objectForKey:[_sectionDataSource.sections objectAtIndex:indexPath.section]];
-    if (indexPath.row >= [metadatas count]) return;
-    
     NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:_metadata.directoryID];
+    if (!serverUrl) return;
     
     // se è in corso una sessione
     if ([_metadata.session length] > 0) return;
@@ -5718,73 +5745,78 @@
 // can i go to next viewcontroller
 - (void)performSegueDirectoryWithControlPasscode:(BOOL)controlPasscode
 {
-    NSString *nomeDir;
+    @synchronized (self) {
+        
+        NSString *nomeDir;
 
-    if(self.tableView.editing == NO && _metadata.errorPasscode == NO){
+        if(self.tableView.editing == NO && _metadata.errorPasscode == NO){
         
-        NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:_metadata.directoryID];
-        NSString *lockServerUrl = [CCUtility stringAppendServerUrl:serverUrl addFileName:_metadata.fileNameData];
+            NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:_metadata.directoryID];
+            if (!serverUrl) return;
         
-        tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", app.activeAccount, lockServerUrl]];
+            NSString *lockServerUrl = [CCUtility stringAppendServerUrl:serverUrl addFileName:_metadata.fileNameData];
         
-        // SE siamo in presenza di una directory bloccata E è attivo il block E la sessione password Lock è senza data ALLORA chiediamo la password per procedere
-        if (directory.lock && [[CCUtility getBlockCode] length] && app.sessionePasscodeLock == nil && controlPasscode) {
+            tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", app.activeAccount, lockServerUrl]];
+        
+            // SE siamo in presenza di una directory bloccata E è attivo il block E la sessione password Lock è senza data ALLORA chiediamo la password per procedere
+            if (directory.lock && [[CCUtility getBlockCode] length] && app.sessionePasscodeLock == nil && controlPasscode) {
             
-            CCBKPasscode *viewController = [[CCBKPasscode alloc] initWithNibName:nil bundle:nil];
-            viewController.delegate = self;
-            viewController.fromType = CCBKPasscodeFromLockDirectory;
-            viewController.type = BKPasscodeViewControllerCheckPasscodeType;
-            viewController.inputViewTitlePassword = YES;
+                CCBKPasscode *viewController = [[CCBKPasscode alloc] initWithNibName:nil bundle:nil];
+                viewController.delegate = self;
+                viewController.fromType = CCBKPasscodeFromLockDirectory;
+                viewController.type = BKPasscodeViewControllerCheckPasscodeType;
+                viewController.inputViewTitlePassword = YES;
             
-            if ([CCUtility getSimplyBlockCode]) {
+                if ([CCUtility getSimplyBlockCode]) {
                 
-                viewController.passcodeStyle = BKPasscodeInputViewNumericPasscodeStyle;
-                viewController.passcodeInputView.maximumLength = 6;
+                    viewController.passcodeStyle = BKPasscodeInputViewNumericPasscodeStyle;
+                    viewController.passcodeInputView.maximumLength = 6;
                 
-            } else {
+                } else {
                 
-                viewController.passcodeStyle = BKPasscodeInputViewNormalPasscodeStyle;
-                viewController.passcodeInputView.maximumLength = 64;
-            }
+                    viewController.passcodeStyle = BKPasscodeInputViewNormalPasscodeStyle;
+                    viewController.passcodeInputView.maximumLength = 64;
+                }
 
-            BKTouchIDManager *touchIDManager = [[BKTouchIDManager alloc] initWithKeychainServiceName:k_serviceShareKeyChain];
-            touchIDManager.promptText = NSLocalizedString(@"_scan_fingerprint_", nil);
-            viewController.touchIDManager = touchIDManager;
+                BKTouchIDManager *touchIDManager = [[BKTouchIDManager alloc] initWithKeychainServiceName:k_serviceShareKeyChain];
+                touchIDManager.promptText = NSLocalizedString(@"_scan_fingerprint_", nil);
+                viewController.touchIDManager = touchIDManager;
             
-            viewController.title = NSLocalizedString(@"_folder_blocked_", nil); 
-            viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(passcodeViewCloseButtonPressed:)];
-            viewController.navigationItem.leftBarButtonItem.tintColor = [NCBrandColor sharedInstance].cryptocloud;
+                viewController.title = NSLocalizedString(@"_folder_blocked_", nil);
+                viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(passcodeViewCloseButtonPressed:)];
+                viewController.navigationItem.leftBarButtonItem.tintColor = [NCBrandColor sharedInstance].cryptocloud;
             
-            UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
-            [self presentViewController:navController animated:YES completion:nil];
+                UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
+                [self presentViewController:navController animated:YES completion:nil];
             
-            return;
-        }
+                return;
+            }
         
-        if (_metadata.cryptated) nomeDir = [_metadata.fileName substringToIndex:[_metadata.fileName length]-6];
-        else nomeDir = _metadata.fileName;
+            if (_metadata.cryptated) nomeDir = [_metadata.fileName substringToIndex:[_metadata.fileName length]-6];
+            else nomeDir = _metadata.fileName;
         
-        NSString *serverUrlPush = [CCUtility stringAppendServerUrl:serverUrl addFileName:nomeDir];
+            NSString *serverUrlPush = [CCUtility stringAppendServerUrl:serverUrl addFileName:nomeDir];
         
-        CCMain *viewController = [app.listMainVC objectForKey:serverUrlPush];
+            CCMain *viewController = [app.listMainVC objectForKey:serverUrlPush];
         
-        if (viewController.isViewLoaded == false || viewController == nil) {
+            if (viewController.isViewLoaded == false || viewController == nil) {
             
-            viewController = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"CCMainVC"];
+                viewController = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"CCMainVC"];
             
-            viewController.isFolderEncrypted = _metadata.cryptated;
-            viewController.serverUrl = serverUrlPush;
-            viewController.titleMain = _metadata.fileNamePrint;
-            viewController.textBackButton = _titleMain;
+                viewController.isFolderEncrypted = _metadata.cryptated;
+                viewController.serverUrl = serverUrlPush;
+                viewController.titleMain = _metadata.fileNamePrint;
+                viewController.textBackButton = _titleMain;
             
-            // save self
-            [app.listMainVC setObject:viewController forKey:serverUrlPush];
-        }
+                // save self
+                [app.listMainVC setObject:viewController forKey:serverUrlPush];
+            }
         
-        // OFF SearchBar
-        [viewController cancelSearchBar];
+            // OFF SearchBar
+            [viewController cancelSearchBar];
         
-        [self.navigationController pushViewController:viewController animated:YES];
+            [self.navigationController pushViewController:viewController animated:YES];
+        }
     }
 }
 

+ 21 - 33
iOSClient/Main/CCMore.swift

@@ -175,14 +175,12 @@ class CCMore: UIViewController, UITableViewDelegate, UITableViewDataSource, CCLo
     
     func changeTheming() {
         
-        // Theming Background
-        let theminBackgroundFile = UIImage.init(contentsOfFile: "\(appDelegate.directoryUser!)/themingBackground.png")
-        if (theminBackgroundFile != nil) {
+        if let theminBackgroundFile = UIImage.init(contentsOfFile: "\(appDelegate.directoryUser!)/themingBackground.png") {
             themingBackground.image = theminBackgroundFile
         } else {
             themingBackground.image = UIImage.init(named: "themingBackground")
         }
-
+        
         if (self.isViewLoaded && (self.view.window != nil)) {
             appDelegate.changeTheming(self)
         }
@@ -190,44 +188,34 @@ class CCMore: UIViewController, UITableViewDelegate, UITableViewDataSource, CCLo
     
     func changeUserProfile() {
      
-        let themingAvatarFile : UIImage? = UIImage.init(contentsOfFile: "\(appDelegate.directoryUser!)/avatar.png")
-        
-        if (themingAvatarFile != nil) {
-            
+        if let themingAvatarFile = UIImage.init(contentsOfFile: "\(appDelegate.directoryUser!)/avatar.png") {
             themingAvatar.image = themingAvatarFile
-            
         } else {
-            
             themingAvatar.image = UIImage.init(named: "moreAvatar")
         }
         
         // Display Name user & Quota
-        tabAccount = NCManageDatabase.sharedInstance.getAccountActive()
-        if (tabAccount != nil) {
-            
-            if let displayName = tabAccount?.displayName {
-                if displayName.isEmpty {
-                    labelUsername.text = tabAccount!.user
-                }
-                else{
-                    labelUsername.text = tabAccount!.displayName
-                }
-            }
-            else{
-                labelUsername.text = tabAccount!.user
-            }
-            
-            // fix CCMore.swift line 208 Version 2.17.2 (00005)
-            if (tabAccount?.quotaRelative != nil && tabAccount?.quotaTotal != nil && tabAccount?.quotaUsed != nil) {
+        guard let tabAccount = NCManageDatabase.sharedInstance.getAccountActive() else {
+            return
+        }
+        
+        if tabAccount.displayName.isEmpty {
+            labelUsername.text = tabAccount.user
+        }
+        else{
+            labelUsername.text = tabAccount.displayName
+        }
+        
+        // fix CCMore.swift line 208 Version 2.17.2 (00005)
+        if (tabAccount.quotaRelative != 0 && tabAccount.quotaTotal != 0 && tabAccount.quotaUsed != 0) {
                 
-                progressQuota.progress = Float((tabAccount?.quotaRelative)!) / 100
-                progressQuota.progressTintColor = NCBrandColor.sharedInstance.brand
+            progressQuota.progress = Float(tabAccount.quotaRelative) / 100
+            progressQuota.progressTintColor = NCBrandColor.sharedInstance.brand
                 
-                let quota : String = CCUtility.transformedSize(Double((tabAccount?.quotaTotal)!))
-                let quotaUsed : String = CCUtility.transformedSize(Double((tabAccount?.quotaUsed)!))
+            let quota : String = CCUtility.transformedSize(Double(tabAccount.quotaTotal))
+            let quotaUsed : String = CCUtility.transformedSize(Double(tabAccount.quotaUsed))
                 
-                labelQuota.text = String.localizedStringWithFormat(NSLocalizedString("_quota_using_", comment: ""), quotaUsed, quota)
-            }
+            labelQuota.text = String.localizedStringWithFormat(NSLocalizedString("_quota_using_", comment: ""), quotaUsed, quota)
         }
     }
     

+ 9 - 1
iOSClient/Move/CCMove.m

@@ -276,9 +276,13 @@
 {
     if ([selector isEqualToString:selectorLoadPlist]) {
 
+        NSString *autoUploadFileName = [[NCManageDatabase sharedInstance] getAccountAutoUploadFileName];
+        NSString *autoUploadDirectory = [[NCManageDatabase sharedInstance] getAccountAutoUploadDirectory:activeUrl];
+        
         tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"fileID = %@", fileID]];
         
         metadata = [CCUtility insertInformationPlist:metadata directoryUser:directoryUser];
+        metadata = [CCUtility insertTypeFileIconName:metadata serverUrl:serverUrl autoUploadFileName:autoUploadFileName autoUploadDirectory:autoUploadDirectory];
         metadata = [[NCManageDatabase sharedInstance] updateMetadata:metadata activeUrl:activeUrl];
         
         // se è un template aggiorniamo anche nel FileSystem
@@ -381,7 +385,7 @@
     }
 
     // insert in Database
-    metadatas = [[NCManageDatabase sharedInstance] addMetadatas:metadatasToInsertInDB activeUrl:activeUrl serverUrl:metadataNet.serverUrl];
+    metadatas = [[NCManageDatabase sharedInstance] addMetadatas:metadatasToInsertInDB serverUrl:metadataNet.serverUrl];
 
     // Plist MULTI THREAD
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
@@ -472,6 +476,7 @@
 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 {
     NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:_serverUrl];
+    if (!directoryID) return 0;
     NSPredicate *predicate;
     
     if (self.onlyClearDirectory) predicate = [NSPredicate predicateWithFormat:@"account = %@ AND directoryID = %@ AND directory = true AND cryptated = false", activeAccount, directoryID];
@@ -497,6 +502,8 @@
     }
     
     NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:_serverUrl];
+    if (!directoryID)
+        return cell;
     
     if (self.onlyClearDirectory) predicate = [NSPredicate predicateWithFormat:@"account = %@ AND directoryID = %@ AND directory = true AND cryptated = false", activeAccount, directoryID];
     else predicate = [NSPredicate predicateWithFormat:@"account = %@ AND directoryID = %@ AND directory = true", activeAccount, directoryID];
@@ -531,6 +538,7 @@
 
     NSIndexPath *index = [self.tableView indexPathForSelectedRow];
     NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:_serverUrl];
+    if (!directoryID) return;
     
     if (self.onlyClearDirectory) predicate = [NSPredicate predicateWithFormat:@"account = %@ AND directoryID = %@ AND directory = true AND cryptated = false", activeAccount, directoryID];
     else predicate = [NSPredicate predicateWithFormat:@"account = %@ AND directoryID == %@ AND directory = true", activeAccount, directoryID];

+ 2 - 1
iOSClient/Networking/CCNetworking.h

@@ -61,7 +61,8 @@
 - (void)downloadFile:(NSString *)fileID serverUrl:(NSString *)serverUrl downloadData:(BOOL)downloadData downloadPlist:(BOOL)downloadPlist selector:(NSString *)selector selectorPost:(NSString *)selectorPost session:(NSString *)session taskStatus:(NSInteger)taskStatus delegate:(id)delegate;
 
 // Upload
-- (void)uploadFileFromAssetLocalIdentifier:(NSString *)assetLocalIdentifier fileName:(NSString *)fileName serverUrl:(NSString *)serverUrl cryptated:(BOOL)cryptated session:(NSString *)session taskStatus:(NSInteger)taskStatus selector:(NSString *)selector selectorPost:(NSString *)selectorPost errorCode:(NSInteger)errorCode delegate:(id)delegate;
+- (void)uploadFileFromAssetLocalIdentifier:(CCMetadataNet *)metadataNet delegate:(id)delegate;
+
 - (void)uploadFile:(NSString *)fileName serverUrl:(NSString *)serverUrl cryptated:(BOOL)cryptated onlyPlist:(BOOL)onlyPlist session:(NSString *)session taskStatus:(NSInteger)taskStatus selector:(NSString *)selector selectorPost:(NSString *)selectorPost errorCode:(NSInteger)errorCode delegate:(id)delegate;
 - (void)uploadTemplate:(NSString *)fileNamePrint fileNameCrypto:(NSString *)fileNameCrypto serverUrl:(NSString *)serverUrl session:(NSString *)session taskStatus:(NSInteger)taskStatus selector:(NSString *)selector selectorPost:(NSString *)selectorPost errorCode:(NSInteger)errorCode delegate:(id)delegate;
 - (void)uploadFileMetadata:(tableMetadata *)metadata taskStatus:(NSInteger)taskStatus;

+ 164 - 137
iOSClient/Networking/CCNetworking.m

@@ -372,9 +372,15 @@
 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
 {
     NSString *url = [[[task currentRequest].URL absoluteString] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+    
+    if (!url)
+        return;
+    
     NSString *fileName = [url lastPathComponent];
     NSString *serverUrl = [self getServerUrlFromUrl:url];
+    if (!serverUrl) return;
     NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:serverUrl];
+    if (!directoryID) return;
     tableMetadata *metadata;
     
     NSInteger errorCode;
@@ -466,8 +472,12 @@
                 etag = [CCUtility removeForbiddenCharactersFileSystem:[fields objectForKey:@"OC-ETag"]];
             
                 NSString *dateString = [fields objectForKey:@"Date"];
-                if (![dateFormatter getObjectValue:&date forString:dateString range:nil error:&error]) {
-                    NSLog(@"Date '%@' could not be parsed: %@", dateString, error);
+                if (dateString) {
+                    if (![dateFormatter getObjectValue:&date forString:dateString range:nil error:&error]) {
+                        NSLog(@"Date '%@' could not be parsed: %@", dateString, error);
+                        date = [NSDate date];
+                    }
+                } else {
                     date = [NSDate date];
                 }
             }
@@ -645,6 +655,9 @@
     NSString *url = [[[downloadTask currentRequest].URL absoluteString] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
     NSString *fileName = [url lastPathComponent];
     NSString *serverUrl = [self getServerUrlFromUrl:url];
+    if (!serverUrl) return;
+    NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:serverUrl];
+    if (!directoryID) return;
     
     // if plist return
     if ([CCUtility getTypeFileName:fileName] == k_metadataTypeFilenamePlist)
@@ -652,7 +665,7 @@
 
     float progress = (float) totalBytesWritten / (float)totalBytesExpectedToWrite;
     
-    tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataFromFileName:fileName directoryID:[[NCManageDatabase sharedInstance] getDirectoryID:serverUrl]];
+    tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataFromFileName:fileName directoryID:directoryID];
     
     if (metadata) {
         
@@ -669,6 +682,7 @@
     NSURLRequest *url = [downloadTask currentRequest];
     NSString *fileName = [[url.URL absoluteString] lastPathComponent];
     NSString *serverUrl = [self getServerUrlFromUrl:[url.URL absoluteString]];
+    if (!serverUrl) return;
     
     tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"session = %@ AND (sessionTaskIdentifier = %i OR sessionTaskIdentifierPlist = %i)",session.sessionDescription, downloadTask.taskIdentifier, downloadTask.taskIdentifier]];
     
@@ -774,8 +788,15 @@
             // Fix Main Thread for insertInformationPlist
             if([selector isEqualToString:selectorLoadPlist] || [selector isEqualToString:selectorLoadModelView]) {
                 dispatch_async(dispatch_get_main_queue(), ^{
-                    if([selector isEqualToString:selectorLoadPlist] || [selector isEqualToString:selectorLoadModelView])
+                    if([selector isEqualToString:selectorLoadPlist] || [selector isEqualToString:selectorLoadModelView]) {
+                        
+                        NSString *autoUploadFileName = [[NCManageDatabase sharedInstance] getAccountAutoUploadFileName];
+                        NSString *autoUploadDirectory = [[NCManageDatabase sharedInstance] getAccountAutoUploadDirectory:_activeUrl];
+                        
                         metadata = [CCUtility insertInformationPlist:metadata directoryUser:_directoryUser];
+                        metadata = [CCUtility insertTypeFileIconName:metadata serverUrl:serverUrl autoUploadFileName:autoUploadFileName autoUploadDirectory:autoUploadDirectory];
+
+                    }
                     metadata = [[NCManageDatabase sharedInstance] updateMetadata:metadata activeUrl:_activeUrl];
                 });
             } else {
@@ -823,131 +844,110 @@
 #pragma mark =====  Upload =====
 #pragma --------------------------------------------------------------------------------------------
 
-- (void)uploadFileFromAssetLocalIdentifier:(NSString *)assetLocalIdentifier fileName:(NSString *)fileName serverUrl:(NSString *)serverUrl cryptated:(BOOL)cryptated session:(NSString *)session taskStatus:(NSInteger)taskStatus selector:(NSString *)selector selectorPost:(NSString *)selectorPost errorCode:(NSInteger)errorCode delegate:(id)delegate
+- (void)uploadFileFromAssetLocalIdentifier:(CCMetadataNet *)metadataNet delegate:(id)delegate
 {
     //delegate
     if (delegate == nil)
         delegate = self.delegate;
     
-    PHFetchResult *result = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetLocalIdentifier] options:nil];
+    PHFetchResult *result = [PHAsset fetchAssetsWithLocalIdentifiers:@[metadataNet.assetLocalIdentifier] options:nil];
     
     if (!result.count) {
         
-        [[NCManageDatabase sharedInstance] addActivityClient:fileName fileID:assetLocalIdentifier action:k_activityDebugActionUpload selector:selector note:@"Internal error image/video not found" type:k_activityTypeFailure verbose:k_activityVerboseHigh activeUrl:_activeUrl];
+        // Delete record on Table Auto Upload
+        if ([metadataNet.selector isEqualToString:selectorUploadAutoUpload] || [metadataNet.selector isEqualToString:selectorUploadAutoUploadAll])
+            [[NCManageDatabase sharedInstance] deleteQueueUploadWithAssetLocalIdentifier:metadataNet.assetLocalIdentifier selector:metadataNet.selector];
+
+        [[NCManageDatabase sharedInstance] addActivityClient:metadataNet.fileName fileID:metadataNet.assetLocalIdentifier action:k_activityDebugActionUpload selector:metadataNet.selector note:@"Error photo/video not found, remove from upload" type:k_activityTypeFailure verbose:k_activityVerboseHigh activeUrl:_activeUrl];
         
         if ([delegate respondsToSelector:@selector(uploadFileFailure:fileID:serverUrl:selector:message:errorCode:)])
-            [delegate uploadFileFailure:nil fileID:nil serverUrl:serverUrl selector:selector message:@"Internal error image/video not found" errorCode: k_CCErrorInternalError];
+            [delegate uploadFileFailure:metadataNet fileID:nil serverUrl:metadataNet.serverUrl selector:metadataNet.selector message:@"Error photo/video not found, remove from upload" errorCode: k_CCErrorInternalError];
         
         return;
     }
     
-    PHAsset *assetResult = result[0];
-    PHAssetMediaType assetMediaType = assetResult.mediaType;
+    @synchronized (self) {
+    
+        PHAsset *assetResult = result[0];
+        PHAssetMediaType assetMediaType = assetResult.mediaType;
     
-    // IMAGE
-    if (assetMediaType == PHAssetMediaTypeImage) {
+        // IMAGE
+        if (assetMediaType == PHAssetMediaTypeImage) {
         
-        __block PHAsset *asset = result[0];
-        __block NSError *error = nil;
+            __block PHAsset *asset = result[0];
+            __block NSError *error = nil;
             
-        PHImageRequestOptions *options = [PHImageRequestOptions new];
-        options.networkAccessAllowed = YES; // iCloud
+            PHImageRequestOptions *options = [PHImageRequestOptions new];
+            options.networkAccessAllowed = YES; // iCloud
             
-        [[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
+            [[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
                 
-            [imageData writeToFile:[NSString stringWithFormat:@"%@/%@", _directoryUser, fileName] options:NSDataWritingAtomic error:&error];
+                [imageData writeToFile:[NSString stringWithFormat:@"%@/%@", _directoryUser, metadataNet.fileName] options:NSDataWritingAtomic error:&error];
                 
-            if (error) {
-                    
-                // Delete record on Table Auto Upload
-                if ([selector isEqualToString:selectorUploadAutoUpload] || [selector isEqualToString:selectorUploadAutoUploadAll])
-                    [[NCManageDatabase sharedInstance] deleteQueueUploadWithAssetLocalIdentifier:assetLocalIdentifier selector:selector];
-                    
-                // Activity
-                [[NCManageDatabase sharedInstance] addActivityClient:fileName fileID:assetLocalIdentifier action:k_activityDebugActionUpload selector:selector note:[NSString stringWithFormat:@"%@ [%@]",NSLocalizedString(@"_read_file_error_", nil), error.description] type:k_activityTypeFailure verbose:k_activityVerboseDefault  activeUrl:_activeUrl];
-                    
-                // Error for uploadFileFailure
-                dispatch_async(dispatch_get_main_queue(), ^{
-                    if ([delegate respondsToSelector:@selector(uploadFileFailure:fileID:serverUrl:selector:message:errorCode:)])
-                        [delegate uploadFileFailure:nil fileID:nil serverUrl:serverUrl selector:selector message:[NSString stringWithFormat:@"%@ [%@]",NSLocalizedString(@"_read_file_error_", nil), error.description] errorCode:error.code];
-                });
-                    
-            } else {
+                if (error) {
+                
+                    dispatch_async(dispatch_get_main_queue(), ^{
+                        if ([delegate respondsToSelector:@selector(uploadFileFailure:fileID:serverUrl:selector:message:errorCode:)])
+                            [delegate uploadFileFailure:metadataNet fileID:nil serverUrl:metadataNet.serverUrl selector:metadataNet.selector message:[NSString stringWithFormat:@"Image request failed [%@]", error.description] errorCode:error.code];
+                    });
+                
+                } else {
                     
-                //OK
-                dispatch_async(dispatch_get_main_queue(), ^{
-                    [self upload:fileName serverUrl:serverUrl cryptated:cryptated template:NO onlyPlist:NO fileNameTemplate:nil assetLocalIdentifier:assetLocalIdentifier session:session taskStatus:taskStatus selector:selector selectorPost:selectorPost errorCode:errorCode delegate:delegate];
-                });
-            }
-        }];
-    }
+                    // OOOOOK
+                    dispatch_async(dispatch_get_main_queue(), ^{
+                        [self upload:metadataNet.fileName serverUrl:metadataNet.serverUrl cryptated:metadataNet.cryptated template:NO onlyPlist:NO fileNameTemplate:nil assetLocalIdentifier:metadataNet.assetLocalIdentifier session:metadataNet.session taskStatus:metadataNet.taskStatus selector:metadataNet.selector selectorPost:metadataNet.selectorPost errorCode:metadataNet.errorCode delegate:delegate];
+                    });
+                }
+            }];
+        }
     
-    // VIDEO
-    if (assetMediaType == PHAssetMediaTypeVideo) {
+        // VIDEO
+        if (assetMediaType == PHAssetMediaTypeVideo) {
         
-        __block PHAsset *asset = result[0];
-        __block NSError *error = nil;
-            
-        PHVideoRequestOptions *options = [PHVideoRequestOptions new];
-        options.networkAccessAllowed = YES; // iCloud
+            __block PHAsset *asset = result[0];
+        
+            PHVideoRequestOptions *options = [PHVideoRequestOptions new];
+            options.networkAccessAllowed = YES; // iCloud
             
-        [[PHImageManager defaultManager] requestPlayerItemForVideo:asset options:options resultHandler:^(AVPlayerItem * _Nullable playerItem, NSDictionary * _Nullable info) {
+            [[PHImageManager defaultManager] requestPlayerItemForVideo:asset options:options resultHandler:^(AVPlayerItem * _Nullable playerItem, NSDictionary * _Nullable info) {
                 
-            if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/%@", _directoryUser, fileName]])
-                [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/%@", _directoryUser, fileName] error:nil];
+                if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/%@", _directoryUser, metadataNet.fileName]])
+                    [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/%@", _directoryUser, metadataNet.fileName] error:nil];
                 
-            AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:playerItem.asset presetName:AVAssetExportPresetHighestQuality];
+                AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:playerItem.asset presetName:AVAssetExportPresetHighestQuality];
                 
-            if (exportSession) {
+                if (exportSession) {
                     
-                exportSession.outputURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@", _directoryUser, fileName]];
-                exportSession.outputFileType = AVFileTypeQuickTimeMovie;
+                    exportSession.outputURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@", _directoryUser, metadataNet.fileName]];
+                    exportSession.outputFileType = AVFileTypeQuickTimeMovie;
                     
-                [exportSession exportAsynchronouslyWithCompletionHandler:^{
+                    [exportSession exportAsynchronouslyWithCompletionHandler:^{
                         
-                    if (AVAssetExportSessionStatusCompleted == exportSession.status) {
-                            
-                        // OK
-                        dispatch_async(dispatch_get_main_queue(), ^{
-                            [self upload:fileName serverUrl:serverUrl cryptated:cryptated template:NO onlyPlist:NO fileNameTemplate:nil assetLocalIdentifier:assetLocalIdentifier session:session taskStatus:taskStatus selector:selector selectorPost:selectorPost errorCode:errorCode delegate:delegate];
-                        });
+                        if (AVAssetExportSessionStatusCompleted == exportSession.status) {
                             
-                    } else if (AVAssetExportSessionStatusFailed == exportSession.status) {
+                            // OOOOOOK
+                            dispatch_async(dispatch_get_main_queue(), ^{
+                                [self upload:metadataNet.fileName serverUrl:metadataNet.serverUrl cryptated:metadataNet.cryptated template:NO onlyPlist:NO fileNameTemplate:nil assetLocalIdentifier:metadataNet.assetLocalIdentifier session:metadataNet.session taskStatus:metadataNet.taskStatus selector:metadataNet.selector selectorPost:metadataNet.selectorPost errorCode:metadataNet.errorCode delegate:delegate];
+                            });
                             
-                        // Delete record on Table Auto Upload
-                        if ([selector isEqualToString:selectorUploadAutoUpload] || [selector isEqualToString:selectorUploadAutoUploadAll])
-                            [[NCManageDatabase sharedInstance] deleteQueueUploadWithAssetLocalIdentifier:assetLocalIdentifier selector:selector];
-                            
-                        // Activity
-                        [[NCManageDatabase sharedInstance] addActivityClient:fileName fileID:assetLocalIdentifier action:k_activityDebugActionUpload selector:selector note:[NSString stringWithFormat:@"%@ [%@]",NSLocalizedString(@"_read_file_error_", nil), error.description] type:k_activityTypeFailure verbose:k_activityVerboseDefault activeUrl:_activeUrl];
-                            
-                        // Error for uploadFileFailure
-                        dispatch_async(dispatch_get_main_queue(), ^{
-                            if ([delegate respondsToSelector:@selector(uploadFileFailure:fileID:serverUrl:selector:message:errorCode:)])
-                                [delegate uploadFileFailure:nil fileID:nil serverUrl:serverUrl selector:selector message:[NSString stringWithFormat:@"%@ [%@]",NSLocalizedString(@"_read_file_error_", nil), exportSession.error.description] errorCode:exportSession.error.code];
-                        });
-
-                    } else {
-                        NSLog(@"Export Session Status: %ld", (long)exportSession.status);
-                    }
-                }];
-                    
-            } else {
-                    
-                // Delete record on Table Auto Upload
-                if ([selector isEqualToString:selectorUploadAutoUpload] || [selector isEqualToString:selectorUploadAutoUploadAll])
-                    [[NCManageDatabase sharedInstance] deleteQueueUploadWithAssetLocalIdentifier:assetLocalIdentifier selector:selector];
-                    
-                // Activity
-                [[NCManageDatabase sharedInstance] addActivityClient:fileName fileID:assetLocalIdentifier action:k_activityDebugActionUpload selector:selector note:[NSString stringWithFormat:@"%@ [%@]",NSLocalizedString(@"_read_file_error_", nil), error.description] type:k_activityTypeFailure verbose:k_activityVerboseDefault activeUrl:_activeUrl];
+                        } else  {
+                        
+                            dispatch_async(dispatch_get_main_queue(), ^{
+                                if ([delegate respondsToSelector:@selector(uploadFileFailure:fileID:serverUrl:selector:message:errorCode:)])
+                                    [delegate uploadFileFailure:metadataNet fileID:nil serverUrl:metadataNet.serverUrl selector:metadataNet.selector message:[NSString stringWithFormat:@"Video export failed [%@]", exportSession.error.description] errorCode:exportSession.error.code];
+                            });
+                        }
+                    }];
                     
-                // Error for uploadFileFailure
-                dispatch_async(dispatch_get_main_queue(), ^{
-                    if ([delegate respondsToSelector:@selector(uploadFileFailure:fileID:serverUrl:selector:message:errorCode:)])
-                        [delegate uploadFileFailure:nil fileID:nil serverUrl:serverUrl selector:selector message:[NSString stringWithFormat:@"%@ [%@]",NSLocalizedString(@"_read_file_error_", nil), exportSession.error.description] errorCode:exportSession.error.code];
-                });
-            }
-        }];
+                } else {
+                
+                    dispatch_async(dispatch_get_main_queue(), ^{
+                        if ([delegate respondsToSelector:@selector(uploadFileFailure:fileID:serverUrl:selector:message:errorCode:)])
+                            [delegate uploadFileFailure:metadataNet fileID:nil serverUrl:metadataNet.serverUrl selector:metadataNet.selector message:@"Create Video session failed [Internal error]" errorCode:k_CCErrorInternalError];
+                    });
+                }
+            }];
+        }
     }
 }
 
@@ -964,6 +964,7 @@
 - (void)upload:(NSString *)fileName serverUrl:(NSString *)serverUrl cryptated:(BOOL)cryptated template:(BOOL)template onlyPlist:(BOOL)onlyPlist fileNameTemplate:(NSString *)fileNameTemplate assetLocalIdentifier:(NSString *)assetLocalIdentifier session:(NSString *)session taskStatus:(NSInteger)taskStatus selector:(NSString *)selector selectorPost:(NSString *)selectorPost errorCode:(NSInteger)errorCode delegate:(id)delegate
 {
     NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:serverUrl];
+    if (!directoryID) return;
     NSString *fileNameCrypto;
     
     // create Metadata
@@ -996,7 +997,7 @@
         metadata.sessionSelectorPost = selectorPost;
         metadata.typeFile = k_metadataTypeFile_unknown;
         
-        metadata = [[NCManageDatabase sharedInstance] addMetadata:metadata activeUrl:_activeUrl serverUrl:serverUrl];
+        metadata = [[NCManageDatabase sharedInstance] addMetadata:metadata];
         
         if (metadata)
             [self uploadURLSession:fileName fileNamePrint:metadata.fileNamePrint serverUrl:serverUrl sessionID:uploadID session:metadata.session taskStatus:taskStatus assetLocalIdentifier:assetLocalIdentifier cryptated:cryptated onlyPlist:onlyPlist selector:selector];
@@ -1027,7 +1028,7 @@
             metadata.sessionSelectorPost = selectorPost;
             metadata.typeFile = k_metadataTypeFile_template;
             
-            metadata = [[NCManageDatabase sharedInstance] addMetadata:metadata activeUrl:_activeUrl serverUrl:serverUrl];
+            metadata = [[NCManageDatabase sharedInstance] addMetadata:metadata];
             
             if (metadata) {
             
@@ -1098,7 +1099,7 @@
             if ([metadata.typeFile isEqualToString: k_metadataTypeFile_image] || [metadata.typeFile isEqualToString: k_metadataTypeFile_video])
                 [[CCCrypto sharedManager] addPlistImage:[NSString stringWithFormat:@"%@/%@", _directoryUser, [fileNameCrypto stringByAppendingString:@".plist"]] fileNamePathImage:[NSTemporaryDirectory() stringByAppendingString:uploadID]];
                 
-            metadata = [[NCManageDatabase sharedInstance] addMetadata:metadata activeUrl:_activeUrl serverUrl:serverUrl];
+            metadata = [[NCManageDatabase sharedInstance] addMetadata:metadata];
             
             if (metadata) {
                 
@@ -1167,7 +1168,7 @@
                     // -- Go to Upload --
                     [CCGraphics createNewImageFrom:metadata.fileNamePrint directoryUser:_directoryUser fileNameTo:metadata.fileID fileNamePrint:metadata.fileNamePrint size:@"m" imageForUpload:YES typeFile:metadata.typeFile writePreview:YES optimizedFileName:NO];
                 
-                    metadata = [[NCManageDatabase sharedInstance] addMetadata:metadata activeUrl:_activeUrl serverUrl:serverUrl];
+                    metadata = [[NCManageDatabase sharedInstance] addMetadata:metadata];
                 
                     if (metadata) {
                         
@@ -1194,7 +1195,7 @@
 #ifndef EXTENSION
             [CCGraphics createNewImageFrom:metadata.fileNamePrint directoryUser:_directoryUser fileNameTo:metadata.fileID fileNamePrint:metadata.fileNamePrint size:@"m" imageForUpload:YES typeFile:metadata.typeFile writePreview:YES optimizedFileName:NO];
 #endif
-            metadata = [[NCManageDatabase sharedInstance] addMetadata:metadata activeUrl:_activeUrl serverUrl:serverUrl];
+            metadata = [[NCManageDatabase sharedInstance] addMetadata:metadata];
             
             if (metadata) {
                 
@@ -1209,6 +1210,7 @@
     BOOL send = NO;
     
     NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
+    if (!serverUrl) return;
     
     if (metadata.cryptated) {
         
@@ -1309,8 +1311,11 @@
 
     NSURLSessionUploadTask *uploadTask = [sessionUpload uploadTaskWithRequest:request fromFile:[NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@", _directoryUser, fileNameForUpload]]];
     
+    // Error
     if (uploadTask == nil) {
         
+        [[NCManageDatabase sharedInstance] addActivityClient:fileName fileID:assetLocalIdentifier action:k_activityDebugActionUpload selector:selector note:@"Upload task not available" type:k_activityTypeFailure verbose:k_activityVerboseHigh activeUrl:_activeUrl];
+        
         NSUInteger sessionTaskIdentifier = k_taskIdentifierNULL;
         NSUInteger sessionTaskIdentifierPlist = k_taskIdentifierNULL;
         
@@ -1331,7 +1336,7 @@
         
         [[NCManageDatabase sharedInstance] setMetadataSession:session sessionError:@"" sessionSelector:nil sessionSelectorPost:nil sessionTaskIdentifier:sessionTaskIdentifier sessionTaskIdentifierPlist:sessionTaskIdentifierPlist predicate:[NSPredicate predicateWithFormat:@"sessionID = %@ AND account = %@", sessionID, _activeAccount]];
         
-        // Delete record on Table Auto Upload
+        // OOOOOOKKKK remove record on Table Auto Upload
         if ([selector isEqualToString:selectorUploadAutoUpload] || [selector isEqualToString:selectorUploadAutoUploadAll])
             [[NCManageDatabase sharedInstance] deleteQueueUploadWithAssetLocalIdentifier:assetLocalIdentifier selector:selector];
         
@@ -1372,6 +1377,9 @@
     NSString *url = [[[task currentRequest].URL absoluteString] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
     NSString *fileName = [url lastPathComponent];
     NSString *serverUrl = [self getServerUrlFromUrl:url];
+    if (!serverUrl) return;
+    NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:serverUrl];
+    if (!directoryID) return;
     
     // if plist return
     if ([CCUtility getTypeFileName:fileName] == k_metadataTypeFilenamePlist)
@@ -1379,7 +1387,7 @@
     
     float progress = (float) totalBytesSent / (float)totalBytesExpectedToSend;
 
-    tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataFromFileName:fileName directoryID:[[NCManageDatabase sharedInstance] getDirectoryID:serverUrl]];
+    tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataFromFileName:fileName directoryID:directoryID];
     
     if (metadata) {
             
@@ -1439,7 +1447,7 @@
             metadata.sessionTaskIdentifier = k_taskIdentifierDone;
         
         // Add new metadata
-        metadata = [[NCManageDatabase sharedInstance] addMetadata:metadata activeUrl:_activeUrl serverUrl:serverUrl];
+        metadata = [[NCManageDatabase sharedInstance] addMetadata:metadata];
         
         if (!metadata) {
             
@@ -1537,10 +1545,16 @@
 
 - (void)verifyDownloadInProgress
 {
+#ifndef EXTENSION
+    
+    // No in background
+    if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground)
+        return;
+    
     NSArray *dataSourceDownload = [[NCManageDatabase sharedInstance] getTableMetadataDownload];
     NSArray *dataSourceDownloadWWan = [[NCManageDatabase sharedInstance] getTableMetadataDownloadWWan];
     
-    NSMutableArray *dataSource = [[NSMutableArray alloc] init];
+    NSMutableArray *dataSource = [NSMutableArray new];
     
     [dataSource addObjectsFromArray:dataSourceDownload];
     [dataSource addObjectsFromArray:dataSourceDownloadWWan];
@@ -1597,7 +1611,7 @@
         }];
     }
     
-    /* Verify Upload In Error */
+    /* Verify Download In Error */
     
     NSMutableSet *serversUrl = [NSMutableSet new];
     
@@ -1608,7 +1622,8 @@
     for (tableMetadata *metadata in metadatas) {
         
         NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
-            
+        if (!serverUrl) continue;
+        
         if (metadata.sessionTaskIdentifier == k_taskIdentifierError)
             [self downloadFile:metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:metadata.sessionSelector selectorPost:nil session:k_download_session taskStatus: k_taskStatusResume delegate:nil];
             
@@ -1625,6 +1640,7 @@
             if ([self.delegate respondsToSelector:@selector(reloadDatasource:)])
                 [self.delegate reloadDatasource:serverUrl];
     });
+#endif
 }
 
 #pragma --------------------------------------------------------------------------------------------
@@ -1633,53 +1649,59 @@
 
 - (void)verifyUploadInProgress
 {
-    NSArray *dataSourceUpload = [[NCManageDatabase sharedInstance] getTableMetadataUpload];
-    NSArray *dataSourceUploadWWan = [[NCManageDatabase sharedInstance] getTableMetadataUploadWWan];
+#ifndef EXTENSION
+    // No in background
+    if ([[UIApplication sharedApplication] applicationState] != UIApplicationStateBackground) {
+
+        NSArray *dataSourceUpload = [[NCManageDatabase sharedInstance] getTableMetadataUpload];
+        NSArray *dataSourceUploadWWan = [[NCManageDatabase sharedInstance] getTableMetadataUploadWWan];
     
-    NSMutableArray *dataSource = [[NSMutableArray alloc] init];
+        NSMutableArray *dataSource = [[NSMutableArray alloc] init];
     
-    [dataSource addObjectsFromArray:dataSourceUpload];
-    [dataSource addObjectsFromArray:dataSourceUploadWWan];
+        [dataSource addObjectsFromArray:dataSourceUpload];
+        [dataSource addObjectsFromArray:dataSourceUploadWWan];
     
-    NSLog(@"[LOG] Verify upload file in progress n. %lu", (unsigned long)[dataSource count]);
+        NSLog(@"[LOG] Verify upload file in progress n. %lu", (unsigned long)[dataSource count]);
     
-    for (tableMetadata *metadata in dataSource) {
+        for (tableMetadata *metadata in dataSource) {
         
-        __block NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
+            __block NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
+            if (!serverUrl) continue;
         
-        NSURLSession *session = [self getSessionfromSessionDescription:metadata.session];
+            NSURLSession *session = [self getSessionfromSessionDescription:metadata.session];
                 
-        [session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
+            [session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
             
-            BOOL findTask = NO;
-            BOOL findTaskPlist = NO;
+                BOOL findTask = NO;
+                BOOL findTaskPlist = NO;
             
-            // cerchiamo la corrispondenza dei task
-            for (NSURLSessionUploadTask *uploadTask in uploadTasks) {
+                // cerchiamo la corrispondenza dei task
+                for (NSURLSessionUploadTask *uploadTask in uploadTasks) {
                 
-                NSLog(@"[LOG] Find metadata Tasks [%li %li] = [%lu] state : %lu", (long)metadata.sessionTaskIdentifier, (long)metadata.sessionTaskIdentifierPlist , (unsigned long)uploadTask.taskIdentifier, (unsigned long)[uploadTask state]);
+                    NSLog(@"[LOG] Find metadata Tasks [%li %li] = [%lu] state : %lu", (long)metadata.sessionTaskIdentifier, (long)metadata.sessionTaskIdentifierPlist , (unsigned long)uploadTask.taskIdentifier, (unsigned long)[uploadTask state]);
                 
-                if (metadata.sessionTaskIdentifier == uploadTask.taskIdentifier) findTask = YES;
-                if (metadata.sessionTaskIdentifierPlist == uploadTask.taskIdentifier) findTaskPlist = YES;
+                    if (metadata.sessionTaskIdentifier == uploadTask.taskIdentifier) findTask = YES;
+                    if (metadata.sessionTaskIdentifierPlist == uploadTask.taskIdentifier) findTaskPlist = YES;
                 
-                if (findTask == YES || findTaskPlist == YES) break;
-            }
+                    if (findTask == YES || findTaskPlist == YES) break;
+                }
             
-            // se non c'è (ci sono) il relativo uploadTask.taskIdentifier allora chiediamolo
-            if ((metadata.cryptated == YES && findTask == NO && findTaskPlist == NO) || (metadata.cryptated == NO && findTask == NO)) {
+                // se non c'è (ci sono) il relativo uploadTask.taskIdentifier allora chiediamolo
+                if ((metadata.cryptated == YES && findTask == NO && findTaskPlist == NO) || (metadata.cryptated == NO && findTask == NO)) {
                 
-                NSLog(@"[LOG] Call ReadFileVerifyUpload because this file %@ (criptated %i) is in progress but there is no task : [%li %li]", metadata.fileNamePrint, metadata.cryptated, (long)metadata.sessionTaskIdentifier, (long)metadata.sessionTaskIdentifierPlist);
+                    NSLog(@"[LOG] Call ReadFileVerifyUpload because this file %@ (criptated %i) is in progress but there is no task : [%li %li]", metadata.fileNamePrint, metadata.cryptated, (long)metadata.sessionTaskIdentifier, (long)metadata.sessionTaskIdentifierPlist);
                 
-                if (metadata.sessionTaskIdentifier >= 0) [self readFileVerifyUpload:metadata.fileNameData fileNamePrint:metadata.fileNamePrint serverUrl:serverUrl];
-                if (metadata.sessionTaskIdentifierPlist >= 0) [self readFileVerifyUpload:metadata.fileName fileNamePrint:metadata.fileNamePrint serverUrl:serverUrl];
-            }
-        }];
+                    if (metadata.sessionTaskIdentifier >= 0) [self readFileVerifyUpload:metadata.fileNameData fileNamePrint:metadata.fileNamePrint serverUrl:serverUrl];
+                    if (metadata.sessionTaskIdentifierPlist >= 0) [self readFileVerifyUpload:metadata.fileName fileNamePrint:metadata.fileNamePrint serverUrl:serverUrl];
+                }
+            }];
         
-        // Notification change session
-        NSArray *object = [[NSArray alloc] initWithObjects:session, metadata, nil];
-        [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:k_networkingSessionNotification object:object];
+            // Notification change session
+            NSArray *object = [[NSArray alloc] initWithObjects:session, metadata, nil];
+            [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:k_networkingSessionNotification object:object];
+        }
     }
-    
+
     /* Verify Upload In Error */
     
     NSMutableSet *directoryIDs = [NSMutableSet new];
@@ -1702,6 +1724,7 @@
             if ([self.delegate respondsToSelector:@selector(reloadDatasource:)])
                 [self.delegate reloadDatasource:[[NCManageDatabase sharedInstance] getServerUrl:directoryID]];
     });
+#endif
 }
 
 - (void)readFileVerifyUpload:(NSString *)fileName fileNamePrint:(NSString *)fileNamePrint serverUrl:(NSString *)serverUrl
@@ -1734,6 +1757,8 @@
         fileName = metadataNet.fileName;
     
     NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:metadataNet.serverUrl];
+    if (!directoryID)
+        [self uploadFileSuccessFailure:metadata fileName:metadataNet.fileName fileID:metadata.fileID etag:metadata.etag date:metadata.date serverUrl:metadataNet.serverUrl errorCode:k_CCErrorFileUploadNotFound];
     
     tableMetadata *metadataTemp = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"fileName = %@ AND directoryID = %@ AND account = %@", fileName , directoryID, _activeAccount]];
     
@@ -1768,6 +1793,8 @@
         fileName = metadataNet.fileName;
     
     NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:metadataNet.serverUrl];
+    if (!directoryID) return;
+    
     tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"fileName = %@ AND directoryID = %@ AND account = %@",fileName , directoryID, _activeAccount]];
     
     NSInteger error;

+ 41 - 11
iOSClient/Networking/OCNetworking.m

@@ -180,7 +180,7 @@
 
 - (void)uploadAsset
 {
-    [[CCNetworking sharedNetworking] uploadFileFromAssetLocalIdentifier:_metadataNet.assetLocalIdentifier fileName:_metadataNet.fileName serverUrl:_metadataNet.serverUrl cryptated:_metadataNet.cryptated session:_metadataNet.session taskStatus:_metadataNet.taskStatus selector:_metadataNet.selector selectorPost:_metadataNet.selectorPost errorCode:_metadataNet.errorCode delegate:self];
+    [[CCNetworking sharedNetworking] uploadFileFromAssetLocalIdentifier:_metadataNet delegate:self];
 }
 
 - (void)uploadTemplate
@@ -340,7 +340,13 @@
             
                 serverUrlFolder = [CCUtility deletingLastPathComponentFromServerUrl:_metadataNet.serverUrl];
                 directoryIDFolder = [[NCManageDatabase sharedInstance] getDirectoryID:serverUrlFolder];
-                
+                if (!directoryIDFolder) {
+                    dispatch_async(dispatch_get_main_queue(), ^{
+                        
+                        if ([self.delegate respondsToSelector:@selector(readFolderSuccess:metadataFolder:metadatas:)])
+                            [self.delegate readFolderSuccess:_metadataNet metadataFolder:metadataFolder metadatas:metadatas];
+                    });
+                }
                 metadataFolder = [CCUtility trasformedOCFileToCCMetadata:itemDtoFolder fileName:[_metadataNet.serverUrl lastPathComponent] fileNamePrint:[_metadataNet.serverUrl lastPathComponent] serverUrl:serverUrlFolder directoryID:directoryIDFolder autoUploadFileName:autoUploadFileName autoUploadDirectory:autoUploadDirectory activeAccount:_metadataNet.account directoryUser:directoryUser];
             }
         
@@ -452,6 +458,8 @@
         
             for(OCFileDto *itemDto in items) {
             
+                NSString *serverUrl;
+
                 itemDto.fileName = [itemDto.fileName stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
             
                 // Not in Crypto Cloud file
@@ -473,8 +481,12 @@
             
                 NSRange firstInstance = [itemDto.filePath rangeOfString:[NSString stringWithFormat:@"%@/files/%@", dav, _activeUser]];
                 NSRange finalRange = NSMakeRange(firstInstance.location + firstInstance.length, itemDto.filePath.length-(firstInstance.location + firstInstance.length));
-                NSString *serverUrl = [itemDto.filePath substringWithRange:finalRange];
-                
+                if (finalRange.location != NSNotFound && finalRange.location + finalRange.length <= itemDto.filePath.length) {
+                    // It's safe to use range on str
+                    serverUrl = [itemDto.filePath substringWithRange:finalRange];
+                } else {
+                    continue;
+                }
                 
                 /* TRIM */
                 if ([serverUrl hasPrefix:@"/"])
@@ -603,6 +615,8 @@
         
         for(OCFileDto *itemDto in items) {
             
+            NSString *serverUrl;
+            
             itemDto.fileName = [itemDto.fileName stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
             itemDto.filePath = [itemDto.filePath stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
 
@@ -625,7 +639,13 @@
             
             NSRange firstInstance = [itemDto.filePath rangeOfString:[NSString stringWithFormat:@"%@/files/%@", dav, _activeUser]];
             NSRange finalRange = NSMakeRange(firstInstance.location + firstInstance.length, itemDto.filePath.length-(firstInstance.location + firstInstance.length));
-            NSString *serverUrl = [itemDto.filePath substringWithRange:finalRange];
+            
+            if (finalRange.location != NSNotFound && finalRange.location + finalRange.length <= itemDto.filePath.length) {
+                // It's safe to use range on str
+                serverUrl = [itemDto.filePath substringWithRange:finalRange];
+            } else {
+                continue;
+            }
 
             /* TRIM */
             if ([serverUrl hasPrefix:@"/"])
@@ -925,15 +945,23 @@
             OCFileDto *itemDto = [items objectAtIndex:0];
             
             NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:_metadataNet.serverUrl];
-            NSString *autoUploadFileName = [[NCManageDatabase sharedInstance] getAccountAutoUploadFileName];
-            NSString *autoUploadDirectory = [[NCManageDatabase sharedInstance] getAccountAutoUploadDirectory:_activeUrl];
+            if (directoryID) {
+            
+                NSString *autoUploadFileName = [[NCManageDatabase sharedInstance] getAccountAutoUploadFileName];
+                NSString *autoUploadDirectory = [[NCManageDatabase sharedInstance] getAccountAutoUploadDirectory:_activeUrl];
 
-            NSString *directoryUser = [CCUtility getDirectoryActiveUser:_activeUser activeUrl:_activeUrl];
+                NSString *directoryUser = [CCUtility getDirectoryActiveUser:_activeUser activeUrl:_activeUrl];
         
-            metadata = [CCUtility trasformedOCFileToCCMetadata:itemDto fileName:_metadataNet.fileName fileNamePrint:_metadataNet.fileNamePrint serverUrl:_metadataNet.serverUrl directoryID:directoryID autoUploadFileName:autoUploadFileName autoUploadDirectory:autoUploadDirectory activeAccount:_metadataNet.account directoryUser:directoryUser];
+                metadata = [CCUtility trasformedOCFileToCCMetadata:itemDto fileName:_metadataNet.fileName fileNamePrint:_metadataNet.fileNamePrint serverUrl:_metadataNet.serverUrl directoryID:directoryID autoUploadFileName:autoUploadFileName autoUploadDirectory:autoUploadDirectory activeAccount:_metadataNet.account directoryUser:directoryUser];
                         
-            if([self.delegate respondsToSelector:@selector(readFileSuccess:metadata:)])
-                [self.delegate readFileSuccess:_metadataNet metadata:metadata];
+                if([self.delegate respondsToSelector:@selector(readFileSuccess:metadata:)])
+                    [self.delegate readFileSuccess:_metadataNet metadata:metadata];
+                
+            } else {
+                
+                if([self.delegate respondsToSelector:@selector(readFileFailure:message:errorCode:)])
+                    [self.delegate readFileFailure:_metadataNet message:@"Directory not found" errorCode:0];
+            }
         }
         
         // BUG 1038
@@ -942,6 +970,8 @@
 #ifndef EXTENSION
             [app messageNotification:@"Server error" description:@"Read File WebDAV : [items NULL] please fix" visible:YES delay:k_dismissAfterSecond type:TWMessageBarMessageTypeError errorCode:0];
 #endif
+            if([self.delegate respondsToSelector:@selector(readFileFailure:message:errorCode:)])
+                [self.delegate readFileFailure:_metadataNet message:@"Read File WebDAV : [items NULL] please fix" errorCode:0];
         }
         
         [self complete];

+ 5 - 9
iOSClient/Notification/CCNotification.swift

@@ -170,19 +170,15 @@ class CCNotification: UITableViewController, OCNetworkingDelegate {
             let urlIcon = URL(string: notification.icon)
             var image : UIImage?
             
-            if urlIcon != nil {
-                let pathFileName = (appDelegate.directoryUser) + "/" + (urlIcon?.lastPathComponent)!
+            if let urlIcon = urlIcon {
+                let pathFileName = (appDelegate.directoryUser) + "/" + (urlIcon.lastPathComponent)
                 image = UIImage(contentsOfFile: pathFileName)
             }
             
-            if image == nil {
-                
-                cell.icon.image = CCGraphics.changeThemingColorImage(#imageLiteral(resourceName: "notification"), color: NCBrandColor.sharedInstance.brand)
-                //downloadImage(url: urlIcon)
-                
-            } else {
-                
+            if let image = image {
                 cell.icon.image = image
+            } else {
+                cell.icon.image = CCGraphics.changeThemingColorImage(#imageLiteral(resourceName: "notification"), color: NCBrandColor.sharedInstance.brand)
             }
             
             //

+ 2 - 1
iOSClient/PeekPop/CCPeekPop.m

@@ -76,7 +76,8 @@
         
         NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:_metadata.directoryID];
         
-        [[CCNetworking sharedNetworking] downloadFile:_metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorOpenIn selectorPost:nil session:k_download_session taskStatus:k_taskStatusResume delegate:self.delegate];
+        if (serverUrl)
+            [[CCNetworking sharedNetworking] downloadFile:_metadata.fileID serverUrl:serverUrl downloadData:YES downloadPlist:NO selector:selectorOpenIn selectorPost:nil session:k_download_session taskStatus:k_taskStatusResume delegate:self.delegate];
     }];
     
     return @[previewAction1];

+ 43 - 35
iOSClient/Photos/CCPhotos.m

@@ -597,32 +597,36 @@
     checked.image = [UIImage imageNamed:@"checked"];
 
     NSArray *metadatasForKey = [_sectionDataSource.sectionArrayRow objectForKey:[_sectionDataSource.sections objectAtIndex:indexPath.section]];
-    NSString *fileID = [metadatasForKey objectAtIndex:indexPath.row];
-    tableMetadata *metadata = [_sectionDataSource.allRecordsDataSource objectForKey:fileID];
     
-    // Image
-    if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/%@.ico", app.directoryUser, metadata.fileID]]) {
+    if ([metadatasForKey count] > indexPath.row) {
         
-        // insert Image
-        imageView.image = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.ico", app.directoryUser, metadata.fileID]];
+        NSString *fileID = [metadatasForKey objectAtIndex:indexPath.row];
+        tableMetadata *metadata = [_sectionDataSource.allRecordsDataSource objectForKey:fileID];
+    
+        // Image
+        if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/%@.ico", app.directoryUser, metadata.fileID]]) {
         
-    } else {
+            // insert Image
+            imageView.image = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.ico", app.directoryUser, metadata.fileID]];
         
-        // Thumbnail not present
-        imageView.image = [UIImage imageNamed:@"file_photo"];
+        } else {
         
-        if (metadata.thumbnailExists)
-            [[CCActions sharedInstance] downloadTumbnail:metadata delegate:self];
-    }
+            // Thumbnail not present
+            imageView.image = [UIImage imageNamed:@"file_photo"];
+        
+            if (metadata.thumbnailExists)
+                [[CCActions sharedInstance] downloadTumbnail:metadata delegate:self];
+        }
     
-    // Cheched
-    if (cell.selected) {
-        checked.hidden = NO;
-        effect.hidden = NO;
-        effect.alpha = 0.4;
-    } else {
-        checked.hidden = YES;
-        effect.hidden = YES;
+        // Cheched
+        if (cell.selected) {
+            checked.hidden = NO;
+            effect.hidden = NO;
+            effect.alpha = 0.4;
+        } else {
+            checked.hidden = YES;
+            effect.hidden = YES;
+        }
     }
     
     return cell;
@@ -631,34 +635,38 @@
 - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
 {
     NSArray *metadatasForKey = [_sectionDataSource.sectionArrayRow objectForKey:[_sectionDataSource.sections objectAtIndex:indexPath.section]];
-    NSString *fileID = [metadatasForKey objectAtIndex:indexPath.row];
-    _metadata = [_sectionDataSource.allRecordsDataSource objectForKey:fileID];
-    
-    //UICollectionViewCell *cell =[collectionView cellForItemAtIndexPath:indexPath];
     
-    if (_cellEditing) {
+    if ([metadatasForKey count] > indexPath.row) {
         
-        [self cellSelect:YES indexPath:indexPath metadata:_metadata];
+        NSString *fileID = [metadatasForKey objectAtIndex:indexPath.row];
+        _metadata = [_sectionDataSource.allRecordsDataSource objectForKey:fileID];
         
-    } else {
+        if (_cellEditing) {
         
-        if ([self shouldPerformSegue])
-            [self performSegueWithIdentifier:@"segueDetail" sender:self];
-    }    
+            [self cellSelect:YES indexPath:indexPath metadata:_metadata];
+        
+        } else {
+        
+            if ([self shouldPerformSegue])
+                [self performSegueWithIdentifier:@"segueDetail" sender:self];
+        }
+    }
 }
 
 - (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath
 {
     if (_cellEditing == NO)
         return;
- 
-    //UICollectionViewCell *cell =[collectionView cellForItemAtIndexPath:indexPath];
     
     NSArray *metadatasForKey = [_sectionDataSource.sectionArrayRow objectForKey:[_sectionDataSource.sections objectAtIndex:indexPath.section]];
-    NSString *fileID = [metadatasForKey objectAtIndex:indexPath.row];
-    _metadata = [_sectionDataSource.allRecordsDataSource objectForKey:fileID];
     
-    [self cellSelect:NO indexPath:indexPath metadata:_metadata];
+    if ([metadatasForKey count] > indexPath.row) {
+        
+        NSString *fileID = [metadatasForKey objectAtIndex:indexPath.row];
+        _metadata = [_sectionDataSource.allRecordsDataSource objectForKey:fileID];
+        
+        [self cellSelect:NO indexPath:indexPath metadata:_metadata];
+    }
 }
 
 - (BOOL)indexPathIsValid:(NSIndexPath *)indexPath

+ 18 - 34
iOSClient/Settings/CCManageAutoUpload.m

@@ -155,6 +155,16 @@
     [row.cellConfig setObject:[UIFont systemFontOfSize:15.0]forKey:@"textLabel.font"];
     [section addFormRow:row];
 
+    // Auto Upload file name
+    
+    section = [XLFormSectionDescriptor formSection];
+    [form addFormSection:section];
+    
+    row = [XLFormRowDescriptor formRowDescriptorWithTag:@"autoUploadFileName" rowType:XLFormRowDescriptorTypeButton title:NSLocalizedString(@"_autoupload_filenamemask_", nil)];
+    [row.cellConfig setObject:[UIFont systemFontOfSize:15.0]forKey:@"textLabel.font"];
+    row.action.viewControllerClass = [NCManageAutoUploadFileName class];
+    [section addFormRow:row];
+    
     // end
     
     section = [XLFormSectionDescriptor formSection];
@@ -334,6 +344,8 @@
     
     XLFormRowDescriptor *rowAutoUploadCreateSubfolder = [self.form formRowWithTag:@"autoUploadCreateSubfolder"];
 
+    XLFormRowDescriptor *rowAutoUploadFileName = [self.form formRowWithTag:@"autoUploadFileName"];
+
     
     // - STATUS ---------------------
     tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountActive];
@@ -375,6 +387,8 @@
     rowAutoUploadFull.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"];
     
     rowAutoUploadCreateSubfolder.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"];
+    
+    rowAutoUploadFileName.hidden = [NSString stringWithFormat:@"$%@==0", @"autoUpload"];
 
     // ----------------------
     
@@ -383,40 +397,6 @@
     self.form.delegate = self;
 }
 
-- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
-{
-    tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountActive];
-    NSString *sectionName;
-    
-    switch (section)
-    {
-        case 0:
-            sectionName = NSLocalizedString(@"_settings_autoupload_", nil);
-            break;
-        case 1:
-            if (tableAccount.autoUpload) sectionName = NSLocalizedString(@"_autoupload_photos_", nil);
-            else sectionName = @"";
-            break;
-        case 2:
-            if (tableAccount.autoUpload) sectionName = NSLocalizedString(@"_autoupload_videos_", nil);
-            else sectionName = @"";
-            break;
-        case 3:
-            if (tableAccount.autoUpload) sectionName = NSLocalizedString(@"_autoupload_background_", nil);
-            else sectionName = @"";
-            break;
-        case 4:
-            if (tableAccount.autoUpload) sectionName = NSLocalizedString(@"_autoupload_fullphotos_", nil);
-            else sectionName = @"";
-            break;
-        case 5:
-            if (tableAccount.autoUpload) sectionName = NSLocalizedString(@"_autoupload_create_subfolder_", nil);
-            else sectionName = @"";
-            break;
-    }
-    return sectionName;
-}
-
 - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
 {
     tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountActive];
@@ -439,6 +419,10 @@
             if (tableAccount.autoUpload) sectionName =  NSLocalizedString(@"_autoupload_create_subfolder_footer_", nil);
             else sectionName = @"";
             break;
+        case 6:
+            if (tableAccount.autoUpload) sectionName =  NSLocalizedString(@"_autoupload_filenamemask_footer_", nil);
+            else sectionName = @"";
+            break;
     }
     return sectionName;
 }

+ 3 - 1
iOSClient/Settings/CCSettings.m

@@ -401,6 +401,8 @@
         if (metadata.directory) {
         
             NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
+            if (!serverUrl) continue;
+            
             serverUrl = [CCUtility stringAppendServerUrl:serverUrl addFileName:metadata.fileNamePrint];
 
             NSString *serverUrlBeginWith = serverUrl;
@@ -491,7 +493,7 @@
         // Email Recipents
         NSArray *toRecipents;
     
-        messageBody = [NSString stringWithFormat:@"\n\n\n%@ Version %@ (%@)", [NCBrandOptions sharedInstance].brand, [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"], [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]];
+        messageBody = [NSString stringWithFormat:@"%@\n\n\n\n%@ Version %@ (%@) - iOS %@", NSLocalizedString(@"_write_in_english_", nil), [NCBrandOptions sharedInstance].brand, [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"], [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"], [[UIDevice currentDevice] systemVersion]];
         toRecipents = [NSArray arrayWithObject:[NCBrandOptions sharedInstance].mailMe];
     
         MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];

+ 202 - 0
iOSClient/Settings/NCManageAutoUploadFileName.swift

@@ -0,0 +1,202 @@
+//
+//  NCManageAutoUploadFileName.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 19/07/17.
+//  Copyright © 2017 TWS. All rights reserved.
+//
+
+import Foundation
+
+class NCManageAutoUploadFileName: XLFormViewController {
+    
+    let appDelegate = UIApplication.shared.delegate as! AppDelegate
+    let dateExample = Date()
+    
+    required init(coder aDecoder: NSCoder) {
+        super.init(coder: aDecoder)
+        self.initializeForm()
+    }
+    
+    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
+        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
+        self.initializeForm()
+    }
+        
+    func initializeForm() {
+        
+        let form : XLFormDescriptor = XLFormDescriptor(title: NSLocalizedString("_autoupload_filename_title_", comment: "")) as XLFormDescriptor
+        form.rowNavigationOptions = XLFormRowNavigationOptions.stopDisableRow
+        
+        var section : XLFormSectionDescriptor
+        var row : XLFormRowDescriptor
+
+        // Section: Add File Name Type
+        
+        section = XLFormSectionDescriptor.formSection()
+        form.addFormSection(section)
+        
+        row = XLFormRowDescriptor(tag: "addFileNameType", rowType: XLFormRowDescriptorTypeBooleanSwitch, title: NSLocalizedString("_filenametype_photo_video_", comment: ""))
+        row.value = CCUtility.getFileNameType(k_keyFileNameAutoUploadType)
+        section.addFormRow(row)
+        
+        // Section: Rename File Name
+        
+        section = XLFormSectionDescriptor.formSection()
+        form.addFormSection(section)
+        
+        row = XLFormRowDescriptor(tag: "maskFileName", rowType: XLFormRowDescriptorTypeAccount, title: NSLocalizedString("_filename_", comment: ""))
+        
+        let fileNameMask : String = CCUtility.getFileNameMask(k_keyFileNameAutoUploadMask)
+        if fileNameMask.characters.count > 0 {
+            row.value = fileNameMask
+        }
+        section.addFormRow(row)
+        
+        // Section: Preview File Name
+        
+        row = XLFormRowDescriptor(tag: "previewFileName", rowType: XLFormRowDescriptorTypeTextView, title: "")
+        row.height = 180
+        row.cellConfig.setObject(NCBrandColor.sharedInstance.tableBackground, forKey: "backgroundColor" as NSCopying)
+        row.cellConfig.setObject(NCBrandColor.sharedInstance.tableBackground, forKey: "textView.backgroundColor" as NSCopying)
+        
+        row.disabled = true
+        section.addFormRow(row)
+        
+        self.form = form
+    }
+    
+    override func formRowDescriptorValueHasChanged(_ formRow: XLFormRowDescriptor!, oldValue: Any!, newValue: Any!) {
+        
+        super.formRowDescriptorValueHasChanged(formRow, oldValue: oldValue, newValue: newValue)
+        
+        if formRow.tag == "addFileNameType" {
+            CCUtility.setFileNameType((formRow.value! as AnyObject).boolValue, key: k_keyFileNameAutoUploadType)
+            self.reloadForm()
+        }
+        else if formRow.tag == "maskFileName" {
+            
+            let fileName = formRow.value as? String
+            
+            self.form.delegate = nil
+            
+            if let fileName = fileName {
+                formRow.value = CCUtility.removeForbiddenCharactersServer(fileName)
+            }
+            
+            self.form.delegate = self
+            
+            let previewFileName : XLFormRowDescriptor  = self.form.formRow(withTag: "previewFileName")!
+            previewFileName.value = self.previewFileName(valueRename: formRow.value as? String)
+            
+            // reload cell
+            if fileName != nil {
+                
+                if newValue as! String != formRow.value as! String {
+                    
+                    self.reloadFormRow(formRow)
+                    
+                    appDelegate.messageNotification("_info_", description: "_forbidden_characters_", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.info, errorCode: 0)
+                }
+            }
+            
+            self.reloadFormRow(previewFileName)
+        }
+    }
+    
+    // MARK: - View Life Cycle
+    
+    override func viewDidLoad() {
+        
+        super.viewDidLoad()
+        
+        self.navigationController?.navigationBar.isTranslucent = false
+        self.navigationController?.navigationBar.barTintColor = NCBrandColor.sharedInstance.brand
+        self.navigationController?.navigationBar.tintColor = NCBrandColor.sharedInstance.navigationBarText
+        self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: NCBrandColor.sharedInstance.navigationBarText]
+        
+        self.tableView.separatorStyle = UITableViewCellSeparatorStyle.none
+        
+        self.tableView.backgroundColor = NCBrandColor.sharedInstance.tableBackground
+        
+        self.reloadForm()
+    }
+    
+    func reloadForm() {
+        
+        self.form.delegate = nil
+        
+        let maskFileName : XLFormRowDescriptor = self.form.formRow(withTag: "maskFileName")!
+        let previewFileName : XLFormRowDescriptor  = self.form.formRow(withTag: "previewFileName")!
+        previewFileName.value = self.previewFileName(valueRename: maskFileName.value as? String)
+        
+        self.tableView.reloadData()
+        self.form.delegate = self
+    }
+    
+    //MARK: TableView
+    
+    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
+        
+        switch section {
+            
+        case 0:
+            return "    " + NSLocalizedString("_add_filenametype_", comment: "")
+        case 1:
+            return "    " + NSLocalizedString("_rename_filename_", comment: "")
+        case 2:
+            return NSLocalizedString("_preview_filename_", comment: "")
+        default:
+            return ""
+        }
+    }
+    
+    override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
+        
+        switch section {
+            
+            /*
+             case 2:
+             let buttonDestinationFolder : XLFormRowDescriptor  = self.form.formRow(withTag: "maskFileName")!
+             let text = self.writePreviewFileName(buttonDestinationFolder)
+             return text
+             */
+            
+        default:
+            return ""
+        }
+    }
+    
+    // MARK: - Utility
+    
+    func previewFileName(valueRename : String?) -> String {
+        
+        var returnString : String = ""
+        
+        if let valueRename = valueRename {
+            
+            let valueRenameTrimming = valueRename.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
+            
+            if valueRenameTrimming.characters.count > 0 {
+                
+                self.form.delegate = nil
+                CCUtility.setFileNameMask(valueRenameTrimming, key: k_keyFileNameAutoUploadMask)
+                self.form.delegate = self
+                
+                returnString = CCUtility.createFileName("IMG_0001.JPG", fileDate: dateExample, fileType: PHAssetMediaType.image, keyFileName: k_keyFileNameAutoUploadMask, keyFileNameType: k_keyFileNameAutoUploadType)
+
+            } else {
+                
+                CCUtility.setFileNameMask("", key: k_keyFileNameAutoUploadMask)
+                returnString = CCUtility.createFileName("IMG_0001.JPG", fileDate: dateExample, fileType: PHAssetMediaType.image, keyFileName: nil, keyFileNameType: k_keyFileNameAutoUploadType)
+            }
+            
+        } else {
+            
+            CCUtility.setFileNameMask("", key: k_keyFileNameAutoUploadMask)
+            returnString = CCUtility.createFileName("IMG_0001.JPG", fileDate: dateExample, fileType: PHAssetMediaType.image, keyFileName: nil, keyFileNameType: k_keyFileNameAutoUploadType)
+        }
+        
+        return NSLocalizedString("_preview_filename_", comment: "") + ":" + "\n\n" + returnString
+    }
+}

+ 16 - 9
iOSClient/Shares/NCShares.m

@@ -166,7 +166,7 @@
 
 - (void)readFileSuccess:(CCMetadataNet *)metadataNet metadata:(tableMetadata *)metadata
 {
-    (void)[[NCManageDatabase sharedInstance] addMetadata:metadata activeUrl:appDelegate.activeUrl serverUrl:metadataNet.serverUrl];
+    (void)[[NCManageDatabase sharedInstance] addMetadata:metadata];
     
     [self reloadDatasource];
 }
@@ -236,7 +236,7 @@
         tableShare *table = [_dataSource objectAtIndex:indexPath.row];
     
         NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:table.serverUrl];
-        if (directoryID.length > 0)
+        if (directoryID)
             metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND directoryID = %@ AND fileName = %@", appDelegate.activeAccount, directoryID, table.fileName]];
     }
         
@@ -251,9 +251,11 @@
         tableShare *table = [_dataSource objectAtIndex:indexPath.row];
         
         NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:table.serverUrl];
-        tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND directoryID = %@ AND fileName = %@", appDelegate.activeAccount, directoryID, table.fileName]];
+        if (directoryID) {
+            tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND directoryID = %@ AND fileName = %@", appDelegate.activeAccount, directoryID, table.fileName]];
         
-        [self removeShares:metadata tableShare:table];
+            [self removeShares:metadata tableShare:table];
+        }
     }
 }
 
@@ -308,6 +310,8 @@
     tableShare *table = [_dataSource objectAtIndex:indexPath.row];
     
     NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:table.serverUrl];
+    if (!directoryID)
+        return cell;
     
     if (directoryID.length > 0)
          metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND directoryID = %@ AND fileName = %@", appDelegate.activeAccount, directoryID, table.fileName]];
@@ -363,13 +367,16 @@
     tableMetadata *metadata;
     tableShare *table = [_dataSource objectAtIndex:indexPath.row];
 
-    NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:table.serverUrl];
-    if (directoryID.length > 0)
-        metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND directoryID = %@ AND fileName = %@", appDelegate.activeAccount, directoryID, table.fileName]];
+    if (table.serverUrl) {
+        
+        NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:table.serverUrl];
+        if (directoryID)
+            metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND directoryID = %@ AND fileName = %@", appDelegate.activeAccount, directoryID, table.fileName]];
 
-    if (metadata) {
+        if (metadata) {
         
-        [appDelegate.activeMain openWindowShare:metadata];
+            [appDelegate.activeMain openWindowShare:metadata];
+        }
     }
 }
 

BIN
iOSClient/Supporting Files/cs-CZ.lproj/Localizable.strings


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


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


BIN
iOSClient/Supporting Files/en-GB.lproj/Localizable.strings


+ 11 - 1
iOSClient/Supporting Files/en.lproj/Localizable.strings

@@ -120,6 +120,7 @@
 "_mail_sent_"               = "Email sent";
 "_mail_failure_"            = "Failed to send email: %@";
 "_information_req_"         = "Information request";
+"_write_in_english_"        = "Please, write us in English";
 "_credentials_"             = "Credentials";
 "_manage_account_"          = "Manage account";
 "_change_password_"         = "Change password";
@@ -178,6 +179,8 @@
 "_autoupload_fullphotos_footer_"    = "Select the options above before uploading";
 "_autoupload_create_subfolder_"     = "Use subfolders";
 "_autoupload_create_subfolder_footer_" = "Store in subfolders based on year and month";
+"_autoupload_filenamemask_"         = "Change filename mask";
+"_autoupload_filenamemask_footer_"  = "Change the automatic filename mask";
 
 // Manage Crypto Cloud
 
@@ -540,8 +543,10 @@
 "_use_folder_photos_"               = "Use the folder Photos as destination";
 "_rename_filename_"                 = "Rename";
 "_filename_"                        = "File name";
-"_preview_filename_"                = "Example preview of filename, you can use the mask MM,DD,YY for the date";
+"_preview_filename_"                = "Example preview of filename, you can use the mask MM,MMM,DD,YY,YYYY and HH,hh,mm,ss,ampm for the date/time";
 "_forbidden_characters_"            = "Invalid character in the filename";
+"_add_filenametype_"                = "Add type in filename";
+"_filenametype_photo_video_"        = "Photo/Video";
 
 // Notification
 
@@ -555,3 +560,8 @@
 "photos"                            = "photos";
 "of"                                = "of";
 "%i of %i"                          = "%1$i of %2$i";
+
+// Manage Auto Upload FileName
+
+"_autoupload_filename_title_"       = "Auto upload filename";
+

BIN
iOSClient/Supporting Files/es-AR.lproj/Localizable.strings


BIN
iOSClient/Supporting Files/es-MX.lproj/Localizable.strings


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


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


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


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


BIN
iOSClient/Supporting Files/nb-NO.lproj/Localizable.strings


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


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


BIN
iOSClient/Supporting Files/pt-BR.lproj/Localizable.strings


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


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


BIN
iOSClient/Supporting Files/zh-Hans.lproj/Localizable.strings


+ 16 - 9
iOSClient/Synchronize/CCSynchronize.m

@@ -64,7 +64,10 @@
     CCMetadataNet *metadataNet = [[CCMetadataNet alloc] initWithAccount:app.activeAccount];
     
     metadataNet.action = actionReadFolder;
-    metadataNet.directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:serverUrl];
+    NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:serverUrl];
+    if (!directoryID) return;
+    
+    metadataNet.directoryID = directoryID;
     metadataNet.priority = NSOperationQueuePriorityLow;
     metadataNet.selector = selector;
     metadataNet.serverUrl = serverUrl;
@@ -91,8 +94,10 @@
 - (void)readFolderSuccess:(CCMetadataNet *)metadataNet metadataFolder:(tableMetadata *)metadataFolder metadatas:(NSArray *)metadatas
 {
     // Add/update self Folder
-    NSString *serverUrlFolded = [[NCManageDatabase sharedInstance] getServerUrl:metadataFolder.directoryID];
-    (void)[[NCManageDatabase sharedInstance] addMetadata:metadataFolder activeUrl:app.activeUrl serverUrl:serverUrlFolded];
+    if (!metadataFolder || !metadatas || [metadatas count] == 0)
+        return;
+    
+    (void)[[NCManageDatabase sharedInstance] addMetadata:metadataFolder];
     
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
         
@@ -172,7 +177,7 @@
                 tableMetadata *result = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"fileID = %@", metadata.fileID]];
 
                 if (!result)
-                    (void)[[NCManageDatabase sharedInstance] addMetadata:metadata activeUrl:app.activeUrl serverUrl:metadataNet.serverUrl];
+                    (void)[[NCManageDatabase sharedInstance] addMetadata:metadata];
               
                 // Load if different etag
                 tableDirectory *tableDirectory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", metadataNet.account, serverUrl]];
@@ -216,7 +221,7 @@
         }
         
         if ([addMetadatas count] > 0)
-            (void)[[NCManageDatabase sharedInstance] addMetadatas:addMetadatas activeUrl:app.activeUrl serverUrl:metadataNet.serverUrl];
+            (void)[[NCManageDatabase sharedInstance] addMetadatas:addMetadatas serverUrl:metadataNet.serverUrl];
         
         if ([metadatasForVerifyChange count] > 0)
             [self verifyChangeMedatas:metadatasForVerifyChange serverUrl:metadataNet.serverUrl account:metadataNet.account withDownload:YES];
@@ -230,7 +235,7 @@
 - (void)synchronizedFile:(tableMetadata *)metadata selector:(NSString *)selector
 {
     NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
-    if (serverUrl == nil) return;
+    if (!serverUrl) return;
         
     CCMetadataNet *metadataNet = [[CCMetadataNet alloc] initWithAccount:app.activeAccount];
         
@@ -257,7 +262,8 @@
         [[NCManageDatabase sharedInstance] deleteMetadataWithPredicate:[NSPredicate predicateWithFormat:@"fileID = %@", metadataNet.account, metadataNet.fileID] clearDateReadDirectoryID:nil];
         
         NSString *serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadataNet.directoryID];
-        [app.activeMain reloadDatasource:serverUrl];
+        if (serverUrl)
+            [app.activeMain reloadDatasource:serverUrl];
     }
 }
 
@@ -271,7 +277,7 @@
             withDownload = YES;
         
         //Add/Update Metadata
-        tableMetadata *addMetadata = [[NCManageDatabase sharedInstance] addMetadata:metadata activeUrl:app.activeUrl serverUrl:metadataNet.serverUrl];
+        tableMetadata *addMetadata = [[NCManageDatabase sharedInstance] addMetadata:metadata];
         
         if (addMetadata)
             [self verifyChangeMedatas:[[NSArray alloc] initWithObjects:addMetadata, nil] serverUrl:metadataNet.serverUrl account:app.activeAccount withDownload:withDownload];
@@ -358,12 +364,13 @@
         // Clear date for dorce refresh view
         if (![oldDirectoryID isEqualToString:metadata.directoryID]) {
             serverUrl = [[NCManageDatabase sharedInstance] getServerUrl:metadata.directoryID];
+            if (!serverUrl) return;
             oldDirectoryID = metadata.directoryID;
             [[NCManageDatabase sharedInstance] clearDateReadWithServerUrl:serverUrl directoryID:nil];
         }
         
         fileID = metadata.fileID;
-        (void)[[NCManageDatabase sharedInstance] addMetadata:metadata activeUrl:app.activeUrl serverUrl:serverUrl];
+        (void)[[NCManageDatabase sharedInstance] addMetadata:metadata];
         
         CCMetadataNet *metadataNet = [[CCMetadataNet alloc] initWithAccount:app.activeAccount];
             

+ 3 - 1
iOSClient/Utility/CCUtility.h

@@ -82,6 +82,7 @@
 + (void)setDirectoryOnTop:(BOOL)directoryOnTop;
 
 + (void)setFileNameMask:(NSString *)mask key:(NSString *)key;
++ (void)setFileNameType:(BOOL)prefix key:(NSString *)key;
 
 + (void)setCreateMenuEncrypted:(BOOL)encrypted;
 
@@ -124,6 +125,7 @@
 + (BOOL)getDirectoryOnTop;
 
 + (NSString *)getFileNameMask:(NSString *)key;
++ (BOOL)getFileNameType:(NSString *)key;
 
 + (BOOL)getCreateMenuEncrypted;
 
@@ -145,7 +147,7 @@
 + (NSString *)stringAppendServerUrl:(NSString *)serverUrl addFileName:(NSString *)addFileName;
 
 + (NSString *)createRandomString:(int)numChars;
-+ (NSString *)createFileNameFromAsset:(PHAsset *)asset key:(NSString *)key;
++ (NSString *)createFileName:fileName fileDate:(NSDate *)fileDate fileType:(PHAssetMediaType)fileType keyFileName:(NSString *)keyFileName keyFileNameType:(NSString *)keyFileNameType;
 
 + (NSString *)getHomeServerUrlActiveUrl:(NSString *)activeUrl;
 + (NSString *)getDirectoryActiveUser:(NSString *)activeUser activeUrl:(NSString *)activeUrl;

+ 74 - 26
iOSClient/Utility/CCUtility.m

@@ -192,6 +192,12 @@
     [UICKeyChainStore setString:mask forKey:key service:k_serviceShareKeyChain];
 }
 
++ (void)setFileNameType:(BOOL)prefix key:(NSString *)key
+{
+    NSString *sPrefix = (prefix) ? @"true" : @"false";
+    [UICKeyChainStore setString:sPrefix forKey:key service:k_serviceShareKeyChain];
+}
+
 + (void)setCreateMenuEncrypted:(BOOL)encrypted
 {
     NSString *sEncrypted = (encrypted) ? @"true" : @"false";
@@ -384,6 +390,11 @@
     return mask;
 }
 
++ (BOOL)getFileNameType:(NSString *)key
+{
+    return [[UICKeyChainStore stringForKey:key service:k_serviceShareKeyChain] boolValue];
+}
+
 + (BOOL)getCreateMenuEncrypted
 {
     return [[UICKeyChainStore stringForKey:@"createMenuEncrypted" service:k_serviceShareKeyChain] boolValue];
@@ -515,63 +526,95 @@
     return [NSString stringWithFormat:@"%@", randomString];
 }
 
-+ (NSString *)createFileNameFromAsset:(PHAsset *)asset key:(NSString *)key
++ (NSString *)createFileName:fileName fileDate:(NSDate *)fileDate fileType:(PHAssetMediaType)fileType keyFileName:(NSString *)keyFileName keyFileNameType:(NSString *)keyFileNameType
 {
-    NSDate *assetDate = asset.creationDate;
-    NSString *fileName;
-    
-    NSString *assetFileName = [asset valueForKey:@"filename"];
+    BOOL addFileNameType = NO;
     
     NSString *numberFileName;
-    if ([assetFileName length] > 8) numberFileName = [assetFileName substringWithRange:NSMakeRange(04, 04)];
+    if ([fileName length] > 8) numberFileName = [fileName substringWithRange:NSMakeRange(04, 04)];
     else numberFileName = [CCUtility getIncrementalNumber];
     
     NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
     [formatter setDateFormat:@"yy-MM-dd HH-mm-ss"];
-    NSString *fileNameDate = [formatter stringFromDate:assetDate];
+    NSString *fileNameDate = [formatter stringFromDate:fileDate];
     
-    PHAssetMediaType assetMediaType = asset.mediaType;
     NSString *fileNameType = @"";
-    if (assetMediaType == PHAssetMediaTypeImage)
+    if (fileType == PHAssetMediaTypeImage)
         fileNameType = NSLocalizedString(@"_photo_", nil);
-    if (assetMediaType == PHAssetMediaTypeVideo)
+    if (fileType == PHAssetMediaTypeVideo)
         fileNameType = NSLocalizedString(@"_video_", nil);
-    if (assetMediaType == PHAssetMediaTypeAudio)
+    if (fileType == PHAssetMediaTypeAudio)
         fileNameType = NSLocalizedString(@"_audio_", nil);
-    if (assetMediaType == PHAssetMediaTypeUnknown)
+    if (fileType == PHAssetMediaTypeUnknown)
         fileNameType = NSLocalizedString(@"_unknown_", nil);
 
-    NSString *fileNameExt = [[assetFileName pathExtension] lowercaseString];
+    // Use File Name Type
+    if (keyFileNameType)
+        addFileNameType = [CCUtility getFileNameType:keyFileNameType];
+    
+    NSString *fileNameExt = [[fileName pathExtension] lowercaseString];
     
-    if (key) {
+    if (keyFileName) {
         
-        fileName = [CCUtility getFileNameMask:key];
+        fileName = [CCUtility getFileNameMask:keyFileName];
         
         if ([fileName length] > 0) {
             
             [formatter setDateFormat:@"dd"];
-            NSString *day = [formatter stringFromDate:assetDate];
+            NSString *dayNumber = [formatter stringFromDate:fileDate];
             [formatter setDateFormat:@"MMM"];
-            NSString *month = [formatter stringFromDate:assetDate];
+            NSString *month = [formatter stringFromDate:fileDate];
+            [formatter setDateFormat:@"MM"];
+            NSString *monthNumber = [formatter stringFromDate:fileDate];
+            [formatter setDateFormat:@"yyyy"];
+            NSString *year = [formatter stringFromDate:fileDate];
             [formatter setDateFormat:@"yy"];
-            NSString *year = [formatter stringFromDate:assetDate];
+            NSString *yearNumber = [formatter stringFromDate:fileDate];
+            [formatter setDateFormat:@"HH"];
+            NSString *hour24 = [formatter stringFromDate:fileDate];
+            [formatter setDateFormat:@"hh"];
+            NSString *hour12 = [formatter stringFromDate:fileDate];
+            [formatter setDateFormat:@"mm"];
+            NSString *minute = [formatter stringFromDate:fileDate];
+            [formatter setDateFormat:@"ss"];
+            NSString *second = [formatter stringFromDate:fileDate];
+            [formatter setDateFormat:@"a"];
+            NSString *ampm = [formatter stringFromDate:fileDate];
             
             // Replace string with date
 
-            fileName = [fileName stringByReplacingOccurrencesOfString:@"DD" withString:day];
-            fileName = [fileName stringByReplacingOccurrencesOfString:@"MM" withString:month];
-            fileName = [fileName stringByReplacingOccurrencesOfString:@"YY" withString:year];
-
-            fileName = [NSString stringWithFormat:@"%@-%@.%@", fileName, numberFileName, fileNameExt];
+            fileName = [fileName stringByReplacingOccurrencesOfString:@"DD" withString:dayNumber];
+            fileName = [fileName stringByReplacingOccurrencesOfString:@"MMM" withString:month];
+            fileName = [fileName stringByReplacingOccurrencesOfString:@"MM" withString:monthNumber];
+            fileName = [fileName stringByReplacingOccurrencesOfString:@"YYYY" withString:year];
+            fileName = [fileName stringByReplacingOccurrencesOfString:@"YY" withString:yearNumber];
+
+            fileName = [fileName stringByReplacingOccurrencesOfString:@"HH" withString:hour24];
+            fileName = [fileName stringByReplacingOccurrencesOfString:@"hh" withString:hour12];
+            fileName = [fileName stringByReplacingOccurrencesOfString:@"mm" withString:minute];
+            fileName = [fileName stringByReplacingOccurrencesOfString:@"ss" withString:second];
+            fileName = [fileName stringByReplacingOccurrencesOfString:@"ampm" withString:ampm];
+
+            if (addFileNameType)
+                fileName = [NSString stringWithFormat:@"%@ %@-%@.%@", fileNameType, fileName, numberFileName, fileNameExt];
+            else
+                fileName = [NSString stringWithFormat:@"%@-%@.%@", fileName, numberFileName, fileNameExt];
             
         } else {
             
-            fileName = [NSString stringWithFormat:@"%@ %@ %@.%@", fileNameType, fileNameDate, numberFileName, fileNameExt];
+            if (addFileNameType)
+                fileName = [NSString stringWithFormat:@"%@ %@ %@.%@", fileNameType, fileNameDate, numberFileName, fileNameExt];
+            else
+                fileName = [NSString stringWithFormat:@"%@ %@.%@", fileNameDate, numberFileName, fileNameExt];
         }
         
     } else {
         
-        fileName = [NSString stringWithFormat:@"%@ %@ %@.%@", fileNameType, fileNameDate, numberFileName, fileNameExt];
+        if (addFileNameType)
+            fileName = [NSString stringWithFormat:@"%@ %@ %@.%@", fileNameType, fileNameDate, numberFileName, fileNameExt];
+        else
+            fileName = [NSString stringWithFormat:@"%@ %@.%@", fileNameDate, numberFileName, fileNameExt];
+
     }
     
     return fileName;
@@ -891,6 +934,11 @@
     if ([metadata.type isEqualToString: k_metadataType_template]) {
         
         metadata.typeFile = k_metadataTypeFile_template;
+    
+    } else if ([metadata.fileName isEqualToString:@"."]) {
+        
+        metadata.typeFile = k_metadataTypeFile_unknown;
+        metadata.iconName = @"file";
         
     } else if (!metadata.directory) {
         
@@ -1112,7 +1160,7 @@
     metadata.protocolCrypto = k_versionProtocolPlist;
     metadata.size = [attributes[NSFileSize] longValue];
     metadata.thumbnailExists = false;
-    metadata.type = k_metadataType_local;
+    metadata.type = k_metadataType_file;
     metadata.title = @"";
     metadata.uuid = [CCUtility getUUID];