Skip to content

Commit

Permalink
Version 1.0.0 (#352)
Browse files Browse the repository at this point in the history
* hide beta warning

* [Bugfix 1.0.0] Fixed an issue with drag to action not working for some actions

* - Fix issue (3) "Oversized thumbnails"
- Fix separator insets in item list

* - Produce an appropriate error when an upload fails due to insufficient space left on the server (fix (4))

* - Fixing issue (1) and (2) via SDK update

* Version Bump to 114

* - disable table cell selection
- fixed long status messages, while setting dynamically numbers of lines

* Version Bump to 115

* - Fixed (5) where the progress of a file that completed download in the background was shown incorrectly

* - Improve progress updates and representation in ClientItemCell

* - Fix: indicate activity during last phase of setting up a new bookmark and whenever editing a bookmark and saving it (previously UI seemed stuck for a couple of seconds)

* - Added NSError+MessageResolution that resolves the localized description for OCErrors so they are included when serialized, so they become visible in the Files app, too
- Fixing issue (8) in #237

* Implemented improvement (13)

* - Fix newly introduced potential crash bug in renameItem FP method
- Remove trash method and permission flag for items in FP, so "Delete Now" is the only option and Files app shows a warning
- Fixing (11) in #237

* - Rename uploadsBarButton to plusBarButton in ClientQueryViewController
- Add new action extension location .plusButton
- Add Action extensions support to provide UIAlertAction objects
- Add .plusButton location to CreateFolder action
- Extend the ClientQueryViewController plusBarButton to include action extensions in the alert that's being shown
- Implementing improvement (15) from #237

* Fixed (13): restore multiple selection after reloading file list

* - Move File Upload and Photo Upload from ClientQueryViewController to distinct Action Extensions
- Extend ActionProgressHandler to cater for both publishing and unpublishing progress objects
- Replace repeated code with a method to provide a ActionProgressHandler in ClientItemQueryViewController
- Make CreateFolderAction require a folder as parent item
- Make MoveAction present on the provided ViewController, not its navigationController
- Extend error handling in several places

* Fixed (21): folder picker not canceleable when navigating into folder and back

* - SortBar overhaul / cleanup
	- remove create folder button from left
	- left-align the sort option and rename it "Sort by" (from "Sorted by")
	- turn the sort option button from a ThemeButton to a UIButton and replace the unicode arrow with an elegant chevron
	- remove sortBar location for action extensions
	- clean up SortBar code
- NSObject+ThemeApplication
	- replace use of isKindOfClass and force-casts with if let constructs
	- add support for UIButton themeing
- fix "flashing" reording right after opening a connection by setting the OCQuery sort method before starting the query
- fix bug where an alert was shown for invalid credentials, but the Edit button did not work
	- fix ClientRootViewController.closeClient(), so it calls the completionHandler
	- adjust the editing method to the changed view and navigation controller structure
- minor code formatting and style fixes in several places

* Fixed (22): no ‘more’ button in directory picker and now swipe to delete

* Another small fix for (22)

* Fix for multi-selection regression (items automatically selected) when re-entering multi-selection

* - Fix UI main thread violation in BookmarkViewController
- Fix spelling of CreateFolderAction.identifier value
- Simplify implementation of DuplicateAction by refactoring it to use new SDK APIs, addressing issue (7) in #237
- Fix potential future crash in ClientDirectoryPickerViewController by avoiding force-casting
- Make OCItem.parentItem in OCItem+Extension more robust using new SDK API
- Adapt FileProviderExtension to use new, supported SDK APIs instead of the island implementation that was -findKnownExistingItemInParent:withName:
- Add (and comment out) code that lets FileProviderExtension.createDirectoryWithName return as soon as the placeholder item is available
- Add empty implementations for trashItemWithIdentifier/untrashItemWithIdentifier/setLastUsedDate/supportedServiceSourcesForItemIdentifier to comply with requirement of overriding all methods raised in the documentation

* Fix for (24) refresh animation glitch

* Fixed (26) crash when trying to downsample corrupt image file

* Version Bump to 116

* Fixed (27): not downloading files which are present offline

* Using OCCore.localCopy() to test if the file is already downloaded

* Another fix for (27)

Not dismissing DisplayViewController when OpenIn action is triggered.

* - Update SDK

* - Address issue (17) from #237 by bringing up a custom error message when a user likely attempted a cross-server move operation through the Files app

* fixed earl grey ui test failures, because UI or logic changed in release_1.0.0 fixes

* - Address issue (30) in #237 via SDK update

* fixed memory leak, which causes that the viewcontroller was not released (this was recognized, because audio or video keeps playing in the background)

* - Updating SDK, fixing issues described for the initial release issue (30) fix

* - Fix issue (19) in #237
- Fix issue (30) in #237 with fixes described in owncloud/ios-sdk#46 (comment)

* - Addressing (30) in #237

* Fixed (35) handling taps in the PDFThumbnailsView

* Some fixes regarding thumbnail size calculation

* - Update to latest SDK (to solve (30))

* Fixed (31) plus couple of PDF thumbnail view fixes

* Fixed (37) disable horizontal scrolling in the gallery if there is a single item

* - Update ios-sdk which now includes important fixes from the ios-sdk feature/sharing branch

* - Fix another formatting warning

* - Certificate Manager now shows the acceptance reason for user-accepted certificates
- Certificate View now shows the acceptance reason description for user-accepted certificates

* Few cosmetic changes

* Removed unused instance variable

* Fixed (38) tap to hide bars -> recalculate image size

* Fixed an issue with swipe in the image gallery causing navigation bar to reappear

* Fixed (39) Going back to root folder when selected “Browse” tab is tapped

* - Fixing two issues from #237:
	- (25) Double deletion in maintenance mode
        - (41) Files re-appear in the files list after batch-deleting them

* - Fix (42) in #237: considerable CPU use and slow-down in busy/frequently updated directories

* - Fixing (33) in #237 via SDK update: give users option to keep file or retry when upload fails

* - Fix issue (32) and (40) in #237 by presenting ClientRootViewController
	- only when the core has been returned by OCCoreManager, showing an activity indicator in the selected cell until then
	- modally, using a custom push transition to avoid UINavigationController hell
- Fix issue where ClientRootViewController would dismiss the lat ClientQueryViewController while also being dismissed, leading to an inconsistent animation when looking closely

* - Cleanup

* - Cleanup

* Version Bump to 117

* Fixed UI tests which broke due to changes made to fix (32) and (40)

* Fixed remaining UI tests

* - Fix issue where logging in and out of a bookmark in quick succession could lead to hangs opening the bookmark (likely is (32) in #237)

* - Fix failing UI tests

* - Make certificate detail view more resilient

* - Update SDK to add logging around OCCoreManager core requests/returns

* - SDK update:
        - Make OCCoreManager use an administrative queue for every bookmark, so that one connection closing down or opening up can't hold up another
- Takes advantage of OCCoreManager managing every bookmark independently
	- allowing to select another bookmark if the previous one takes longer to open
	- not show the UI for a bookmark if Settings, Help or Add/Edit Bookmark UI is triggered meanwhile
	- fix crash caused by force-unwrapping self.core in ClientRootViewController.coreReady()

* - Address "(44) Re-save file to the same folder will lead to an error" in #237

* - Avoid showing download progress indicator when viewing files that are already downloaded (issue (46) in #237)
- Fix bug in PDFViewerViewController where CoreGraphics would throw an error when using pdfView with zero size (before properly laying it out)

* - Clean up DisplayViewController and remove force-casts
- Fix (47) "the non-openable files prompt the download progress bar in the "details" view" in #237

* removed localization for "Feedback" button

* Feature/heic to jpeg (#363)

* Added HEIC to JPEG conversion

* Localized strings for photo upload settings

* Fixed indentation

* Fixed license header

* Version Bump to 118

* Made sure that photo metadata is exported
  • Loading branch information
jesmrec authored and michaelstingl committed Apr 29, 2019
1 parent c7069ca commit 8b86fc1
Show file tree
Hide file tree
Showing 83 changed files with 1,937 additions and 1,087 deletions.
1 change: 1 addition & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ disabled_rules:
- line_length
- type_name
- vertical_parameter_alignment
- function_body_length
custom_rules:
empty_line_after_guard_statement:
included: ".*\\.swift"
Expand Down
Binary file added design/chevron-small-light.idraw
Binary file not shown.
Binary file added design/chevron-small.idraw
Binary file not shown.
2 changes: 1 addition & 1 deletion ios-sdk
Submodule ios-sdk updated 82 files
+14 −3 doc/CONFIGURATION.md
+69 −0 doc/TESTING.md
+10 −0 doc/testing-resources/docker-compose.yml
+44 −0 doc/testing-resources/mitmproxy/cert-pkey-A-cert1.pem
+44 −0 doc/testing-resources/mitmproxy/cert-pkey-A-cert2.pem
+44 −0 doc/testing-resources/mitmproxy/cert-pkey-B-cert1.pem
+64 −0 ownCloudSDK.xcodeproj/project.pbxproj
+1 −1 ownCloudSDK/Authentication/OCAuthenticationMethodOAuth2.m
+7 −0 ownCloudSDK/Connection/OCConnection+Authentication.m
+1 −1 ownCloudSDK/Connection/OCConnection+Setup.m
+43 −8 ownCloudSDK/Connection/OCConnection+Sharing.m
+9 −0 ownCloudSDK/Connection/OCConnection+Tools.m
+5 −3 ownCloudSDK/Connection/OCConnection.h
+199 −36 ownCloudSDK/Connection/OCConnection.m
+15 −4 ownCloudSDK/Core/Connection Status/OCCore+ConnectionStatus.m
+82 −7 ownCloudSDK/Core/ItemList/OCCore+ItemList.m
+1 −1 ownCloudSDK/Core/ItemList/OCCoreItemListTask.m
+15 −5 ownCloudSDK/Core/OCCore+ItemUpdates.m
+10 −3 ownCloudSDK/Core/OCCore.h
+59 −7 ownCloudSDK/Core/OCCore.m
+2 −1 ownCloudSDK/Core/Sharing/OCShareQuery.h
+7 −1 ownCloudSDK/Core/Sharing/OCShareQuery.m
+5 −0 ownCloudSDK/Core/Sync/Actions/CopyMove/OCSyncActionCopyMove.m
+1 −1 ownCloudSDK/Core/Sync/Actions/CreateFolder/OCCore+CommandCreateFolder.m
+6 −2 ownCloudSDK/Core/Sync/Actions/CreateFolder/OCSyncActionCreateFolder.h
+14 −1 ownCloudSDK/Core/Sync/Actions/CreateFolder/OCSyncActionCreateFolder.m
+1 −1 ownCloudSDK/Core/Sync/Actions/Upload/OCCore+CommandLocalImport.m
+3 −3 ownCloudSDK/Core/Sync/Actions/Upload/OCCore+CommandLocalModification.m
+2 −0 ownCloudSDK/Core/Sync/Actions/Upload/OCSyncActionUpload.h
+200 −3 ownCloudSDK/Core/Sync/Actions/Upload/OCSyncActionUpload.m
+21 −10 ownCloudSDK/Core/Sync/OCCore+SyncEngine.m
+2 −2 ownCloudSDK/Core/Thumbnails/OCCore+Thumbnails.m
+3 −1 ownCloudSDK/Errors/NSError+OCError.h
+10 −17 ownCloudSDK/Errors/NSError+OCError.m
+3 −0 ownCloudSDK/File Handling/Checksums/OCChecksumAlgorithm.m
+5 −1 ownCloudSDK/HTTP/Pipeline/OCHTTPPipeline.h
+220 −6 ownCloudSDK/HTTP/Pipeline/OCHTTPPipeline.m
+1 −0 ownCloudSDK/HTTP/Pipeline/OCHTTPPipelineManager.m
+3 −0 ownCloudSDK/HTTP/Pipeline/OCHTTPPipelineTask.h
+56 −0 ownCloudSDK/HTTP/Pipeline/OCHTTPPipelineTaskMetrics.h
+180 −0 ownCloudSDK/HTTP/Pipeline/OCHTTPPipelineTaskMetrics.m
+3 −2 ownCloudSDK/HTTP/Request/OCHTTPRequest.m
+3 −1 ownCloudSDK/HTTP/Status/OCHTTPStatus.h
+1 −3 ownCloudSDK/Item/OCItem.h
+0 −4 ownCloudSDK/Item/OCItem.m
+2 −2 ownCloudSDK/Logging/OCLogger.h
+4 −0 ownCloudSDK/OCMacros.h
+53 −0 ownCloudSDK/Resource Management/OCBackgroundManager.h
+267 −0 ownCloudSDK/Resource Management/OCBackgroundManager.m
+48 −0 ownCloudSDK/Resource Management/OCBackgroundTask.h
+62 −0 ownCloudSDK/Resource Management/OCBackgroundTask.m
+1 −1 ownCloudSDK/Resource Management/OCCoreManager.h
+30 −4 ownCloudSDK/Resource Management/OCCoreManager.m
+4 −0 ownCloudSDK/Resources/en.lproj/Localizable.strings
+28 −0 ownCloudSDK/Security/OCCertificate+PrivacyLogging.h
+28 −0 ownCloudSDK/Security/OCCertificate+PrivacyLogging.m
+33 −6 ownCloudSDK/Security/OCCertificate.h
+217 −9 ownCloudSDK/Security/OCCertificate.m
+53 −0 ownCloudSDK/Security/OCCertificateRuleChecker.h
+231 −0 ownCloudSDK/Security/OCCertificateRuleChecker.m
+29 −0 ownCloudSDK/Toolkit/OCDeallocAction.h
+57 −0 ownCloudSDK/Toolkit/OCDeallocAction.m
+2 −0 ownCloudSDK/Toolkit/OCProcessManager.h
+5 −0 ownCloudSDK/Toolkit/OCProcessManager.m
+1 −1 ownCloudSDK/Toolkit/OCProcessSession.m
+2 −2 ownCloudSDK/Vaults/Database/OCDatabase.m
+1 −1 ownCloudSDK/Vaults/Database/SQLite/Internals/OCSQLiteDB+Internal.m
+1 −1 ownCloudSDK/Vaults/Database/SQLite/Internals/OCSQLiteResultSet.m
+5 −1 ownCloudSDK/Wait Condition/OCWaitConditionIssue.m
+1 −1 ownCloudSDK/XML/Parsing/OCXMLParser.m
+5 −0 ownCloudSDK/ownCloudSDK.h
+79 −3 ownCloudSDKTests/CertificateTests.m
+4 −4 ownCloudSDKTests/ConnectionTests.m
+14 −8 ownCloudSDKTests/CoreSharingTests.m
+ ownCloudSDKTests/demo-cert-letsencrypt.cer
+ ownCloudSDKTests/demo-cert-new.cer
+ ownCloudSDKTests/demo-cert-old.cer
+ ownCloudSDKTests/demo-cert-root.cer
+3 −1 ownCloudUI/Certificate Metadata/OCCertificateDetailsViewNode.h
+47 −9 ownCloudUI/Certificate Metadata/OCCertificateDetailsViewNode.m
+31 −0 ownCloudUI/Certificate Metadata/OCCertificateViewController.m
+2 −0 ownCloudUI/Resources/en.lproj/Localizable.strings
2 changes: 1 addition & 1 deletion ownCloud File Provider/FileProviderEnumerator.m
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ - (void)provideItemsForChangeObserverFromQuery:(OCQuery *)query
{
if (_changeObservers.count > 0)
{
OCLogDebug(@"##### PROVIDE ITEMS TO %d --CHANGE-- OBSERVER FOR %@: %@", _changeObservers.count, query.queryPath, query.queryResults);
OCLogDebug(@"##### PROVIDE ITEMS TO %lu --CHANGE-- OBSERVER FOR %@: %@", _changeObservers.count, query.queryPath, query.queryResults);

for (FileProviderEnumeratorObserver *observer in _changeObservers)
{
Expand Down
170 changes: 100 additions & 70 deletions ownCloud File Provider/FileProviderExtension.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#import "FileProviderEnumerator.h"
#import "OCItem+FileProviderItem.h"
#import "FileProviderExtensionThumbnailRequest.h"
#import "NSError+MessageResolution.h"

@interface FileProviderExtension ()

Expand Down Expand Up @@ -138,7 +139,7 @@ - (NSFileProviderItem)itemForIdentifier:(NSFileProviderItemIdentifier)identifier

if (outError != NULL)
{
*outError = returnError;
*outError = [returnError resolvedError];
}

return item;
Expand Down Expand Up @@ -233,7 +234,7 @@ - (void)startProvidingItemAtURL:(NSURL *)provideAtURL completionHandler:(void (^

FPLogCmd(@"Completed with error=%@", error);

completionHandler(error);
completionHandler([error resolvedError]);
}];

return;
Expand Down Expand Up @@ -350,28 +351,6 @@ - (void)stopProvidingItemAtURL:(NSURL *)url
// }
}

#pragma mark - Helpers
- (OCItem *)findKnownExistingItemInParent:(OCItem *)parentItem withName:(NSString *)name
{
OCPath parentPath;
__block OCItem *existingItem = nil;

if (((parentPath = parentItem.path) != nil) && (name != nil))
{
OCPath destinationPath = [parentPath stringByAppendingPathComponent:name];

OCSyncExec(retrieveExistingItem, {
[self.core.vault.database retrieveCacheItemsAtPath:destinationPath itemOnly:YES completionHandler:^(OCDatabase *db, NSError *error, OCSyncAnchor syncAnchor, NSArray<OCItem *> *items) {
existingItem = items.firstObject;
OCSyncExecDone(retrieveExistingItem);
}];
});
}

return (existingItem);
}


#pragma mark - Actions

// ### Apple template comments: ###
Expand All @@ -397,35 +376,41 @@ - (void)createDirectoryWithName:(NSString *)directoryName inParentItemIdentifier

FPLogCmd(@"Creating folder %@ inside %@", directoryName, parentItem.path);

if ((existingItem = [self findKnownExistingItemInParent:parentItem withName:directoryName]) != nil)
if ((existingItem = [self.core cachedItemInParent:parentItem withName:directoryName isDirectory:YES error:NULL]) != nil)
{
FPLogCmd(@"Completed with collission with existingItem=%@ (locally detected)", existingItem);
// completionHandler(nil, [NSError fileProviderErrorForCollisionWithItem:existingItem]); // This is what we should do according to docs
completionHandler(nil, OCError(OCErrorItemAlreadyExists)); // This is what we need to do to avoid users running into issues using the broken Files "Duplicate" action
// completionHandler(nil, [NSError fileProviderErrorForCollisionWithItem:existingItem]); // This is what we should do according to docs
completionHandler(nil, [OCError(OCErrorItemAlreadyExists) resolvedError]); // This is what we need to do to avoid users running into issues using the broken Files "Duplicate" action
return;
}

[self.core createFolder:directoryName inside:parentItem options:nil resultHandler:^(NSError *error, OCCore *core, OCItem *item, id parameter) {
[self.core createFolder:directoryName inside:parentItem options:@{
// OCCoreOptionPlaceholderCompletionHandler : [^(NSError * _Nullable error, OCItem * _Nullable item) {
// FPLogCmd(@"Completed placeholder creation with item=%@, error=%@", item, error);
//
// completionHandler(item, [error resolvedError]);
// } copy]
} resultHandler:^(NSError *error, OCCore *core, OCItem *item, id parameter) {
if (error != nil)
{
if (error.HTTPStatus.code == OCHTTPStatusCodeMETHOD_NOT_ALLOWED)
{
// Folder already exists on the server
OCItem *existingItem;

if ((existingItem = [self findKnownExistingItemInParent:parentItem withName:directoryName]) != nil)
if ((existingItem = [self.core cachedItemInParent:parentItem withName:directoryName isDirectory:YES error:NULL]) != nil)
{
FPLogCmd(@"Completed with collission with existingItem=%@ (server response)", existingItem);
// completionHandler(nil, [NSError fileProviderErrorForCollisionWithItem:existingItem]); // This is what we should do according to docs
completionHandler(nil, OCError(OCErrorItemAlreadyExists)); // This is what we need to do to avoid users running into issues using the broken Files "Duplicate" action
// completionHandler(nil, [NSError fileProviderErrorForCollisionWithItem:existingItem]); // This is what we should do according to docs
completionHandler(nil, [OCError(OCErrorItemAlreadyExists) resolvedError]); // This is what we need to do to avoid users running into issues using the broken Files "Duplicate" action
return;
}
}
}

FPLogCmd(@"Completed with item=%@, error=%@", item, error);

completionHandler(item, error);
completionHandler(item, [error resolvedError]);
}];
}
else
Expand All @@ -436,7 +421,7 @@ - (void)createDirectoryWithName:(NSString *)directoryName inParentItemIdentifier
}
}

- (void)reparentItemWithIdentifier:(NSFileProviderItemIdentifier)itemIdentifier toParentItemWithIdentifier:(NSFileProviderItemIdentifier)parentItemIdentifier newName:(NSString *)newName completionHandler:(void (^)(NSFileProviderItem _Nullable, NSError * _Nullable))completionHandler
- (void)reparentItemWithIdentifier:(NSFileProviderItemIdentifier)itemIdentifier toParentItemWithIdentifier:(NSFileProviderItemIdentifier)parentItemIdentifier newName:(NSString *)newName completionHandler:(void (^)(NSFileProviderItem _Nullable reparentedItem, NSError * _Nullable))completionHandler
{
NSError *error = nil;
OCItem *item=nil, *parentItem=nil;
Expand All @@ -451,54 +436,41 @@ - (void)reparentItemWithIdentifier:(NSFileProviderItemIdentifier)itemIdentifier
[self.core moveItem:item to:parentItem withName:((newName != nil) ? newName : item.name) options:nil resultHandler:^(NSError *error, OCCore *core, OCItem *item, id parameter) {
FPLogCmd(@"Completed with item=%@, error=%@", item, error);

completionHandler(item, error);
completionHandler(item, [error resolvedError]);
}];
}
else
{
FPLogCmd(@"Completed with item=%@ or parentItem=%@ not found, error=%@", item, parentItem, error);
completionHandler(nil, error);
}
}

- (void)renameItemWithIdentifier:(NSFileProviderItemIdentifier)itemIdentifier toName:(NSString *)itemName completionHandler:(void (^)(NSFileProviderItem renamedItem, NSError *error))completionHandler
{
NSError *error = nil;
OCItem *item, *parentItem;

FPLogCmdBegin(@"Rename", @"Start of renameItemWithIdentifier=%@, toName=%@", itemIdentifier, itemName);

if (((item = (OCItem *)[self itemForIdentifier:itemIdentifier error:&error]) != nil) &&
((parentItem = (OCItem *)[self itemForIdentifier:item.parentLocalID error:&error]) != nil))
{
FPLogCmd(@"Renaming %@ in %@ to %@", item, parentItem, itemName);
if (([error.domain isEqual:NSFileProviderErrorDomain] && error.code == NSFileProviderErrorNoSuchItem) && (parentItem == nil) && (item != nil))
{
// When moving files from one OC bookmark to another, the Files app will call with the ID of the item to move on this server
// and the ID on the destination server for the item to move to. For now, we provide an error message covering that case. A
// future release could possibly go through the bookmarks, request the cores, search for the item IDs, etc. - and then implement
// a cross-server move using OCCore actions. The complexity of such an undertaking should not be underestimated, though, as in
// the case of moving folders, we'd have to download and upload entire hierarchies of files - that could change while we're at it.
FPLogCmd(@"parentItem not found. Likely a cross-domain move. Changing error message accordingly.");
error = OCErrorWithDescription(OCErrorItemNotFound, OCLocalized(@"The destination folder couldn't be found on this server. Moving items across servers is currently not supported."));
}

[self.core moveItem:item to:parentItem withName:itemName options:nil resultHandler:^(NSError *error, OCCore *core, OCItem *item, id parameter) {
FPLogCmd(@"Completed with item=%@, error=%@", item, error);
completionHandler(item, error);
}];
}
else
{
FPLogCmd(@"Completed with item=%@ or parentItem=%@ not found, error=%@", item, parentItem, error);
completionHandler(nil, error);
}
}

- (void)trashItemWithIdentifier:(NSFileProviderItemIdentifier)itemIdentifier completionHandler:(void (^)(NSFileProviderItem _Nullable, NSError * _Nullable))completionHandler
- (void)renameItemWithIdentifier:(NSFileProviderItemIdentifier)itemIdentifier toName:(NSString *)itemName completionHandler:(void (^)(NSFileProviderItem renamedItem, NSError *error))completionHandler
{
NSError *error = nil;
OCItem *item;

FPLogCmdBegin(@"Trash", @"Start of trashItemWithIdentifier=%@", itemIdentifier);
FPLogCmdBegin(@"Rename", @"Start of renameItemWithIdentifier=%@, toName=%@", itemIdentifier, itemName);

if ((item = (OCItem *)[self itemForIdentifier:itemIdentifier error:&error]) != nil)
{
FPLogCmd(@"Trashing %@", item);
FPLogCmd(@"Renaming %@ in %@ to %@", item, item.path.parentPath, itemName);

[self.core deleteItem:item requireMatch:YES resultHandler:^(NSError *error, OCCore *core, OCItem *item, id parameter) {
FPLogCmd(@"Completed with error=%@", error);
completionHandler(nil, error);
[self.core renameItem:item to:itemName options:nil resultHandler:^(NSError *error, OCCore *core, OCItem *item, id parameter) {
FPLogCmd(@"Completed with item=%@, error=%@", item, error);
completionHandler(item, [error resolvedError]);
}];
}
else
Expand All @@ -521,7 +493,7 @@ - (void)deleteItemWithIdentifier:(NSFileProviderItemIdentifier)itemIdentifier co

[self.core deleteItem:item requireMatch:YES resultHandler:^(NSError *error, OCCore *core, OCItem *item, id parameter) {
FPLogCmd(@"Completed with error=%@", error);
completionHandler(error);
completionHandler([error resolvedError]);
}];
}
else
Expand Down Expand Up @@ -659,7 +631,7 @@ - (void)importDocumentAtURL:(NSURL *)fileURL toParentItemIdentifier:(NSFileProvi
OCItem *existingItem;
OCCoreImportTransformation transformation = nil;

if ((existingItem = [self findKnownExistingItemInParent:parentItem withName:importFileName]) != nil)
if ((existingItem = [self.core cachedItemInParent:parentItem withName:importFileName isDirectory:NO error:NULL]) != nil)
{
// Return collission error
FPLogCmd(@"Completed with collission with existingItem=%@ (local)", existingItem);
Expand Down Expand Up @@ -715,7 +687,7 @@ - (void)importDocumentAtURL:(NSURL *)fileURL toParentItemIdentifier:(NSFileProvi
else
{
// Import of directories not supported
completionHandler(nil, OCError(OCErrorFeatureNotSupportedForItem));
completionHandler(nil, [OCError(OCErrorFeatureNotSupportedForItem) resolvedError]);
return;
}
}
Expand All @@ -727,7 +699,7 @@ - (void)importDocumentAtURL:(NSURL *)fileURL toParentItemIdentifier:(NSFileProvi
[transformation copy], OCCoreOptionImportTransformation,
nil] placeholderCompletionHandler:^(NSError *error, OCItem *item) {
FPLogCmd(@"Completed with placeholderItem=%@, error=%@", item, error);
completionHandler(item, error);
completionHandler(item, [error resolvedError]);
} resultHandler:^(NSError *error, OCCore *core, OCItem *item, id parameter) {
if ([error.domain isEqual:OCHTTPStatusErrorDomain] && (error.code == OCHTTPStatusCodePRECONDITION_FAILED))
{
Expand Down Expand Up @@ -777,7 +749,7 @@ - (void)setFavoriteRank:(NSNumber *)favoriteRank forItemIdentifier:(NSFileProvid

[self.core updateItem:item properties:@[ OCItemPropertyNameLocalAttributes ] options:nil resultHandler:^(NSError *error, OCCore *core, OCItem *item, id parameter) {
FPLogCmd(@"Completed with item=%@, error=%@", item, error);
completionHandler(item, error);
completionHandler(item, [error resolvedError]);
}];
}
else
Expand Down Expand Up @@ -812,7 +784,7 @@ - (void)setTagData:(NSData *)tagData forItemIdentifier:(NSFileProviderItemIdenti

[self.core updateItem:item properties:@[ OCItemPropertyNameLocalAttributes ] options:nil resultHandler:^(NSError *error, OCCore *core, OCItem *item, id parameter) {
FPLogCmd(@"Completed with item=%@, error=%@", item, error);
completionHandler(item, error);
completionHandler(item, [error resolvedError]);
}];
}
else
Expand All @@ -822,6 +794,65 @@ - (void)setTagData:(NSData *)tagData forItemIdentifier:(NSFileProviderItemIdenti
}
}

#pragma mark - Incomplete/Compatibility actions
- (void)trashItemWithIdentifier:(NSFileProviderItemIdentifier)itemIdentifier completionHandler:(void (^)(NSFileProviderItem _Nullable, NSError * _Nullable))completionHandler
{
NSError *error = nil;
OCItem *item;

/*
This File Provider does not actually support trashing items - and also indicates so via NSFileProviderItem.capabilities.
Regardless, iOS will call -trashItemWithIdentifier: instead of -deleteItemWithIdentifier: when a user chooses to replace an
existing file. And - if we return NSFeatureUnsupportedError - will make the replace action unusuable.
This File Provider therefore implements this method to work around this problem. As soon as iOS uses NSFileProviderItem.capabilities
and picks the correct action in that case, this implementation can and should be removed.
*/

FPLogCmdBegin(@"Trash", @"Start of trashItemWithIdentifier=%@", itemIdentifier);

if ((item = (OCItem *)[self itemForIdentifier:itemIdentifier error:&error]) != nil)
{
FPLogCmd(@"Deleting %@", item);

[self.core deleteItem:item requireMatch:YES resultHandler:^(NSError *error, OCCore *core, OCItem *item, id parameter) {
FPLogCmd(@"Completed with error=%@", error);
completionHandler(nil, [error resolvedError]);
}];
}
else
{
FPLogCmd(@"Completed with item=%@ not found, error=%@", item, error);
completionHandler(nil, error);
}
}

#pragma mark - Unimplemented actions
/*
"You must override all of the extension's methods (except the deprecated methods), even if your implementation is only an empty method."
- [Source: https://developer.apple.com/documentation/fileprovider/nsfileproviderextension?language=objc]
*/

- (void)untrashItemWithIdentifier:(NSFileProviderItemIdentifier)itemIdentifier toParentItemIdentifier:(NSFileProviderItemIdentifier)parentItemIdentifier completionHandler:(void (^)(NSFileProviderItem _Nullable, NSError * _Nullable))completionHandler
{
FPLogCmdBegin(@"Untrash", @"Invocation of unimplemented untrashItemWithIdentifier=%@ toParentItemIdentifier=%@", itemIdentifier, parentItemIdentifier);

completionHandler(nil, [NSError errorWithDomain:NSCocoaErrorDomain code:NSFeatureUnsupportedError userInfo:@{}]);
}

- (void)setLastUsedDate:(NSDate *)lastUsedDate forItemIdentifier:(NSFileProviderItemIdentifier)itemIdentifier completionHandler:(void (^)(NSFileProviderItem _Nullable, NSError * _Nullable))completionHandler
{
FPLogCmdBegin(@"SetLastUsedDate", @"Invocation of unimplemented setLastUsedDate=%@ forItemIdentifier=%@", lastUsedDate, itemIdentifier);

completionHandler(nil, [NSError errorWithDomain:NSCocoaErrorDomain code:NSFeatureUnsupportedError userInfo:@{}]);
}

- (NSArray<id<NSFileProviderServiceSource>> *)supportedServiceSourcesForItemIdentifier:(NSFileProviderItemIdentifier)itemIdentifier error:(NSError * _Nullable __autoreleasing *)error
{
return (nil);
}

#pragma mark - Enumeration
- (nullable id<NSFileProviderEnumerator>)enumeratorForContainerItemIdentifier:(NSFileProviderItemIdentifier)containerItemIdentifier error:(NSError **)error
{
Expand Down Expand Up @@ -981,4 +1012,3 @@ - (void)core:(OCCore *)core handleError:(NSError *)error issue:(OCIssue *)issue
}

@end

Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/

#import "FileProviderExtensionThumbnailRequest.h"
#import "NSError+MessageResolution.h"

@implementation FileProviderExtensionThumbnailRequest

Expand Down Expand Up @@ -68,7 +69,7 @@ - (void)requestNextThumbnail
if (!isOngoing)
{
dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
self.perThumbnailCompletionHandler(itemIdentifier, thumbnail.data, (thumbnail==nil) ? nil : error);
self.perThumbnailCompletionHandler(itemIdentifier, thumbnail.data, (thumbnail==nil) ? nil : [error resolvedError]);

[self requestNextThumbnail];
});
Expand Down
2 changes: 1 addition & 1 deletion ownCloud File Provider/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>113</string>
<string>118</string>
<key>OCAppGroupIdentifier</key>
<string>group.com.owncloud.ios-app</string>
<key>OCAppIdentifierPrefix</key>
Expand Down
29 changes: 29 additions & 0 deletions ownCloud File Provider/NSError+MessageResolution.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// NSError+MessageResolution.h
// ownCloud File Provider
//
// Created by Felix Schwarz on 09.04.19.
// Copyright © 2019 ownCloud GmbH. All rights reserved.
//

/*
* Copyright (C) 2019, ownCloud GmbH.
*
* This code is covered by the GNU Public License Version 3.
*
* For distribution utilizing Apple mechanisms please see https://owncloud.org/contribute/iOS-license-exception/
* You should have received a copy of this license along with this program. If not, see <http://www.gnu.org/licenses/gpl-3.0.en.html>.
*
*/

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface NSError (MessageResolution)

- (NSError *)resolvedError;

@end

NS_ASSUME_NONNULL_END
Loading

0 comments on commit 8b86fc1

Please sign in to comment.