From 2f2157d458c0d59ed0af6ac4b9b408ec23625b99 Mon Sep 17 00:00:00 2001 From: Chris Li Date: Mon, 28 Nov 2016 09:53:25 -0500 Subject: [PATCH] commit --- .../Main/Bookmark.imageset/star-3 copy.png | Bin 2194 -> 0 bytes Kiwix-iOS/Controller/Main/MainDelegates.swift | 11 ++++- Kiwix-iOS/Info.plist | 2 +- Kiwix-iOSWidgets/Bookmarks/Info.plist | 2 +- Kiwix.xcodeproj/project.pbxproj | 4 ++ Kiwix/CoreData/Classes/Article.swift | 23 +++++++++- Kiwix/CoreData/Classes/Book.swift | 40 +++++++++++++----- Kiwix/Operations/CloudKitOperations.swift | 20 +++++++++ 8 files changed, 88 insertions(+), 14 deletions(-) delete mode 100644 Kiwix-iOS/Assets.xcassets/Main/Bookmark.imageset/star-3 copy.png create mode 100644 Kiwix/Operations/CloudKitOperations.swift diff --git a/Kiwix-iOS/Assets.xcassets/Main/Bookmark.imageset/star-3 copy.png b/Kiwix-iOS/Assets.xcassets/Main/Bookmark.imageset/star-3 copy.png deleted file mode 100644 index e22bbafe223fee5194672045db64c1921baa7832..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2194 zcmZ`)X*iS(8-47ItuG;jxq9DZXDoxUL|J176Juwj8CwWr&%Tt#mJo($B!oc>*^NEI zYwT-;hHOb`K3d-C-}mSHaqe@SbKmE>f1Xq;gb6Q56a)YOubHVKlED^#z{$#(e$NU@ z8N}*o05<@DhD`1s?raPV_Ao`l0U%Ne0OFDW;FMv-Z394vG5~x+0{|=^0EF)qwOQ*h z7RqG4>I3%GZfc7Q-@#xU@7_oCV#?n1jFROnZb=X*0}k&G%p$aBd^VH&}N1P zHeRb^i&1IQGlCqSC&m@IN13(p`uI4d`=vxH`P-)nvnJG2FUoCls(P&y)aSNu^o!Yf zo9cA9@8Y~YaXPy){iR>OLhh;bqEBrl=XD1%rzp-~^(-#>b@17cYpndm z|+JrR+k0))AJWvAky(rHv z#l8q6ESB*zZ?Sk9>i9}NQQ6gwmOoD8FvQMsRo= zp^J|zdQ!sRGgflehZxJ9z)suJFo@|b32IQIy@S}nXoJg zi@PU-y>Lf8S4HTk3^g}V5zB=_GEGq(23ce-=-qVM2c7WtJm7yVotZal&I!R|yR2|vh-)oOLqR#6{u zIH6X#;5$Q|_7S(PN$B)}&dwkm)q8d{e(Z^pJ%ZfN0XrS*p2B0TKbYd%wFc|m+B4|h zb3{GGlV^07irKChma<+Msp>qGVD}W&SXM(mW`zIoH&17W4`&C+cqyf&QtL8f_|Zb8 zbv2?`MFp13)U%U*Gv}t6Os-0A{)@DXi7LHnP_4gkI)>n6E8JJRYb;|MbFR25_7P+( z_R%`^+x1&D=ULm4fw{0fC8$(ZswPrKjH1TPBL|i3dzaZY++Hq4??7V4FVx8S_{;4_ zUQ=P;7YeMQ5!t+(hc}6o!VmG%bc$+5ifZTMixU`x9H^!s@2c@HG7DFM!>>G>x}eo_ zgme{QdjZcwtBtP*=}&Yo9-pIN?fBe7t9!{15O3ki+|-bHyDlt_B5^H)GPwRS@L=+S z=gPs$)t}Alqi8%?+nlT~ETza;h$50xL&lgqSzkD%@U1UOAZZ2-e z=e&_U?ML4W&aJMU6-{%(gR?L&0#_0pXjSZMbKw#ycWLjT>U4YAZ|@{)e+zbK+t7d5 zl0$L^QrW`ahp}UsQd;|CH`YQk^O4H-Qwo_}TWhwoO@W};ar4ync0*eOH2lOOXheQY zDFV0}DgWx&)lH7GUhIR9`f08uU&^HBcN6i>7NCCQHp;I~QnaAcmn6QrV-`i3XLgp( zF^aD|PWnh;@<8fH>51Z`ueXbr!oEX4GNTT7WN?nUUiNn`KRrT-$k$ts152GQ0J=jc zdefn`#!eAEq{-edYMOqvI$QjJ z>#n{nNqcRtXV7G68EqRM*KkuHrJz8UP%J**pMQ68J28RD$yZo&Ch13f@%f*RNGIl74i@%c-b?IvRrN}PIxxJ|+1TBqh{3GoO1_`+$8+>4$W0%S*wOGclRef5HA z`A2$mOvPIs0xM+9s| z=eIxBc)BNhvQap&G#0rnlIEms^oa-!MqYW{SkO=V+0K2MCV2CQ{7JWtB)W`P*V>-h z^Xi?Bdg|foPDl%#?8o)aCC0;1l0^NHFW;q6LTDA}ki2pisZ={e_x=)AfF`(UO7s

z+OqhU^I@@JznH>Nm7ZEN)vhzkSsQ1+qf*vJcB_SF1#ala+lH$Rz76((w+8Fx4o}3$ zx#Vq>NDHj^+-jK%pWic_@2|6mKSThPq#SbLqNUgZ86CyaZWqArCcLv~r{9?B%55cSj-2?x@t&P_cVaMED6?Bhm)b5C?-u73WvQd>|or2A*w&tVp#A$bZ zH45)9cl-)8d^!2Qs>~iP>oSMcEek47v6%zGow2D$88#%!1C}<>9{v>^S+#)WWm`k> zoJt;AdX=$GUd?0F?-iVpJ?@S>4g>QD!Y~L>QHDSjAP@zJnvJp+OdSeS(Ns`Yhbb#3 zaFZFe|33l0fIHsUi2olrM)4jo0wRAt+zP>l`Bme*a diff --git a/Kiwix-iOS/Controller/Main/MainDelegates.swift b/Kiwix-iOS/Controller/Main/MainDelegates.swift index 6cdfcb37..32d7c353 100644 --- a/Kiwix-iOS/Controller/Main/MainDelegates.swift +++ b/Kiwix-iOS/Controller/Main/MainDelegates.swift @@ -9,6 +9,7 @@ import UIKit import SafariServices import CoreSpotlight +import CloudKit // MARK: - Web @@ -177,7 +178,14 @@ extension MainController: ButtonDelegates { } func syncBookmark(article: Article) { - + guard let record = article.cloudKitRecord else {return} +// guard let book = article.book else {return} +// let record = book.cloudKitRecord + let container = CKContainer(identifier: "iCloud.org.kiwix") + let database = container.privateCloudDatabase + database.save(record, completionHandler: {record, error in + print(error?.localizedDescription) + }) } guard let url = webView.request?.url, @@ -189,6 +197,7 @@ extension MainController: ButtonDelegates { buttons.bookmark.isHighlighted = article.isBookmarked indexBookmark(article: article) + let op = Art syncBookmark(article: article) } } diff --git a/Kiwix-iOS/Info.plist b/Kiwix-iOS/Info.plist index 972a6868..2bdc479b 100644 --- a/Kiwix-iOS/Info.plist +++ b/Kiwix-iOS/Info.plist @@ -49,7 +49,7 @@ CFBundleVersion - 1.8.3483 + 1.8.3509 ITSAppUsesNonExemptEncryption LSRequiresIPhoneOS diff --git a/Kiwix-iOSWidgets/Bookmarks/Info.plist b/Kiwix-iOSWidgets/Bookmarks/Info.plist index c55b169b..5afef6ec 100644 --- a/Kiwix-iOSWidgets/Bookmarks/Info.plist +++ b/Kiwix-iOSWidgets/Bookmarks/Info.plist @@ -21,7 +21,7 @@ CFBundleSignature ???? CFBundleVersion - 1.8.3483 + 1.8.3509 NSExtension NSExtensionMainStoryboard diff --git a/Kiwix.xcodeproj/project.pbxproj b/Kiwix.xcodeproj/project.pbxproj index ca383d0e..f7242f7f 100644 --- a/Kiwix.xcodeproj/project.pbxproj +++ b/Kiwix.xcodeproj/project.pbxproj @@ -44,6 +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 */; }; 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 */; }; @@ -191,6 +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 = ""; }; 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 = ""; }; @@ -786,6 +788,7 @@ 97D6811C1D6F70AC00E5FA99 /* GlobalQueue.swift */, 9764CBD21D8083AA00072D6A /* ArticleOperation.swift */, 970A2A211DD562CB0078BB7C /* BookOperations.swift */, + 973A5C981DEBC54800C7804C /* CloudKitOperations.swift */, 973208281DD223DB00EDD3DC /* RefreshLibrary.swift */, 97D6811E1D6F70AC00E5FA99 /* ScanLocalBook.swift */, 972F81561DDBFC79008D7289 /* Search.swift */, @@ -1176,6 +1179,7 @@ 97A1FD261D6F71E200A80EE2 /* ZimReader.mm in Sources */, 97A1FD1C1D6F71D800A80EE2 /* KiwixURLProtocol.swift in Sources */, 97C2C26A1DDCC58500A9CC64 /* ArticleOperation.swift in Sources */, + 973A5C991DEBC54800C7804C /* CloudKitOperations.swift in Sources */, 973208261DD21E9C00EDD3DC /* CoreDataContainer.swift in Sources */, 97D6813F1D6F712800E5FA99 /* Article+CoreDataProperties.swift in Sources */, 97A1FD441D6F728200A80EE2 /* Preference.swift in Sources */, diff --git a/Kiwix/CoreData/Classes/Article.swift b/Kiwix/CoreData/Classes/Article.swift index 8ef8587e..cc4ff058 100644 --- a/Kiwix/CoreData/Classes/Article.swift +++ b/Kiwix/CoreData/Classes/Article.swift @@ -8,9 +8,12 @@ import CoreData import CoreSpotlight +import CloudKit class Article: NSManagedObject { + // MARK: - Fetch + class func fetch(url: URL, context: NSManagedObjectContext) -> Article? { guard let bookID = url.host, let book = Book.fetch(bookID, context: context) else {return nil} @@ -42,6 +45,8 @@ class Article: NSManagedObject { return fetch(request, type: Article.self, context: context) ?? [Article]() } + // MARK: - CoreSpotlight + var searchableItem: CSSearchableItem { let attributeSet = CSSearchableItemAttributeSet() attributeSet.title = title @@ -54,7 +59,23 @@ class Article: NSManagedObject { return CSSearchableItem(uniqueIdentifier: url?.absoluteString, domainIdentifier: book?.id, attributeSet: attributeSet) } - // MARK: - Helper + // 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 + } + + // MARK: - Properties var url: URL? { guard let bookID = book?.id else {return nil} diff --git a/Kiwix/CoreData/Classes/Book.swift b/Kiwix/CoreData/Classes/Book.swift index ab738ead..c2ea3624 100644 --- a/Kiwix/CoreData/Classes/Book.swift +++ b/Kiwix/CoreData/Classes/Book.swift @@ -8,6 +8,7 @@ import Foundation import CoreData +import CloudKit #if os(iOS) || os(watchOS) || os(tvOS) import UIKit #elseif os(OSX) @@ -16,7 +17,7 @@ import CoreData class Book: NSManagedObject { - // MARK: - Add Book + // MARK: - Add class func add(meta: [String: String], in context: NSManagedObjectContext) -> Book? { guard let id = meta["id"] else {return nil} @@ -74,15 +75,6 @@ class Book: NSManagedObject { return book } - // MARK: - Properties - - var url: URL? { - guard let meta4URL = meta4URL else {return nil} - var urlComponents = URLComponents(string: meta4URL.replacingOccurrences(of: ".meta4", with: "")) - urlComponents?.scheme = "https" - return urlComponents?.url - } - // MARK: - Fetch class func fetchAll(in context: NSManagedObjectContext) -> [Book] { @@ -109,6 +101,34 @@ class Book: NSManagedObject { return fetch(fetchRequest, type: Book.self, context: context) ?? [Book]() } + // MARK: - CloudKit + + var cloudKitRecord: CKRecord { + let recordID = CKRecordID(recordName: id) + 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 + + var url: URL? { + guard let meta4URL = meta4URL else {return nil} + var urlComponents = URLComponents(string: meta4URL.replacingOccurrences(of: ".meta4", with: "")) + urlComponents?.scheme = "https" + return urlComponents?.url + } + // MARK: - Manage func removeResumeData() { diff --git a/Kiwix/Operations/CloudKitOperations.swift b/Kiwix/Operations/CloudKitOperations.swift new file mode 100644 index 00000000..47eafad1 --- /dev/null +++ b/Kiwix/Operations/CloudKitOperations.swift @@ -0,0 +1,20 @@ +// +// CloudKitOperations.swift +// Kiwix +// +// Created by Chris Li on 11/27/16. +// Copyright © 2016 Chris Li. All rights reserved. +// + +import CloudKit +import ProcedureKit + +class BookmarkSyncOperation: Procedure { + let articleURL: URL + + init(articleURL: URL) { + self.articleURL = articleURL + super.init() + } + +}