@@ -11,12 +11,18 @@ import enum Alamofire.AFError
1111class MediaCoordinator : NSObject {
1212 @objc static let shared = MediaCoordinator ( )
1313
14- private( set) var backgroundContext : NSManagedObjectContext = {
15- let context = ContextManager . sharedInstance ( ) . newDerivedContext ( )
16- context. automaticallyMergesChangesFromParent = true
17- return context
14+ private let coreDataStack : CoreDataStack
15+
16+ private var mainContext : NSManagedObjectContext {
17+ coreDataStack. mainContext
18+ }
19+
20+ private let syncOperationQueue : OperationQueue = {
21+ let queue = OperationQueue ( )
22+ queue. name = " org.wordpress.mediauploadcoordinator.sync "
23+ queue. maxConcurrentOperationCount = 1
24+ return queue
1825 } ( )
19- private let mainContext = ContextManager . sharedInstance ( ) . mainContext
2026
2127 private let queue = DispatchQueue ( label: " org.wordpress.mediauploadcoordinator " )
2228
@@ -36,8 +42,9 @@ class MediaCoordinator: NSObject {
3642
3743 private let mediaServiceFactory : MediaService . Factory
3844
39- init ( _ mediaServiceFactory: MediaService . Factory = MediaService . Factory ( ) ) {
45+ init ( _ mediaServiceFactory: MediaService . Factory = MediaService . Factory ( ) , coreDataStack : CoreDataStack = ContextManager . shared ) {
4046 self . mediaServiceFactory = mediaServiceFactory
47+ self . coreDataStack = coreDataStack
4148
4249 super. init ( )
4350
@@ -54,12 +61,11 @@ class MediaCoordinator: NSObject {
5461 /// - Returns: `true` if all media in the post is uploading or was uploaded, `false` otherwise.
5562 ///
5663 func uploadMedia( for post: AbstractPost , automatedRetry: Bool = false ) -> Bool {
57- let mediaService = mediaServiceFactory. create ( backgroundContext)
5864 let failedMedia : [ Media ] = post. media. filter ( { $0. remoteStatus == . failed } )
5965 let mediasToUpload : [ Media ]
6066
6167 if automatedRetry {
62- mediasToUpload = mediaService . failedMediaForUpload ( in: post, automatedRetry: automatedRetry)
68+ mediasToUpload = Media . failedForUpload ( in: post, automatedRetry: automatedRetry)
6369 } else {
6470 mediasToUpload = failedMedia
6571 }
@@ -286,25 +292,23 @@ class MediaCoordinator: NSObject {
286292 func delete( media: [ Media ] , onProgress: ( ( Progress ? ) -> Void ) ? = nil , success: ( ( ) -> Void ) ? = nil , failure: ( ( ) -> Void ) ? = nil ) {
287293 media. forEach ( { self . cancelUpload ( of: $0) } )
288294
289- let service = mediaServiceFactory. create ( backgroundContext)
290- service. deleteMedia ( media,
291- progress: { onProgress ? ( $0) } ,
292- success: success,
293- failure: failure)
295+ coreDataStack. performAndSave { context in
296+ let service = self . mediaServiceFactory. create ( context)
297+ service. deleteMedia ( media,
298+ progress: { onProgress ? ( $0) } ,
299+ success: success,
300+ failure: failure)
301+ }
294302 }
295303
296304 @discardableResult
297305 private func uploadMedia( _ media: Media , automatedRetry: Bool = false ) -> Progress {
298- let service = mediaServiceFactory. create ( backgroundContext)
299-
300- var progress : Progress ? = nil
306+ let resultProgress = Progress . discreteProgress ( totalUnitCount: 100 )
301307
302- service. uploadMedia ( media,
303- automatedRetry: automatedRetry,
304- progress: & progress,
305- success: {
306- self . end ( media)
307- } , failure: { error in
308+ let success : ( ) -> Void = {
309+ self . end ( media)
310+ }
311+ let failure : ( Error ? ) -> Void = { error in
308312 // Ideally the upload service should always return an error. This may be easier to enforce
309313 // if we update the service to Swift, but in the meanwhile I'm instantiating an unknown upload
310314 // error whenever the service doesn't provide one.
@@ -324,12 +328,19 @@ class MediaCoordinator: NSObject {
324328
325329 self . coordinator ( for: media) . attach ( error: nserror, toMediaID: media. uploadID)
326330 self . fail ( nserror, media: media)
327- } )
328- var resultProgress = Progress . discreteCompletedProgress ( )
329- if let taskProgress = progress {
330- resultProgress = taskProgress
331331 }
332+
333+ coreDataStack. performAndSave { context in
334+ let service = self . mediaServiceFactory. create ( context)
335+ var progress : Progress ? = nil
336+ service. uploadMedia ( media, automatedRetry: automatedRetry, progress: & progress, success: success, failure: failure)
337+ if let progress {
338+ resultProgress. addChild ( progress, withPendingUnitCount: resultProgress. totalUnitCount)
339+ }
340+ }
341+
332342 uploading ( media, progress: resultProgress)
343+
333344 return resultProgress
334345 }
335346
@@ -634,16 +645,30 @@ class MediaCoordinator: NSObject {
634645 /// - parameter blog: The blog from where to sync the media library from.
635646 ///
636647 @objc func syncMedia( for blog: Blog , success: ( ( ) -> Void ) ? = nil , failure: ( ( Error ) -> Void ) ? = nil ) {
637- let service = mediaServiceFactory. create ( backgroundContext)
638- service. syncMediaLibrary ( for: blog, success: success, failure: failure)
648+ syncOperationQueue. addOperation ( AsyncBlockOperation { done in
649+ self . coreDataStack. performAndSave { context in
650+ let service = self . mediaServiceFactory. create ( context)
651+ service. syncMediaLibrary (
652+ for: blog,
653+ success: {
654+ done ( )
655+ success ? ( )
656+ } ,
657+ failure: { error in
658+ done ( )
659+ failure ? ( error)
660+ }
661+ )
662+ }
663+ } )
664+
639665 }
640666
641667 /// This method checks the status of all media objects and updates them to the correct status if needed.
642668 /// The main cause of wrong status is the app being killed while uploads of media are happening.
643669 ///
644670 @objc func refreshMediaStatus( ) {
645- let service = mediaServiceFactory. create ( backgroundContext)
646- service. refreshMediaStatus ( )
671+ Media . refreshMediaStatus ( using: coreDataStack)
647672 }
648673}
649674
@@ -693,10 +718,12 @@ extension MediaCoordinator: MediaProgressCoordinatorDelegate {
693718
694719extension MediaCoordinator : Uploader {
695720 func resume( ) {
696- let service = mediaServiceFactory. create ( backgroundContext)
697-
698- service. failedMediaForUpload ( automatedRetry: true ) . forEach ( ) {
699- retryMedia ( $0, automatedRetry: true )
721+ coreDataStack. performAndSave { context in
722+ Media
723+ . failedMediaForUpload ( automatedRetry: true , in: context)
724+ . forEach ( ) {
725+ self . retryMedia ( $0, automatedRetry: true )
726+ }
700727 }
701728 }
702729}
0 commit comments