Skip to content

Commit

Permalink
- New activity tracking subsystem
Browse files Browse the repository at this point in the history
	- OCActivityManager
		- keeps track of activities
		- coalesces updates for maximum performance
		- relays activity information to main thread
	- OCActivity
		- describes an activity with description, status message, progress
		- provides cancel option
		- can contain an OCIssue for error resolution
	- OCActivityUpdate
		- encapsulates activity update information
		- allows publishing and unpublishing activities
		- allows update of individual activity properties
	- simplified creation of OCActivity objects and updates via the OCActivitySource protocol
- OCConnection
	- trying to upload a non-existant file now results in an error
	- extended internal error checks in uploadFileFromURL:
- OCCore+ItemList
	- experimental supply of activity information for background updates
- OCCore+LocalImport
	- addition of a import transformations
	- used by the FileProvider to transform select bundle document formats into ZIP archives on the fly
- OCSyncRecord
	- adding OCActivitySource conformance
  • Loading branch information
felix-schwarz committed Jan 26, 2019
1 parent 58d5397 commit 8dcda9c
Show file tree
Hide file tree
Showing 24 changed files with 909 additions and 59 deletions.
54 changes: 39 additions & 15 deletions ownCloudSDK.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

89 changes: 89 additions & 0 deletions ownCloudSDK/Activity/OCActivity.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//
// OCActivity.h
// ownCloudSDK
//
// Created by Felix Schwarz on 24.01.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>
#import "OCIssue.h"

typedef NSString* OCActivityIdentifier;

typedef NS_ENUM(NSUInteger, OCActivityState)
{
OCActivityStatePending, //!< Activity is pending
OCActivityStateRunning, //!< Activity is being executed
OCActivityStatePaused, //!< Activity is paused
OCActivityStateFailed //!< Activity has failed (and optionally awaits resolution)
};

NS_ASSUME_NONNULL_BEGIN

@class OCActivity;
@class OCActivityUpdate;

@protocol OCActivitySource

@required
@property(readonly,nonatomic) OCActivityIdentifier activityIdentifier; //!< Returns an identifier uniquely identifying the source's activity.

@optional
- (OCActivity *)provideActivity; //!< Returns a new instance of OCActivity representing the source's activity.

@end

@interface OCActivity : NSObject
{
OCActivityIdentifier _identifier;

OCActivityState _state;

NSInteger _ranking;

NSString *_localizedDescription;
NSString *_localizedStatusMessage;

NSProgress *_progress;

OCIssue *_issue;

BOOL _isCancellable;
}

@property(strong) OCActivityIdentifier identifier; //!< Identifier uniquely identifying an activity

@property(assign,nonatomic) OCActivityState state; //!< State of the activity

@property(assign) NSInteger ranking; //!< Lower numbers for higher prioritized items

@property(strong) NSString *localizedDescription; //!< Localized description of the activity (f.ex. "Copying party.jpg to Photos..")
@property(nullable,strong) NSString *localizedStatusMessage; //!< Localized message describing the status of the activity (f.ex. "Waiting for response..")

@property(nullable,strong) NSProgress *progress; //!< Progress information on the activity

@property(nullable,strong) OCIssue *issue; //!< If .state is failed, an issue that can be used to resolve the failure (optional)

@property(assign) BOOL isCancellable; //!< If YES, the activity can be cancelled

+ (instancetype)withIdentifier:(OCActivityIdentifier)identifier description:(NSString *)description statusMessage:(nullable NSString *)statusMessage ranking:(NSInteger)ranking;

- (NSError *)applyUpdate:(OCActivityUpdate *)update; //!< Applies an update to the activity. Returns nil if the update could be applied, an error otherwise.
- (NSError *)applyValue:(nullable id <NSObject>)value forKeyPath:(NSString *)keyPath; //!< Applies a new value to a keypath (entrypoint for subclassing)

- (void)cancel;

@end

NS_ASSUME_NONNULL_END
93 changes: 93 additions & 0 deletions ownCloudSDK/Activity/OCActivity.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
//
// OCActivity.m
// ownCloudSDK
//
// Created by Felix Schwarz on 24.01.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 "OCActivity.h"
#import "OCActivityUpdate.h"
#import "NSError+OCError.h"

@implementation OCActivity

@synthesize identifier = _identifier;

@synthesize ranking = _ranking;

@synthesize localizedDescription = _localizedDescription;
@synthesize localizedStatusMessage = _localizedStatusMessage;

@synthesize progress = _progress;

@synthesize issue = _issue;

@synthesize isCancellable = _isCancellable;

+ (instancetype)withIdentifier:(OCActivityIdentifier)identifier description:(NSString *)description statusMessage:(nullable NSString *)statusMessage ranking:(NSInteger)ranking
{
OCActivity *activity = [OCActivity new];

activity.identifier = identifier;
activity.localizedDescription = description;
activity.localizedStatusMessage = statusMessage;
activity.ranking = ranking;

return (activity);
}

- (void)cancel
{
if (_isCancellable)
{
[self.progress cancel];
}
}

- (NSError *)applyUpdate:(OCActivityUpdate *)update
{
__block NSError *error = nil;

if (update.type != OCActivityUpdateTypeProperty)
{
return (OCError(OCErrorInsufficientParameters));
}

[update.updatesByKeyPath enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull keyPath, id<NSObject> _Nonnull value, BOOL * _Nonnull stop) {
NSError *applicationError = nil;

if ([value isEqual:[NSNull null]])
{
value = nil;
}

if ((applicationError = [self applyValue:value forKeyPath:keyPath]) != nil)
{
error = applicationError;
*stop = YES;
}
}];

return (error);
}

- (NSError *)applyValue:(nullable id <NSObject>)value forKeyPath:(NSString *)keyPath
{
// Entrypoint for subclassing
[self setValue:value forKeyPath:keyPath];

return (nil);
}

@end
47 changes: 47 additions & 0 deletions ownCloudSDK/Activity/OCActivityManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// OCActivityManager.h
// ownCloudSDK
//
// Created by Felix Schwarz on 25.01.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>
#import "OCActivity.h"
#import "OCLogTag.h"

NS_ASSUME_NONNULL_BEGIN

@interface OCActivityManager : NSObject <OCLogTagging>

#pragma mark - Init
- (instancetype)initWithUpdateNotificationName:(NSString *)updateNotificationName;

#pragma mark - Update notifications
@property(readonly,nonatomic) NSNotificationName activityUpdateNotificationName;

#pragma mark - Access
@property(readonly,nonatomic) NSArray <OCActivity *> *activities;
- (nullable OCActivity *)activityForIdentifier:(OCActivityIdentifier)activityIdentifier;

#pragma mark - Updating
- (void)update:(OCActivityUpdate *)update;

@end

extern NSString *OCActivityManagerNotificationUserInfoUpdatesKey; //!< UserInfo key that contains an array of dictionaries providing info on the activity updates:

extern NSString *OCActivityManagerUpdateTypeKey; //!< the type of the update [OCActivityUpdateType]
extern NSString *OCActivityManagerUpdateActivityKey; //!< the updated activity object [OCActivity]

NS_ASSUME_NONNULL_END
Loading

0 comments on commit 8dcda9c

Please sign in to comment.