Skip to content

Commit

Permalink
Feature/task scheduling (#484)
Browse files Browse the repository at this point in the history
* #386 Added relevant classes

* First draft of the scheduled task manager

* Just changed some comments

* Implemented background fetch

* Implemented background update fetch

* Clean up of the code

* Fixed merge problems from previous commit

And eliminated some warnings

* Small changes in background fetch operation

* Some refactoring done

* Added some user defaults for media upload

* Available Offline Support
- new MakeAvailableOfflineAction and MakeUnavailableOfflineAction actions
- new Available Offline Library section
	- easy access to all files available offline via Available Offline
	- new ItemPolicyTableViewController and ItemPolicyCell prepared for reuse for presenting other item policies
- Design: added SVG/TVG/PNG icons and cloud symbols for make available offline / make unavailable offline

ClientItemCell changes
- new ClientItemResolvingCell can resolve item from LocalID or path, new superclass of ShareClientItemCell and ItemPolicyCell
- string to use as content for title and detail are now provided via titleLabelString(for:) and detailLabelString(for:), updated via updateLabels(with:), making customization easier
- support for new available offline badge

ProgressSummarizer changes
- changed ProgressSummary from a struct to a class, addressing issue #451 ("Waiting for server response..." message sometimes not disappearing)

* UI for bookmark / upload path selection

* Added dummy implementation of media upload task

* - Adopt OCClaim to ensure files aren't deleted while they are being used in
	- DisplayViewController
	- DownloadItemsHUDViewController
	- FileListTableViewController
	- File Provider
- Add new Storage Settings to allow control over how long unused local copies are kept around
- DisplayViewController now uses OCClaims to ensure files aren't deleted while they are being viewed
- ClientItemCell uses new SDK APIs to
	- show "available offline" badges for folders
	- to indicate if an item has been made available offline directly (solid icon) or indirectly (dimmed icon)
	- keep the cloud status icon updated following changes
- Change "+" icon to "•••" icon in file list, rename plusButton to folderAction everywhere
- Action.provideAlertAction() now applies padding to images if necessary so their text aligns at the same horizontal offset
- Fix typo in BookmarkInfoViewController and change wording from "Delete Offline Copies" to "Delete Local Copies" for consistency
- Update swiftlint.yml to silence ownCloudScreenshotsTests warnings

* - Update ios-sdk

* - Make changes requested in code review, adding missing localizable strings and removing extraneous code

* - Update SDK

* Refactored current implementation of media upload

* Added method to fetch photos from photo library

* - Add downloadTriggerIdentifier and availableOfflinePolicyCoverage as properties that trigger the update of an item's visual representation (addressing finding 6 in #456)
- Update make available offline action to use new convertExistingLocalDownloads option (addressing finding 2 in #456)
- Update SDK (addressing finding 5 in #456)

* Items in moved Available Offline folders should no longer be cleared locally and re-downloaded, following under the hood improvements in the ios-sdk

* - Add initial support for cookies via SDK update

* First draft of instant photo upload implementation

* Calling task completion handler after upload was finished

* - Temporarily disable some UI tests broken due to lack of database running

* - Fix issue (11) in #456 by updating the lastUsed date of already downloaded items when they are viewed

* - Added slider type to StaticTableViewRow
- changed storage settings to allow picking a timeframe via slider rather than a list of time frames

* - Change text from "Remove" to "Make unavailable offline" in Quick Access > Available Offline list (addressing issue (9))

* - Update BookmarkInfoViewController to provide users with the choice to also remove local copies of items marked as Available Offline, issuing a warning and giving the users a way to cancel, addressing issue (12) in #456.

* Fixed QA finding (1)

* Using PHAsset.creationDate to check which media files shall be instantly uploaded

* Fixed naming of class / group

* Moved Tasks folder

* Fixed some review findings

* - Fix issue where a busy bookmark alert is followed by duplicating the bookmark

* Fixed some review findings

* Improved background update fetching

* Fixed some issues in media upload

* Fixed a type in settings key

* Improvements in the instant media upload task

* Added missing returnCore in the selection of the instant upload path

* Fixed QA finding (3)

* Fixes for the correct core returning / requesting

* Small cosmetic code changes

* Fixed video and serialized photo / video uploads

* Moved upload() method to UploadBaseAction class

* Some refactoring in InstantMediaUploadTaskExtension

* Improvements for bookmark / path selection for instant upload

* Remove instant upload configuration if bookmark is not available

* minor refactoring

* Added possibility to cancel account selection

* Small fix: reset the path if new account is selected

* Using item tracking instead of OCQuery

- Disabling instant photo upload if target directory is removed
- Item tracking is potentially faster since it can use cached item information and is not always issuing PROPFIND

* Made some ivars private

* Detect in settings that instant upload path is gone

In this case instant upload is disabled

* - Update ios-sdk
- Take advantage of the new key-value store and OCCoreSkipAvailableOfflineKey to make sure available offline files are not immediately downloaded again after clearing the vault from local copies of available offline files.
- Logging into an account removes any previously set OCCoreSkipAvailableOfflineKey from the key value store
- Move Bookmark locking to an OCBookmarkManager category (next stop: use the new key-value store and bake support for locking bookmarks directly into the SDK)

* - Add missing localization

* Update SDK with latest fixes

* - Fix SettingsTests bugs

* - Apply additional fixes to UI tests and disable the remaining failing ones

* - Wait for connection initialization to complete before requesting sharing info
- Use latest SDK with cookie filtering

* - Turn off Request/Response log tags only filter in project file

* - Disable cookie support

* - Address (13) via SDK update

* link against newest development SDK

* Showing warning that instant upload was disabled

* Fixes for UI testing:
- use new SDK version that returns errors if the SQLite DB has not been opened
- MockOCCore.state now returns .running to avoid queueing of PROPFINDs

* - Fix unit tests

* Added alert shown when in settings when instant upload is disabled

* Added fetchUpdates() within which target folder tracking is started

* - UI testing: make MockOCCore.state no longer return .running due to side effects
- fixed conflicting constraints in two places

* - force-delete bookmarks in UI tests if timeout has passed, log error but don't assert in that case
- handle case where a swipe on table cells in DeleteBookmarkTests triggers deletion outright

* - Further hardening of SettingsTests against timing differences local vs. CI

* - make SettingsTest.testCheckMoreItems() more robust

* Update to the latest changes in the SDK

Those changes reduce memory consumption used for hash calculation

* Change required to accomodate latest SDK changes

* Less parallel photo uploads

* - update SDK to address stuck sync action issues
- no longer auto-open the last selected bookmark when launched by iOS in the background. Instead, the last selected bookmark is now auto-openend only when the app comes to the foreground.
- update FileProviderInterfaceManager to better support the case where the app ships without File Provider.

* Fixed compilation warning

* - Add ATS exemption for File Provider

* - Update SDK

* - Update SDK + add colored debugging option to scheme

* Addressed code review comments

* Removed unneeded weak self

* Removed another unwanted weak self

* - Fix OCEvent-dropping issue via SDK update with fix
- Make UploadMediaAction use OCBackgroundTask to protect while exporting

* - Added missing OCBackgroundTask.start call in UploadMediaAction
- Update SDK

* Fixed missing copyright information and some warnings
  • Loading branch information
mneuwert authored and hosy committed Sep 6, 2019
1 parent 81c2173 commit 52e6df6
Show file tree
Hide file tree
Showing 29 changed files with 1,670 additions and 293 deletions.
2 changes: 1 addition & 1 deletion ios-sdk
Submodule ios-sdk updated 38 files
+45 −21 ownCloudSDK.xcodeproj/project.pbxproj
+1 −1 ownCloudSDK.xcodeproj/xcshareddata/xcschemes/Ocean.xcscheme
+1 −1 ownCloudSDK.xcodeproj/xcshareddata/xcschemes/ownCloudSDK.xcscheme
+10 −10 ownCloudSDK/Connection/OCConnection+Sharing.m
+22 −22 ownCloudSDK/Connection/OCConnection.m
+1 −1 ownCloudSDK/Core/OCCore+Internal.h
+49 −26 ownCloudSDK/Core/OCCore.m
+2 −0 ownCloudSDK/Core/Sync/OCCore+SyncEngine.h
+172 −18 ownCloudSDK/Core/Sync/OCCore+SyncEngine.m
+34 −0 ownCloudSDK/Events/Internal/OCEventQueue.h
+111 −0 ownCloudSDK/Events/Internal/OCEventQueue.m
+36 −0 ownCloudSDK/Events/Internal/OCEventRecord.h
+69 −0 ownCloudSDK/Events/Internal/OCEventRecord.m
+4 −1 ownCloudSDK/Events/OCEvent.h
+29 −4 ownCloudSDK/Events/OCEvent.m
+1 −1 ownCloudSDK/Events/OCEventTarget.h
+2 −2 ownCloudSDK/Events/OCEventTarget.m
+1 −1 ownCloudSDK/File Handling/Checksums/OCChecksumAlgorithmSHA1.m
+75 −21 ownCloudSDK/HTTP/Pipeline/OCHTTPPipeline.m
+1 −1 ownCloudSDK/HTTP/Pipeline/OCHTTPPipelineBackend.h
+56 −3 ownCloudSDK/HTTP/Pipeline/OCHTTPPipelineBackend.m
+15 −1 ownCloudSDK/HTTP/Pipeline/OCHTTPPipelineManager.m
+1 −1 ownCloudSDK/HTTP/Pipeline/OCHTTPPipelineTask.m
+22 −0 ownCloudSDK/KV Store/OCKeyValueStore.m
+2 −0 ownCloudSDK/Logging/OCLogger.h
+15 −1 ownCloudSDK/Logging/OCLogger.m
+7 −7 ownCloudSDK/Logging/Writers/OCLogWriter.m
+4 −1 ownCloudSDK/Resource Management/OCBackgroundManager.h
+31 −2 ownCloudSDK/Resource Management/OCBackgroundManager.m
+1 −1 ownCloudSDK/Resource Management/OCBackgroundTask.h
+5 −2 ownCloudSDK/Resource Management/OCBackgroundTask.m
+30 −0 ownCloudSDK/Vaults/Database/OCDatabase+Schemas.m
+2 −1 ownCloudSDK/Vaults/Database/OCDatabase.h
+39 −4 ownCloudSDK/Vaults/Database/OCDatabase.m
+18 −1 ownCloudSDK/Vaults/Database/SQLite/OCSQLiteDB.h
+96 −3 ownCloudSDK/Vaults/Database/SQLite/OCSQLiteDB.m
+3 −0 ownCloudSDK/Vaults/OCVault.m
+2 −0 ownCloudSDK/ownCloudSDK.h
5 changes: 5 additions & 0 deletions ownCloud File Provider/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,10 @@
<true/>
<key>OCKeychainAccessGroupIdentifier</key>
<string>group.com.owncloud.ios-app</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
</dict>
</plist>
76 changes: 76 additions & 0 deletions ownCloud.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion ownCloud.xcodeproj/xcshareddata/xcschemes/MakeTVG.xcscheme
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1030"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1030"
wasCreatedForAppExtension = "YES"
version = "2.0">
<BuildAction
Expand Down Expand Up @@ -98,9 +98,9 @@
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "2">
<RemoteRunnable
runnableDebuggingMode = "0"
runnableDebuggingMode = "1"
BundleIdentifier = "com.owncloud.ios-app"
RemotePath = "/var/containers/Bundle/Application/5FF9AF8A-2171-4750-8C7B-7785079F446A/ownCloud.app">
RemotePath = "/Users/felix/Library/Developer/CoreSimulator/Devices/348A2D78-5A15-4E50-8EAF-1170115BC798/data/Containers/Bundle/Application/AD282E5C-E658-4707-8C08-A292831061C2/ownCloud.app">
</RemoteRunnable>
<MacroExpansion>
<BuildableReference
Expand All @@ -122,6 +122,11 @@
value = "true"
isEnabled = "YES">
</EnvironmentVariable>
<EnvironmentVariable
key = "oc:log.log-colored"
value = "true"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
<AdditionalOptions>
</AdditionalOptions>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1030"
wasCreatedForAppExtension = "YES"
version = "2.0">
<BuildAction
Expand Down
7 changes: 6 additions & 1 deletion ownCloud.xcodeproj/xcshareddata/xcschemes/ownCloud.xcscheme
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1030"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down Expand Up @@ -169,6 +169,11 @@
value = "0"
isEnabled = "YES">
</EnvironmentVariable>
<EnvironmentVariable
key = "oc:log.log-colored"
value = "true"
isEnabled = "YES">
</EnvironmentVariable>
<EnvironmentVariable
key = "oc:log.log-synchronous"
value = "true"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1030"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1030"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
46 changes: 46 additions & 0 deletions ownCloud/AVFoundation Extensions/AVAsset+Extension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// AVAsset+Extension.swift
// ownCloud
//
// Created by Michael Neuwert on 17.07.2019.
// Copyright © 2019 ownCloud GmbH. All rights reserved.
//

/*
* Copyright (C) 2018, 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 AVFoundation

extension AVAsset {
func exportVideo(targetURL:URL, type:AVFileType, completion:@escaping (_ success:Bool) -> Void) {
if self.isExportable {

let preset = AVAssetExportPresetHighestQuality

AVAssetExportSession.determineCompatibility(ofExportPreset: preset, with: self, outputFileType: type, completionHandler: { (isCompatible) in
if !isCompatible {
completion(false)
}})

guard let export = AVAssetExportSession(asset: self, presetName: preset) else {
completion(false)
return
}

export.outputFileType = type
export.outputURL = targetURL
export.exportAsynchronously {
completion( export.status == .completed )
}
} else {
completion(false)
}
}
}
16 changes: 9 additions & 7 deletions ownCloud/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

FileProviderInterfaceManager.shared.updateDomainsFromBookmarks()

// Set up background refresh
application.setMinimumBackgroundFetchInterval(UIApplication.backgroundFetchIntervalMinimum + 10)
ScheduledTaskManager.shared.setup()

// Display Extensions
OCExtensionManager.shared.addExtension(WebViewDisplayViewController.displayExtension)
Expand All @@ -76,6 +75,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
OCExtensionManager.shared.addExtension(MakeAvailableOfflineAction.actionExtension)
OCExtensionManager.shared.addExtension(MakeUnavailableOfflineAction.actionExtension)

OCExtensionManager.shared.addExtension(BackgroundFetchUpdateTaskAction.taskExtension)
OCExtensionManager.shared.addExtension(InstantMediaUploadTaskExtension.taskExtension)

Theme.shared.activeCollection = ThemeCollection(with: ThemeStyle.preferredStyle)

// Licenses
Expand All @@ -86,6 +88,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
UIView.setAnimationsEnabled(enableUIAnimations)
}

// Set background refresh interval
UIApplication.shared.setMinimumBackgroundFetchInterval(
UIApplication.backgroundFetchIntervalMinimum)

return true
}

Expand All @@ -101,11 +107,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}

func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
Log.debug("AppDelegate: performFetchWithCompletionHandler")

OnMainThread(after: 2.0) {
completionHandler(.noData)
}
ScheduledTaskManager.shared.backgroundFetch(completionHandler: completionHandler)
}

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
Expand Down
35 changes: 5 additions & 30 deletions ownCloud/Client/Actions/Actions+Extensions/UploadBaseAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ import ownCloudApp

class UploadBaseAction: Action {

typealias UploadCompletionHandler = (_ success: Bool, _ item:OCItem?) -> Void
typealias UploadPlaceholderCompletionHandler = (_ item:OCItem?, _ error:Error?) -> Void

// MARK: - Action Matching
override class func applicablePosition(forContext: ActionContext) -> ActionPosition {
// Only available for a single item ..
Expand All @@ -40,36 +37,14 @@ class UploadBaseAction: Action {
return .middle
}

// MARK: - Upload
func upload(itemURL: URL, to rootItem: OCItem, name: String, completionHandler: UploadCompletionHandler? = nil, placeholderHandler:UploadPlaceholderCompletionHandler? = nil, importByCopy:Bool = false) {
if let progress = core?.importItemNamed(name,
at: rootItem,
from: itemURL,
isSecurityScoped: false,
options: [
OCCoreOption.importByCopying : importByCopy,
OCCoreOption.automaticConflictResolutionNameStyle : OCCoreDuplicateNameStyle.bracketed.rawValue
],
placeholderCompletionHandler: { (error, item) in
if error != nil {
Log.debug("Error uploading \(Log.mask(name)) to \(Log.mask(rootItem.path)), error: \(error?.localizedDescription ?? "" )")
}
placeholderHandler?(item, error)
},
resultHandler: { (error, _ core, _ item, _) in
if error != nil {
Log.debug("Error uploading \(Log.mask(name)) to \(Log.mask(rootItem.path)), error: \(error?.localizedDescription ?? "" )")
completionHandler?(false, item)
} else {
Log.debug("Success uploading \(Log.mask(name)) to \(Log.mask(rootItem.path))")
completionHandler?(true, item)
}
}
) {
internal func upload(itemURL: URL, to rootItem: OCItem, name: String) -> Bool {

if core != nil, let progress = itemURL.upload(with: core, at: rootItem) {
self.publish(progress: progress)
return true
} else {
Log.debug("Error setting up upload of \(Log.mask(name)) to \(Log.mask(rootItem.path))")
completionHandler?(false, nil)
return false
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ extension UploadFileAction : UIDocumentPickerDelegate {
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
if let rootItem = context.items.first {
for url in urls {
self.upload(itemURL: url, to: rootItem, name: url.lastPathComponent)
if !self.upload(itemURL: url, to: rootItem, name: url.lastPathComponent) {
self.completed(with: NSError(ocError: .internal))
return
}
}
}

Expand Down
Loading

0 comments on commit 52e6df6

Please sign in to comment.