From dbf9f5dc421f1388536649243037017d08a983a7 Mon Sep 17 00:00:00 2001 From: Chris Li Date: Thu, 21 Jul 2016 15:20:08 -0400 Subject: [PATCH] A working today widget prototype --- Articles.entitlements | 10 ++ Kiwix-iOS/Controller/BookmarkTBVC.swift | 23 ++-- .../Main/MainControllerDelegates.swift | 3 + Kiwix-iOS/Info.plist | 2 +- Kiwix-iOS/Kiwix.entitlements | 10 ++ .../Base.lproj/MainInterface.storyboard | 75 +++++++++++- .../Articles/BookmarkWidgetCell.swift | 22 ++++ .../Articles/TodayViewController.swift | 75 +++++++++++- Kiwix.xcodeproj/project.pbxproj | 32 +++++- .../xcschemes/Kiwix-iOS.xcscheme | 2 +- .../xcschemes/Kiwix-iOSWidget.xcscheme | 108 ------------------ .../xcschemes/xcschememanagement.plist | 5 - Kiwix/CoreData/Article.swift | 22 ++++ .../UpdateWidgetDataSourceOperation.swift | 44 +++++++ Kiwix/Tools/ArticleDataContainer.swift | 31 +++++ 15 files changed, 334 insertions(+), 130 deletions(-) create mode 100644 Articles.entitlements create mode 100644 Kiwix-iOS/Kiwix.entitlements create mode 100644 Kiwix-iOSWidgets/Articles/BookmarkWidgetCell.swift delete mode 100644 Kiwix.xcodeproj/xcuserdata/Chrisli.xcuserdatad/xcschemes/Kiwix-iOSWidget.xcscheme create mode 100644 Kiwix/Operations/UpdateWidgetDataSourceOperation.swift create mode 100644 Kiwix/Tools/ArticleDataContainer.swift diff --git a/Articles.entitlements b/Articles.entitlements new file mode 100644 index 00000000..91646974 --- /dev/null +++ b/Articles.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.application-groups + + group.kiwix + + + diff --git a/Kiwix-iOS/Controller/BookmarkTBVC.swift b/Kiwix-iOS/Controller/BookmarkTBVC.swift index 56d1a010..d5d74778 100644 --- a/Kiwix-iOS/Controller/BookmarkTBVC.swift +++ b/Kiwix-iOS/Controller/BookmarkTBVC.swift @@ -35,6 +35,11 @@ class BookmarkTBVC: UITableViewController, NSFetchedResultsControllerDelegate, D navigationController?.setToolbarHidden(!editing, animated: animated) } + func updateWidgetData() { + let operation = UpdateWidgetDataSourceOperation() + GlobalOperationQueue.sharedInstance.addOperation(operation) + } + // MARK: - Empty table datasource & delegate func imageForEmptyDataSet(scrollView: UIScrollView!) -> UIImage! { @@ -92,16 +97,8 @@ class BookmarkTBVC: UITableViewController, NSFetchedResultsControllerDelegate, D guard let article = fetchedResultController.objectAtIndexPath(indexPath) as? Article else {return} cell.thumbImageView.image = { - if let urlString = article.thumbImageURL, - let url = NSURL(string: urlString), - let data = NSData(contentsOfURL: url), - let image = UIImage(data: data) { - return image - } else if let bookFavIconImageData = article.book?.favIcon { - return UIImage(data: bookFavIconImageData) - } else { - return nil - } + guard let data = article.thumbImageData else {return nil} + return UIImage(data: data) }() cell.titleLabel.text = article.title cell.subtitleLabel.text = article.book?.title @@ -135,6 +132,7 @@ class BookmarkTBVC: UITableViewController, NSFetchedResultsControllerDelegate, D override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? { let remove = UITableViewRowAction(style: .Destructive, title: LocalizedStrings.remove) { (action, indexPath) -> Void in guard let article = self.fetchedResultController.objectAtIndexPath(indexPath) as? Article else {return} + self.updateWidgetData() let context = NSManagedObjectContext.mainQueueContext context.performBlockAndWait({ () -> Void in context.deleteObject(article) @@ -208,6 +206,11 @@ class BookmarkTBVC: UITableViewController, NSFetchedResultsControllerDelegate, D guard editing else {return} guard let selectedIndexPathes = tableView.indexPathsForSelectedRows else {return} let artiicles = selectedIndexPathes.flatMap() {fetchedResultController.objectAtIndexPath($0) as? Article} + + if artiicles.count > 0 { + updateWidgetData() + } + let context = NSManagedObjectContext.mainQueueContext context.performBlock { artiicles.forEach() { diff --git a/Kiwix-iOS/Controller/Main/MainControllerDelegates.swift b/Kiwix-iOS/Controller/Main/MainControllerDelegates.swift index af84fba4..3c1d151e 100644 --- a/Kiwix-iOS/Controller/Main/MainControllerDelegates.swift +++ b/Kiwix-iOS/Controller/Main/MainControllerDelegates.swift @@ -29,6 +29,9 @@ extension MainController: LPTBarButtonItemDelegate, TableOfContentsDelegate, Zim if article.isBookmarked {article.bookmarkDate = NSDate()} if article.snippet == nil {article.snippet = getSnippet(webView)} + let operation = UpdateWidgetDataSourceOperation() + GlobalOperationQueue.sharedInstance.addOperation(operation) + guard let controller = bookmarkController ?? UIStoryboard.main.initViewController("BookmarkController", type: BookmarkController.self) else {return} bookmarkController = controller controller.bookmarkAdded = article.isBookmarked diff --git a/Kiwix-iOS/Info.plist b/Kiwix-iOS/Info.plist index da8b3aae..cc62a14f 100644 --- a/Kiwix-iOS/Info.plist +++ b/Kiwix-iOS/Info.plist @@ -36,7 +36,7 @@ CFBundleSignature ???? CFBundleVersion - 1.7.352 + 1.7.448 ITSAppUsesNonExemptEncryption LSRequiresIPhoneOS diff --git a/Kiwix-iOS/Kiwix.entitlements b/Kiwix-iOS/Kiwix.entitlements new file mode 100644 index 00000000..91646974 --- /dev/null +++ b/Kiwix-iOS/Kiwix.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.application-groups + + group.kiwix + + + diff --git a/Kiwix-iOSWidgets/Articles/Base.lproj/MainInterface.storyboard b/Kiwix-iOSWidgets/Articles/Base.lproj/MainInterface.storyboard index dec9a6af..6d8ffc6c 100644 --- a/Kiwix-iOSWidgets/Articles/Base.lproj/MainInterface.storyboard +++ b/Kiwix-iOSWidgets/Articles/Base.lproj/MainInterface.storyboard @@ -3,6 +3,7 @@ + @@ -14,15 +15,85 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + diff --git a/Kiwix-iOSWidgets/Articles/BookmarkWidgetCell.swift b/Kiwix-iOSWidgets/Articles/BookmarkWidgetCell.swift new file mode 100644 index 00000000..f4794e7a --- /dev/null +++ b/Kiwix-iOSWidgets/Articles/BookmarkWidgetCell.swift @@ -0,0 +1,22 @@ +// +// BookmarkWidgetCell.swift +// Kiwix +// +// Created by Chris Li on 7/20/16. +// Copyright © 2016 Chris. All rights reserved. +// + +import UIKit + +class BookmarkWidgetCell: UICollectionViewCell { + override func awakeFromNib() { + imageView.layer.masksToBounds = true + imageView.layer.cornerRadius = 4.0 + imageBackgroundView.layer.masksToBounds = true + imageBackgroundView.layer.cornerRadius = 6.0 + } + + @IBOutlet weak var imageView: UIImageView! + @IBOutlet weak var imageBackgroundView: UIView! + @IBOutlet weak var label: UILabel! +} diff --git a/Kiwix-iOSWidgets/Articles/TodayViewController.swift b/Kiwix-iOSWidgets/Articles/TodayViewController.swift index dab6a283..65c42925 100644 --- a/Kiwix-iOSWidgets/Articles/TodayViewController.swift +++ b/Kiwix-iOSWidgets/Articles/TodayViewController.swift @@ -9,17 +9,39 @@ import UIKit import NotificationCenter -class TodayViewController: UIViewController, NCWidgetProviding { +class TodayViewController: UIViewController, NCWidgetProviding, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { + @IBOutlet weak var collectionView: UICollectionView! + + private var rowHeight: CGFloat = 110.0 + private let hSpacing: CGFloat = 15.0 + private var titles = [String]() + private var thumbDatas = [NSData]() + override func viewDidLoad() { super.viewDidLoad() - // Do any additional setup after loading the view from its nib. + collectionView.dataSource = self + collectionView.delegate = self + preferredContentSize = CGSizeMake(0, rowHeight) + updateData() + } + + override func viewWillAppear(animated: Bool) { + super.viewWillAppear(animated) + updateData() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } + + + // MARK: - NCWidgetProviding + + func widgetMarginInsetsForProposedMarginInsets(defaultMarginInsets: UIEdgeInsets) -> UIEdgeInsets { + return UIEdgeInsetsZero + } func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)) { // Perform any setup necessary in order to update the view. @@ -28,7 +50,56 @@ class TodayViewController: UIViewController, NCWidgetProviding { // If there's no update required, use NCUpdateResult.NoData // If there's an update, use NCUpdateResult.NewData + updateData() + completionHandler(NCUpdateResult.NewData) } + func updateData() { + let defaults = NSUserDefaults(suiteName: "group.kiwix") + guard let bookmarks = defaults?.objectForKey("bookmarks") as? [String: NSArray], + let titles = bookmarks["titles"] as? [String], + let thumbDatas = bookmarks["thumbDatas"] as? [NSData] else {return} + self.titles = titles + self.thumbDatas = thumbDatas + collectionView.reloadData() + } + + // MARK: - UICollectionView + + func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { + return 1 + } + + func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return titles.count + } + + func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCellWithReuseIdentifier("BookmarkWidgetCell", forIndexPath: indexPath) + configureCell(cell, atIndexPath: indexPath) + return cell + } + + func configureCell(cell: UICollectionViewCell, atIndexPath indexPath: NSIndexPath) { + guard let cell = cell as? BookmarkWidgetCell else {return} + cell.label.text = titles[indexPath.item] + cell.imageView.image = UIImage(data: thumbDatas[indexPath.item]) + } + + // MARK: - UICollectionViewDelegateFlowLayout + + func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { + let sectionInset = self.collectionView(collectionView, layout: collectionViewLayout, insetForSectionAtIndex: indexPath.section) + let itemWidth = (collectionView.frame.width - 6 * hSpacing) / 5.0 + return CGSizeMake(itemWidth, rowHeight - sectionInset.top - sectionInset.bottom) + } + + func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat { + return 0.0 + } + + func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets { + return UIEdgeInsetsMake(10, hSpacing, 10, hSpacing) + } } diff --git a/Kiwix.xcodeproj/project.pbxproj b/Kiwix.xcodeproj/project.pbxproj index 932031a6..365d968c 100644 --- a/Kiwix.xcodeproj/project.pbxproj +++ b/Kiwix.xcodeproj/project.pbxproj @@ -93,6 +93,10 @@ 971A107F1D022F74007FC62C /* ImportBookLearnMore.html in Resources */ = {isa = PBXBuildFile; fileRef = 971A107B1D022F74007FC62C /* ImportBookLearnMore.html */; }; 971A10801D022F74007FC62C /* Pic_I.png in Resources */ = {isa = PBXBuildFile; fileRef = 971A107C1D022F74007FC62C /* Pic_I.png */; }; 971A10811D022F74007FC62C /* Pic_P.png in Resources */ = {isa = PBXBuildFile; fileRef = 971A107D1D022F74007FC62C /* Pic_P.png */; }; + 971C4F0E1D400F010027B7D2 /* UpdateWidgetDataSourceOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 971C4F0D1D400F010027B7D2 /* UpdateWidgetDataSourceOperation.swift */; }; + 971C4F121D4020E90027B7D2 /* BookmarkWidgetCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 971C4F111D4020E90027B7D2 /* BookmarkWidgetCell.swift */; }; + 971C4F141D411DC00027B7D2 /* ArticleDataContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 971C4F131D411DC00027B7D2 /* ArticleDataContainer.swift */; }; + 971C4F151D411DC00027B7D2 /* ArticleDataContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 971C4F131D411DC00027B7D2 /* ArticleDataContainer.swift */; }; 97219DBD1D383A00009FDFF1 /* BookmarkController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97219DBC1D383A00009FDFF1 /* BookmarkController.swift */; }; 9722121C1D3ECCFE00C0DCF2 /* NotificationCenter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97E609F01D103DED00EBCB9D /* NotificationCenter.framework */; }; 9722121F1D3ECCFE00C0DCF2 /* TodayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9722121E1D3ECCFE00C0DCF2 /* TodayViewController.swift */; }; @@ -335,6 +339,11 @@ 971A107B1D022F74007FC62C /* ImportBookLearnMore.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = ImportBookLearnMore.html; path = Kiwix/HelpDocuments/ImportBookLearnMore.html; sourceTree = SOURCE_ROOT; }; 971A107C1D022F74007FC62C /* Pic_I.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Pic_I.png; path = Kiwix/HelpDocuments/Pic_I.png; sourceTree = SOURCE_ROOT; }; 971A107D1D022F74007FC62C /* Pic_P.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Pic_P.png; path = Kiwix/HelpDocuments/Pic_P.png; sourceTree = SOURCE_ROOT; }; + 971C4F0B1D3FFFA60027B7D2 /* Kiwix.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = Kiwix.entitlements; path = "Kiwix-iOS/Kiwix.entitlements"; sourceTree = SOURCE_ROOT; }; + 971C4F0C1D3FFFFF0027B7D2 /* Articles.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = Articles.entitlements; path = ../../Articles.entitlements; sourceTree = ""; }; + 971C4F0D1D400F010027B7D2 /* UpdateWidgetDataSourceOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = UpdateWidgetDataSourceOperation.swift; path = Operations/UpdateWidgetDataSourceOperation.swift; sourceTree = ""; }; + 971C4F111D4020E90027B7D2 /* BookmarkWidgetCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarkWidgetCell.swift; sourceTree = ""; }; + 971C4F131D411DC00027B7D2 /* ArticleDataContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ArticleDataContainer.swift; path = Kiwix/Tools/ArticleDataContainer.swift; sourceTree = ""; }; 97219DBC1D383A00009FDFF1 /* BookmarkController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BookmarkController.swift; path = "Kiwix-iOS/Controller/Bookmark/BookmarkController.swift"; sourceTree = SOURCE_ROOT; }; 9722121B1D3ECCFE00C0DCF2 /* Articles.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = Articles.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 9722121E1D3ECCFE00C0DCF2 /* TodayViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayViewController.swift; sourceTree = ""; }; @@ -718,8 +727,10 @@ 9722121D1D3ECCFE00C0DCF2 /* Articles */ = { isa = PBXGroup; children = ( - 9722121E1D3ECCFE00C0DCF2 /* TodayViewController.swift */, + 971C4F0C1D3FFFFF0027B7D2 /* Articles.entitlements */, 972212201D3ECCFE00C0DCF2 /* MainInterface.storyboard */, + 9722121E1D3ECCFE00C0DCF2 /* TodayViewController.swift */, + 971C4F111D4020E90027B7D2 /* BookmarkWidgetCell.swift */, 972212231D3ECCFE00C0DCF2 /* Info.plist */, ); path = Articles; @@ -813,6 +824,7 @@ 97E891681CA976E90001CA32 /* FileManager.swift */, 973C8D5B1C25F945007272F9 /* Preference.swift */, 979C51511CECA9AF001707F2 /* StringTools.swift */, + 971C4F131D411DC00027B7D2 /* ArticleDataContainer.swift */, ); name = Tools; sourceTree = ""; @@ -912,6 +924,7 @@ 978C58791C1CCC920077AE47 /* Supporting */ = { isa = PBXGroup; children = ( + 971C4F0B1D3FFFA60027B7D2 /* Kiwix.entitlements */, 971A10791D022F05007FC62C /* Localizable.stringsdict */, 971A10191D0228E8007FC62C /* JavaScripts */, 975227CF1D022814001D1DDE /* LaunchScreen.storyboard */, @@ -1093,6 +1106,7 @@ 9779A1C51D34225E0071EFAB /* RefreshLibraryOperation.swift */, 973DD4241D344558009D45DB /* ScanLocalBookOperation.swift */, 9779A1C61D34225E0071EFAB /* SearchOperation.swift */, + 971C4F0D1D400F010027B7D2 /* UpdateWidgetDataSourceOperation.swift */, 970C61961D34243600087758 /* URLSessionDownloadTaskOperation.swift */, ); name = Operation; @@ -1279,6 +1293,11 @@ 9722121A1D3ECCFE00C0DCF2 = { CreatedOnToolsVersion = 7.3.1; DevelopmentTeam = L7HWM3SP3L; + SystemCapabilities = { + com.apple.ApplicationGroups.iOS = { + enabled = 1; + }; + }; }; 973BCCE81CEB3FA400F10B44 = { CreatedOnToolsVersion = 7.3.1; @@ -1295,6 +1314,9 @@ CreatedOnToolsVersion = 7.2; DevelopmentTeam = L7HWM3SP3L; SystemCapabilities = { + com.apple.ApplicationGroups.iOS = { + enabled = 1; + }; com.apple.BackgroundModes = { enabled = 0; }; @@ -1535,7 +1557,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 971C4F121D4020E90027B7D2 /* BookmarkWidgetCell.swift in Sources */, 9722121F1D3ECCFE00C0DCF2 /* TodayViewController.swift in Sources */, + 971C4F151D411DC00027B7D2 /* ArticleDataContainer.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1626,6 +1650,7 @@ 9779A1CC1D34225E0071EFAB /* SearchOperation.swift in Sources */, 97BAA8EC1D3D2D7B0038F57F /* PacketAnalyzer.swift in Sources */, 970E68BA1D3809A3001E8514 /* MainController.swift in Sources */, + 971C4F141D411DC00027B7D2 /* ArticleDataContainer.swift in Sources */, 970C65501D398D5A007032F8 /* BookmarkControllerAnimator.swift in Sources */, 978C58981C1CD86E0077AE47 /* Book.swift in Sources */, 978C58961C1CD86E0077AE47 /* Language.swift in Sources */, @@ -1662,6 +1687,7 @@ 9779A1C81D34225E0071EFAB /* AlertOperation.swift in Sources */, 971A104B1D022CBE007FC62C /* SearchBooksVC.swift in Sources */, 977998771C1E0B7900B1DD5E /* Article+CoreDataProperties.swift in Sources */, + 971C4F0E1D400F010027B7D2 /* UpdateWidgetDataSourceOperation.swift in Sources */, 971187301CEB50FC00B9909D /* ZimReader.mm in Sources */, 971A103C1D022C2C007FC62C /* FontSizeTBVC.swift in Sources */, 971A103B1D022C2C007FC62C /* AdjustLayoutTBVC.swift in Sources */, @@ -1757,6 +1783,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_ENTITLEMENTS = Articles.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; INFOPLIST_FILE = "Kiwix-iOSWidgets/Articles/Info.plist"; @@ -1772,6 +1799,7 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ANALYZER_NONNULL = YES; + CODE_SIGN_ENTITLEMENTS = Articles.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; INFOPLIST_FILE = "Kiwix-iOSWidgets/Articles/Info.plist"; @@ -2002,6 +2030,7 @@ CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = "Kiwix-iOS/Kiwix.entitlements"; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; @@ -2036,6 +2065,7 @@ CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = "Kiwix-iOS/Kiwix.entitlements"; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; diff --git a/Kiwix.xcodeproj/xcuserdata/Chrisli.xcuserdatad/xcschemes/Kiwix-iOS.xcscheme b/Kiwix.xcodeproj/xcuserdata/Chrisli.xcuserdatad/xcschemes/Kiwix-iOS.xcscheme index e4e71124..e0af121d 100644 --- a/Kiwix.xcodeproj/xcuserdata/Chrisli.xcuserdatad/xcschemes/Kiwix-iOS.xcscheme +++ b/Kiwix.xcodeproj/xcuserdata/Chrisli.xcuserdatad/xcschemes/Kiwix-iOS.xcscheme @@ -65,7 +65,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "1" + launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" diff --git a/Kiwix.xcodeproj/xcuserdata/Chrisli.xcuserdatad/xcschemes/Kiwix-iOSWidget.xcscheme b/Kiwix.xcodeproj/xcuserdata/Chrisli.xcuserdatad/xcschemes/Kiwix-iOSWidget.xcscheme deleted file mode 100644 index 96befb57..00000000 --- a/Kiwix.xcodeproj/xcuserdata/Chrisli.xcuserdatad/xcschemes/Kiwix-iOSWidget.xcscheme +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Kiwix.xcodeproj/xcuserdata/Chrisli.xcuserdatad/xcschemes/xcschememanagement.plist b/Kiwix.xcodeproj/xcuserdata/Chrisli.xcuserdatad/xcschemes/xcschememanagement.plist index 56baf3fc..8157e3d0 100644 --- a/Kiwix.xcodeproj/xcuserdata/Chrisli.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Kiwix.xcodeproj/xcuserdata/Chrisli.xcuserdatad/xcschemes/xcschememanagement.plist @@ -19,11 +19,6 @@ orderHint 0 - Kiwix-iOSWidget.xcscheme - - orderHint - 8 - SuppressBuildableAutocreation diff --git a/Kiwix/CoreData/Article.swift b/Kiwix/CoreData/Article.swift index d237d675..d444498f 100644 --- a/Kiwix/CoreData/Article.swift +++ b/Kiwix/CoreData/Article.swift @@ -24,9 +24,31 @@ class Article: NSManagedObject { return article } + class func fetchRecentFiveBookmarks(context: NSManagedObjectContext) -> [Article] { + let fetchRequest = NSFetchRequest(entityName: "Article") + let dateDescriptor = NSSortDescriptor(key: "bookmarkDate", ascending: false) + let titleDescriptor = NSSortDescriptor(key: "title", ascending: true) + fetchRequest.sortDescriptors = [dateDescriptor, titleDescriptor] + fetchRequest.predicate = NSPredicate(format: "isBookmarked == true") + fetchRequest.fetchLimit = 5 + return fetch(fetchRequest, type: Article.self, context: context) ?? [Article]() + } + + // MARK: - Helper + var url: NSURL? { guard let urlString = urlString else {return nil} return NSURL(string: urlString) } + + var thumbImageData: NSData? { + if let urlString = thumbImageURL, + let url = NSURL(string: urlString), + let data = NSData(contentsOfURL: url) { + return data + } else { + return book?.favIcon + } + } } diff --git a/Kiwix/Operations/UpdateWidgetDataSourceOperation.swift b/Kiwix/Operations/UpdateWidgetDataSourceOperation.swift new file mode 100644 index 00000000..6a4eb67b --- /dev/null +++ b/Kiwix/Operations/UpdateWidgetDataSourceOperation.swift @@ -0,0 +1,44 @@ +// +// UpdateWidgetDataSourceOperation.swift +// Kiwix +// +// Created by Chris Li on 7/20/16. +// Copyright © 2016 Chris. All rights reserved. +// + +import CoreData +import PSOperations + +class UpdateWidgetDataSourceOperation: Operation { + let context: NSManagedObjectContext + + override init() { + self.context = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType) + context.parentContext = NSManagedObjectContext.mainQueueContext + context.mergePolicy = NSOverwriteMergePolicy + super.init() + name = String(self) + } + + override func execute() { + let defaults = NSUserDefaults(suiteName: "group.kiwix") + + var articles = [Article]() + context.performBlockAndWait { + articles = Article.fetchRecentFiveBookmarks(self.context) + } + + var titles = [String]() + var thumbDatas = [NSData]() + for article in articles { + guard let title = article.title, + let data = article.thumbImageData else {continue} + titles.append(title) + thumbDatas.append(data) + } + let bookmarks = ["titles": titles, "thumbDatas": thumbDatas] + defaults?.setObject(bookmarks, forKey: "bookmarks") + + finish() + } +} diff --git a/Kiwix/Tools/ArticleDataContainer.swift b/Kiwix/Tools/ArticleDataContainer.swift new file mode 100644 index 00000000..f995d443 --- /dev/null +++ b/Kiwix/Tools/ArticleDataContainer.swift @@ -0,0 +1,31 @@ +// +// ArticleDataContainer.swift +// Kiwix +// +// Created by Chris Li on 7/21/16. +// Copyright © 2016 Chris. All rights reserved. +// + +import UIKit + +class ArticleDataContainer: NSObject, NSCoding { + let title: String + let thumbImageData: NSData + + init(title: String, thumbImageData: NSData) { + self.title = title + self.thumbImageData = thumbImageData + } + + required convenience init?(coder aDecoder: NSCoder) { + guard let title = aDecoder.decodeObjectForKey("title") as? String, + let thumbImageData = aDecoder.decodeObjectForKey("thumbImageData") as? NSData else {return nil} + self.init(title: title, thumbImageData: thumbImageData) + } + + func encodeWithCoder(aCoder: NSCoder) { + aCoder.encodeObject(title, forKey: "title") + aCoder.encodeObject(thumbImageData, forKey: "thumbImageData") + } + +}