fetchbookOP

This commit is contained in:
Chris Li 2016-11-29 19:01:26 -05:00
parent 004a31f09e
commit 05ec52d535
8 changed files with 224 additions and 102 deletions

View File

@ -49,7 +49,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>1.8.3557</string>
<string>1.8.3635</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>

View File

@ -21,7 +21,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.8.3557</string>
<string>1.8.3635</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionMainStoryboard</key>

View File

@ -44,7 +44,7 @@
9734E54E1D289D060061C39B /* Welcome.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9734E54D1D289D060061C39B /* Welcome.storyboard */; };
973A5C921DEA3F5600C7804C /* CoreDataTableBaseController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 973A5C911DEA3F5600C7804C /* CoreDataTableBaseController.swift */; };
973A5C951DEA6DD000C7804C /* URLResponseCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 973A5C931DEA6CA900C7804C /* URLResponseCache.swift */; };
973A5C991DEBC54800C7804C /* CloudKitOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 973A5C981DEBC54800C7804C /* CloudKitOperations.swift */; };
973A5C991DEBC54800C7804C /* CloudKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 973A5C981DEBC54800C7804C /* CloudKit.swift */; };
973BCD1A1CEB402900F10B44 /* KiwixTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 973BCD181CEB402900F10B44 /* KiwixTests.swift */; };
973DD40F1D343F2F009D45DB /* libicudata.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 973DD4041D343F2F009D45DB /* libicudata.a */; };
973DD4101D343F2F009D45DB /* libicui18n.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 973DD4051D343F2F009D45DB /* libicui18n.a */; };
@ -192,7 +192,7 @@
9734E54D1D289D060061C39B /* Welcome.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Welcome.storyboard; path = "Kiwix-iOS/Storyboard/Welcome.storyboard"; sourceTree = SOURCE_ROOT; };
973A5C911DEA3F5600C7804C /* CoreDataTableBaseController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataTableBaseController.swift; sourceTree = "<group>"; };
973A5C931DEA6CA900C7804C /* URLResponseCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLResponseCache.swift; sourceTree = "<group>"; };
973A5C981DEBC54800C7804C /* CloudKitOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CloudKitOperations.swift; sourceTree = "<group>"; };
973A5C981DEBC54800C7804C /* CloudKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CloudKit.swift; sourceTree = "<group>"; };
973BCD001CEB3FA500F10B44 /* Kiwix_OSXTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Kiwix_OSXTests.swift; sourceTree = "<group>"; };
973BCD021CEB3FA500F10B44 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
973BCD0B1CEB3FA500F10B44 /* Kiwix_OSXUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Kiwix_OSXUITests.swift; sourceTree = "<group>"; };
@ -788,7 +788,7 @@
97D6811C1D6F70AC00E5FA99 /* GlobalQueue.swift */,
9764CBD21D8083AA00072D6A /* ArticleOperation.swift */,
970A2A211DD562CB0078BB7C /* BookOperations.swift */,
973A5C981DEBC54800C7804C /* CloudKitOperations.swift */,
973A5C981DEBC54800C7804C /* CloudKit.swift */,
973208281DD223DB00EDD3DC /* RefreshLibrary.swift */,
97D6811E1D6F70AC00E5FA99 /* ScanLocalBook.swift */,
972F81561DDBFC79008D7289 /* Search.swift */,
@ -1179,7 +1179,7 @@
97A1FD261D6F71E200A80EE2 /* ZimReader.mm in Sources */,
97A1FD1C1D6F71D800A80EE2 /* KiwixURLProtocol.swift in Sources */,
97C2C26A1DDCC58500A9CC64 /* ArticleOperation.swift in Sources */,
973A5C991DEBC54800C7804C /* CloudKitOperations.swift in Sources */,
973A5C991DEBC54800C7804C /* CloudKit.swift in Sources */,
973208261DD21E9C00EDD3DC /* CoreDataContainer.swift in Sources */,
97D6813F1D6F712800E5FA99 /* Article+CoreDataProperties.swift in Sources */,
97A1FD441D6F728200A80EE2 /* Preference.swift in Sources */,

View File

@ -13,5 +13,37 @@
stopOnStyle = "0">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Kiwix/Operations/CloudKit.swift"
timestampString = "502151859.112083"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "89"
endingLineNumber = "89"
landmarkName = "execute()"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Kiwix/Operations/CloudKit.swift"
timestampString = "502151861.497788"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "95"
endingLineNumber = "95"
landmarkName = "execute()"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>

View File

@ -8,7 +8,6 @@
import CoreData
import CoreSpotlight
import CloudKit
class Article: NSManagedObject {
@ -61,19 +60,19 @@ class Article: NSManagedObject {
// MARK: - CloudKit
var cloudKitRecord: CKRecord? {
guard let url = url, let bookID = book?.id else {return nil}
let recordID = CKRecordID(recordName: url.absoluteString)
let bookRecordID = CKRecordID(recordName: bookID)
let record = CKRecord(recordType: "Article", recordID: recordID)
record["path"] = path as NSString?
record["title"] = title as NSString?
record["snippet"] = snippet as NSString?
record["thumbImagePath"] = thumbImagePath as NSString?
record["isBookmarked"] = isBookmarked as NSNumber
record["book"] = CKReference(recordID: bookRecordID, action: .deleteSelf)
return record
}
// var cloudKitRecord: CKRecord? {
// guard let url = url, let bookID = book?.id else {return nil}
// let recordID = CKRecordID(recordName: url.absoluteString)
// let bookRecordID = CKRecordID(recordName: bookID)
// let record = CKRecord(recordType: "Article", recordID: recordID)
// record["path"] = path as NSString?
// record["title"] = title as NSString?
// record["snippet"] = snippet as NSString?
// record["thumbImagePath"] = thumbImagePath as NSString?
// record["isBookmarked"] = isBookmarked as NSNumber
// record["book"] = CKReference(recordID: bookRecordID, action: .deleteSelf)
// return record
// }
// MARK: - Properties

View File

@ -8,7 +8,7 @@
import Foundation
import CoreData
import CloudKit
#if os(iOS) || os(watchOS) || os(tvOS)
import UIKit
#elseif os(OSX)
@ -102,30 +102,30 @@ class Book: NSManagedObject {
}
// MARK: - CloudKit
var recordZoneID: CKRecordZoneID {
return CKRecordZoneID(zoneName: id, ownerName: CKCurrentUserDefaultName)
}
var recordID: CKRecordID {
return CKRecordID(recordName: id, zoneID: recordZoneID)
}
var record: CKRecord {
let record = CKRecord(recordType: "Book", recordID: recordID)
record["id"] = id as NSString?
record["title"] = title as NSString?
record["description"] = desc as NSString?
record["creator"] = creator as NSString?
record["publisher"] = publisher as NSString?
record["favicon"] = favIcon as NSData?
record["date"] = date as NSDate?
record["articleCount"] = articleCount as NSNumber
record["mediaCount"] = mediaCount as NSNumber
record["fileSize"] = fileSize as NSNumber
record["language"] = language?.code as NSString?
return record
}
//
// var recordZoneID: CKRecordZoneID {
// return CKRecordZoneID(zoneName: id, ownerName: CKCurrentUserDefaultName)
// }
//
// var recordID: CKRecordID {
// return CKRecordID(recordName: id, zoneID: recordZoneID)
// }
//
// var record: CKRecord {
// let record = CKRecord(recordType: "Book", recordID: recordID)
// record["id"] = id as NSString?
// record["title"] = title as NSString?
// record["description"] = desc as NSString?
// record["creator"] = creator as NSString?
// record["publisher"] = publisher as NSString?
// record["favicon"] = favIcon as NSData?
// record["date"] = date as NSDate?
// record["articleCount"] = articleCount as NSNumber
// record["mediaCount"] = mediaCount as NSNumber
// record["fileSize"] = fileSize as NSNumber
// record["language"] = language?.code as NSString?
// return record
// }
// MARK: - Properties

View File

@ -0,0 +1,148 @@
//
// CloudKitOperations.swift
// Kiwix
//
// Created by Chris Li on 11/27/16.
// Copyright © 2016 Chris Li. All rights reserved.
//
import CloudKit
import ProcedureKit
class BookmarkSyncOperation: GroupProcedure {
let articleURL: URL
init(articleURL: URL) {
self.articleURL = articleURL
let database = CKContainer(identifier: "iCloud.org.kiwix").privateCloudDatabase
let zone = FetchBookRecordZoneOperation(database: database, bookID: articleURL.host!)
let book = FetchBookRecordOperation(database: database, bookID: articleURL.host!)
book.inject(dependency: zone, block: {book, zone, error in
book.recordZone = zone.recordZone
})
super.init(operations: [zone, book])
}
}
//class UpdateArticleOperation: Procedure {
// let database: CKDatabase
// let bookID: String
//
// init(database: CKDatabase, bookID: String) {
// self.database = database
// self.bookID = bookID
// super.init()
// }
//
// override func execute() {
// guard let zone = requirement.value else {
// finish()
// return
// }
//
// AppDelegate.persistentContainer.performBackgroundTask { (context) in
// guard let book = Book.fetch(self.bookID, context: context) else {
// self.finish()
// return
// }
// let fetch = CKFetchRecordsOperation(recordIDs: [bookRecordID])
// fetch.database = self.database
// fetch.fetchRecordsCompletionBlock = { records, error in
// if let book = records?[bookRecordID] {
//
// }
// }
// }
//
//
// }
//}
class FetchBookRecordOperation: Procedure {
let database: CKDatabase
let bookID: String
var recordZone: CKRecordZone?
var record: CKRecord?
init(database: CKDatabase, bookID: String) {
self.database = database
self.bookID = bookID
super.init()
}
override func execute() {
guard let zone = recordZone else {
finish()
return
}
AppDelegate.persistentContainer.performBackgroundTask { (context) in
let recordID = CKRecordID(recordName: self.bookID, zoneID: zone.zoneID)
let fetch = CKFetchRecordsOperation(recordIDs: [recordID])
fetch.database = self.database
fetch.fetchRecordsCompletionBlock = { records, error in
if let record = records?[recordID] {
self.record = record
// update, or not
self.finish()
} else {
let record = CKRecord(recordType: "Book", recordID: recordID)
let modify = CKModifyRecordsOperation(recordsToSave: [record], recordIDsToDelete: nil)
modify.database = self.database
modify.modifyRecordsCompletionBlock = { saved, _, error in
if let record = saved?.first {
self.record = record
self.finish()
} else {
self.finish(withError: error)
}
}
CloudKitQueue.shared.add(operations: modify)
}
}
CloudKitQueue.shared.add(operations: fetch)
}
}
}
class FetchBookRecordZoneOperation: Procedure {
let database: CKDatabase
let bookID: String
private(set) var recordZone: CKRecordZone?
init(database: CKDatabase, bookID: String) {
self.database = database
self.bookID = bookID
super.init()
}
override func execute() {
let zoneID = CKRecordZoneID(zoneName: bookID, ownerName: CKCurrentUserDefaultName)
let fetch = CKFetchRecordZonesOperation(recordZoneIDs: [zoneID])
fetch.database = database
fetch.fetchRecordZonesCompletionBlock = {zones, error in
if let error = error as? CKError, (error.code == .partialFailure || error.code == .zoneNotFound) {
let zone = CKRecordZone(zoneID: zoneID)
let modify = CKModifyRecordZonesOperation(recordZonesToSave: [zone], recordZoneIDsToDelete: nil)
modify.database = self.database
modify.modifyRecordZonesCompletionBlock = { saved, _, error in
if let zone = saved?.first {
self.recordZone = zone
self.finish()
} else {
self.finish(withError: error)
}
}
CloudKitQueue.shared.add(operations: modify)
} else if let zone = zones?[zoneID] {
self.recordZone = zone
self.finish()
} else {
self.finish(withError: error)
}
}
CloudKitQueue.shared.add(operations: fetch)
}
}

View File

@ -1,57 +0,0 @@
//
// CloudKitOperations.swift
// Kiwix
//
// Created by Chris Li on 11/27/16.
// Copyright © 2016 Chris Li. All rights reserved.
//
import CloudKit
import ProcedureKit
class BookmarkSyncOperation: GroupProcedure {
let articleURL: URL
init(articleURL: URL) {
self.articleURL = articleURL
super.init(operations: [])
}
}
class FetchBookRecordZoneOperation: Procedure, ResultInjection {
let database: CKDatabase
let bookID: String
var requirement: PendingValue<Void> = .void
fileprivate(set) var result: PendingValue<CKRecordZone> = .pending
init(database: CKDatabase, bookID: String) {
self.database = database
self.bookID = bookID
super.init()
}
override func execute() {
let zoneID = CKRecordZoneID(zoneName: bookID, ownerName: CKCurrentUserDefaultName)
let fetch = CKFetchRecordZonesOperation(recordZoneIDs: [zoneID])
fetch.database = database
fetch.fetchRecordZonesCompletionBlock = {zones, error in
if let error = error as? CKError, error.code == .zoneNotFound {
let zone = CKRecordZone(zoneID: zoneID)
let modify = CKModifyRecordZonesOperation(recordZonesToSave: [zone], recordZoneIDsToDelete: nil)
modify.database = self.database
modify.modifyRecordZonesCompletionBlock = { saved, _, error in
if let error = error {
self.finish(withError: error)
} else {
// self.result.value = saved?.first
}
}
} else {
}
}
CloudKitQueue.shared.add(operations: fetch)
}
}