diff --git a/Kiwix-iOS/Info.plist b/Kiwix-iOS/Info.plist
index 9a5605a5..e4f812f2 100644
--- a/Kiwix-iOS/Info.plist
+++ b/Kiwix-iOS/Info.plist
@@ -49,7 +49,7 @@
CFBundleVersion
- 1.8.3557
+ 1.8.3635
ITSAppUsesNonExemptEncryption
LSRequiresIPhoneOS
diff --git a/Kiwix-iOSWidgets/Bookmarks/Info.plist b/Kiwix-iOSWidgets/Bookmarks/Info.plist
index cd8242fe..ab1f1b41 100644
--- a/Kiwix-iOSWidgets/Bookmarks/Info.plist
+++ b/Kiwix-iOSWidgets/Bookmarks/Info.plist
@@ -21,7 +21,7 @@
CFBundleSignature
????
CFBundleVersion
- 1.8.3557
+ 1.8.3635
NSExtension
NSExtensionMainStoryboard
diff --git a/Kiwix.xcodeproj/project.pbxproj b/Kiwix.xcodeproj/project.pbxproj
index f7242f7f..e5956492 100644
--- a/Kiwix.xcodeproj/project.pbxproj
+++ b/Kiwix.xcodeproj/project.pbxproj
@@ -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 = ""; };
973A5C931DEA6CA900C7804C /* URLResponseCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLResponseCache.swift; sourceTree = ""; };
- 973A5C981DEBC54800C7804C /* CloudKitOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CloudKitOperations.swift; sourceTree = ""; };
+ 973A5C981DEBC54800C7804C /* CloudKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CloudKit.swift; sourceTree = ""; };
973BCD001CEB3FA500F10B44 /* Kiwix_OSXTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Kiwix_OSXTests.swift; sourceTree = ""; };
973BCD021CEB3FA500F10B44 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
973BCD0B1CEB3FA500F10B44 /* Kiwix_OSXUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Kiwix_OSXUITests.swift; sourceTree = ""; };
@@ -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 */,
diff --git a/Kiwix.xcworkspace/xcuserdata/chrisli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Kiwix.xcworkspace/xcuserdata/chrisli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
index e2573a59..32e8dcb3 100644
--- a/Kiwix.xcworkspace/xcuserdata/chrisli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
+++ b/Kiwix.xcworkspace/xcuserdata/chrisli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
@@ -13,5 +13,37 @@
stopOnStyle = "0">
+
+
+
+
+
+
+
+
diff --git a/Kiwix/CoreData/Classes/Article.swift b/Kiwix/CoreData/Classes/Article.swift
index cc4ff058..c0c470e6 100644
--- a/Kiwix/CoreData/Classes/Article.swift
+++ b/Kiwix/CoreData/Classes/Article.swift
@@ -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
diff --git a/Kiwix/CoreData/Classes/Book.swift b/Kiwix/CoreData/Classes/Book.swift
index 98561f81..f70a4ebd 100644
--- a/Kiwix/CoreData/Classes/Book.swift
+++ b/Kiwix/CoreData/Classes/Book.swift
@@ -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
diff --git a/Kiwix/Operations/CloudKit.swift b/Kiwix/Operations/CloudKit.swift
new file mode 100644
index 00000000..804f3778
--- /dev/null
+++ b/Kiwix/Operations/CloudKit.swift
@@ -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)
+ }
+}
diff --git a/Kiwix/Operations/CloudKitOperations.swift b/Kiwix/Operations/CloudKitOperations.swift
deleted file mode 100644
index 92a2d675..00000000
--- a/Kiwix/Operations/CloudKitOperations.swift
+++ /dev/null
@@ -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
- fileprivate(set) var result: PendingValue = .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)
- }
-}