diff --git a/Example/RealmContent.xcodeproj/project.pbxproj b/Example/RealmContent.xcodeproj/project.pbxproj index 281647e..d1a029a 100644 --- a/Example/RealmContent.xcodeproj/project.pbxproj +++ b/Example/RealmContent.xcodeproj/project.pbxproj @@ -14,6 +14,9 @@ 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; }; + 9C027FB91F14D30600D1E781 /* StoreViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C027FB81F14D30600D1E781 /* StoreViewController.swift */; }; + 9C027FBB1F14D40200D1E781 /* PageCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C027FBA1F14D40200D1E781 /* PageCellView.swift */; }; + 9C027FBD1F14D4C600D1E781 /* ProductCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C027FBC1F14D4C600D1E781 /* ProductCellView.swift */; }; 9CB782231F1394A000FE1828 /* PageCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CB782221F1394A000FE1828 /* PageCollectionViewCell.swift */; }; 9CB782251F13966900FE1828 /* CustomCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CB782241F13966900FE1828 /* CustomCollectionViewController.swift */; }; 9CB782271F13C03C00FE1828 /* DemosTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CB782261F13C03C00FE1828 /* DemosTableViewController.swift */; }; @@ -51,6 +54,9 @@ 79587B91D264E98BB4B38592 /* Pods-RealmContent_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RealmContent_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RealmContent_Tests/Pods-RealmContent_Tests.release.xcconfig"; sourceTree = ""; }; 91887025475E5527D73EE4E9 /* Pods-RealmContent_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RealmContent_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RealmContent_Example/Pods-RealmContent_Example.debug.xcconfig"; sourceTree = ""; }; 9B388CBFD66930A128F34526 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; + 9C027FB81F14D30600D1E781 /* StoreViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoreViewController.swift; sourceTree = ""; }; + 9C027FBA1F14D40200D1E781 /* PageCellView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PageCellView.swift; sourceTree = ""; }; + 9C027FBC1F14D4C600D1E781 /* ProductCellView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProductCellView.swift; sourceTree = ""; }; 9CB782221F1394A000FE1828 /* PageCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PageCollectionViewCell.swift; sourceTree = ""; }; 9CB782241F13966900FE1828 /* CustomCollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomCollectionViewController.swift; sourceTree = ""; }; 9CB782261F13C03C00FE1828 /* DemosTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DemosTableViewController.swift; sourceTree = ""; }; @@ -114,6 +120,7 @@ 607FACD21AFB9204008FA782 /* Example for RealmContent */ = { isa = PBXGroup; children = ( + 9C027FB71F14CFD600D1E781 /* App Demo */, 9CB782211F13948500FE1828 /* List Style Demos */, 9CB7EF7F1F0C1D5400E70F21 /* Assets */, 9CB7EF791F0C0F1700E70F21 /* Entities */, @@ -172,6 +179,16 @@ name = Pods; sourceTree = ""; }; + 9C027FB71F14CFD600D1E781 /* App Demo */ = { + isa = PBXGroup; + children = ( + 9C027FB81F14D30600D1E781 /* StoreViewController.swift */, + 9C027FBA1F14D40200D1E781 /* PageCellView.swift */, + 9C027FBC1F14D4C600D1E781 /* ProductCellView.swift */, + ); + name = "App Demo"; + sourceTree = ""; + }; 9CB782211F13948500FE1828 /* List Style Demos */ = { isa = PBXGroup; children = ( @@ -408,8 +425,11 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9C027FBB1F14D40200D1E781 /* PageCellView.swift in Sources */, + 9C027FB91F14D30600D1E781 /* StoreViewController.swift in Sources */, 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, 9CB7EF7E1F0C14A100E70F21 /* DemoData.swift in Sources */, + 9C027FBD1F14D4C600D1E781 /* ProductCellView.swift in Sources */, 9CB782231F1394A000FE1828 /* PageCollectionViewCell.swift in Sources */, 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, 9CB782271F13C03C00FE1828 /* DemosTableViewController.swift in Sources */, diff --git a/Example/RealmContent/AppDelegate.swift b/Example/RealmContent/AppDelegate.swift index 54567a1..65e2010 100644 --- a/Example/RealmContent/AppDelegate.swift +++ b/Example/RealmContent/AppDelegate.swift @@ -36,7 +36,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate { private func showMainViewController(success: Bool = true) { let storyboard = self.window!.rootViewController!.storyboard! - self.window!.rootViewController = storyboard.instantiateViewController(withIdentifier: "Main") + let menu = storyboard.instantiateViewController(withIdentifier: "Main") + self.window!.rootViewController = menu + + if !success { + let alert = UIAlertController(title: "Couldn't connect to \(host)", message: "Still fine though! The demo app will use temporarily a local Realm file.\n----------------\n For a syncing demo start your ROS, adjust connection details in AppDelegate.swift, and restart the app.", preferredStyle: .alert) + alert.addAction(UIAlertAction(title: "Close", style: .default, handler: { _ in + menu.dismiss(animated: true, completion: nil) + })) + menu.present(alert, animated: true, completion: nil) + } } } @@ -52,7 +61,6 @@ extension AppDelegate { DispatchQueue.main.async { completion(false) } return } - var conf = Realm.Configuration.defaultConfiguration conf.syncConfiguration = SyncConfiguration(user: user, realmURL: URL(string: "realm://\(host):9080/~/realmcontenttest1")!) Realm.Configuration.defaultConfiguration = conf diff --git a/Example/RealmContent/Base.lproj/Main.storyboard b/Example/RealmContent/Base.lproj/Main.storyboard index 77b1412..996bbcb 100644 --- a/Example/RealmContent/Base.lproj/Main.storyboard +++ b/Example/RealmContent/Base.lproj/Main.storyboard @@ -6,6 +6,7 @@ + @@ -18,10 +19,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -46,7 +76,7 @@ - + @@ -71,7 +101,7 @@ - + @@ -96,7 +126,7 @@ - + @@ -125,7 +155,7 @@ - + @@ -150,7 +180,7 @@ - + @@ -175,7 +205,7 @@ - + @@ -200,7 +230,7 @@ - + @@ -238,6 +268,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/RealmContent/DemoData.swift b/Example/RealmContent/DemoData.swift index 4d38175..5fd2a78 100644 --- a/Example/RealmContent/DemoData.swift +++ b/Example/RealmContent/DemoData.swift @@ -12,6 +12,44 @@ import RealmContent struct DemoData { + static func createDemoDataSet3(in realm: Realm) { + try! realm.write { + realm.deleteAll() + + // store offers + let offer1 = ContentPage(value: ["title": "This weekend everything is 20% off", "tag": "offer", "mainColor": "f25192"]) + let elements1: [ContentElement] = [ + ContentElement(value: ["type": "h1", "content": "Big weekend sale!"]), + ContentElement(value: ["type": "h2", "content": "This weekend everything is 20% off"]), + ContentElement(value: ["type": "p", "content": "Use promo code 'bigsummersale20' to get your discount at checkout"]), + ContentElement(value: ["type": "img", "content": "http://realm.io/assets/img/news/2016-05-17-realm-rxswift/rx.png", "url": "https://news.realm.io/news/marin-todorov-realm-rxswift/"]) + ] + offer1.elements.append(objectsIn: elements1) + + let offer2 = ContentPage(value: ["title": "Buy 4 garden gnomes, pay 5!", "tag": "offer", "mainColor": "f25192"]) + let elements2: [ContentElement] = [ + ContentElement(value: ["type": "h1", "content": "Big spring sale!"]), + ContentElement(value: ["type": "h2", "content": "Buy 4 garden gnomes, pay 5!"]), + ContentElement(value: ["type": "p", "content": "Use promo code '4for5supergnome' to get your discount at checkout"]), + ContentElement(value: ["type": "img", "content": "http://realm.io/assets/img/news/2016-05-17-realm-rxswift/rx.png", "url": "https://news.realm.io/news/marin-todorov-realm-rxswift/"]) + ] + offer2.elements.append(objectsIn: elements2) + + let offer3 = ContentPage(value: ["title": "Get our fidelity card for a chance to win!", "tag": "offer", "mainColor": "f25192"]) + let elements3: [ContentElement] = [ + ContentElement(value: ["type": "h1", "content": "Get the card, win the prizes! Do it now!"]), + ContentElement(value: ["type": "p", "content": "Not only you will get permanent discount of 5% on all products, but you can also win big time!"]), + ContentElement(value: ["type": "img", "content": "http://realm.io/assets/img/news/2016-05-17-realm-rxswift/rx.png", "url": "https://news.realm.io/news/marin-todorov-realm-rxswift/"]) + ] + offer3.elements.append(objectsIn: elements3) + + + realm.add([offer1, offer2, offer3]) + + + } + } + static func createDemoDataSet2(in realm: Realm) { try! realm.write { realm.deleteAll() diff --git a/Example/RealmContent/PageCellView.swift b/Example/RealmContent/PageCellView.swift new file mode 100644 index 0000000..ceb175f --- /dev/null +++ b/Example/RealmContent/PageCellView.swift @@ -0,0 +1,41 @@ +// +// PageCellView.swift +// RealmContent +// +// Created by Marin Todorov on 7/11/17. +// Copyright © 2017 CocoaPods. All rights reserved. +// + +import UIKit +import RealmContent + +struct OrbColor { + static func at(index: Int) -> UIColor { + switch index { + case 0: return NSString(string: "#D34CA3").representedColor() + case 1: return NSString(string: "#9A50A5").representedColor() + case 2: return NSString(string: "#59569E").representedColor() + default: return NSString(string: "#39477F").representedColor() + } + } +} + +class PageCellView: UITableViewCell { + + @IBOutlet var label: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + } + + func populate(with page: ContentPage, atRow row: Int) { + label.text = page.title + label.textColor = OrbColor.at(index: row) + } +} diff --git a/Example/RealmContent/ProductCellView.swift b/Example/RealmContent/ProductCellView.swift new file mode 100644 index 0000000..c9ebb73 --- /dev/null +++ b/Example/RealmContent/ProductCellView.swift @@ -0,0 +1,32 @@ +// +// ProductCellView.swift +// RealmContent +// +// Created by Marin Todorov on 7/11/17. +// Copyright © 2017 CocoaPods. All rights reserved. +// + +import UIKit +import RealmContent +import Kingfisher + +class ProductCellView: UICollectionViewCell { + + @IBOutlet var image: UIImageView! + @IBOutlet var label: UILabel! + + func populate(with page: ContentPage) { + label.text = page.title + + // expects the top element in the page to be an image, + // grabs it, and shows it in the cell + + if let imageElement = page.elements.first, + imageElement.type == ContentElement.Kind.img.rawValue, + let urlString = imageElement.url, + let url = URL(string: urlString) { + + image.kf.setImage(with: url) + } + } +} diff --git a/Example/RealmContent/StoreViewController.swift b/Example/RealmContent/StoreViewController.swift new file mode 100644 index 0000000..732b486 --- /dev/null +++ b/Example/RealmContent/StoreViewController.swift @@ -0,0 +1,72 @@ +// +// StoreViewController.swift +// Created by Marin Todorov +// Copyright © 2017 - present Realm. All rights reserved. +// + +import UIKit +import NSString_Color + +import RealmSwift +import RealmContent + +class StoreViewController: UIViewController { + + let offers = ContentListDataSource(style: .plain) + let products = ContentListDataSource(style: .plain) + + override func viewDidLoad() { + super.viewDidLoad() + + let realm = try! Realm() + DemoData.createDemoDataSet3(in: realm) + + offers.loadContent(from: realm, filter: NSPredicate(format: "tag = %@", "offer")) + products.loadContent(from: realm, filter: NSPredicate(format: "tag = %@", "product")) + + + } + +} + +extension StoreViewController: UITableViewDataSource, UITableViewDelegate { + func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + return "Current Offers" + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return offers.numberOfItemsIn(section: section) + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "PageCell") as! PageCellView + cell.populate(with: offers.itemAt(indexPath: indexPath), atRow: indexPath.row) + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + tableView.deselectRow(at: indexPath, animated: true) + + let offer = offers.itemAt(indexPath: indexPath) + navigationController!.pushViewController( + ContentViewController(page: offer), animated: true) + } +} + +extension StoreViewController: UICollectionViewDataSource, UICollectionViewDelegate { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return products.numberOfItemsIn(section: section) + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ProductCell", for: indexPath) as! ProductCellView + cell.populate(with: products.itemAt(indexPath: indexPath)) + return cell + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + collectionView.deselectItem(at: indexPath, animated: true) + + } + +} diff --git a/RealmContent/Classes/Classes/ContentListDataSource.swift b/RealmContent/Classes/Classes/ContentListDataSource.swift index 0e1da6d..50e34f2 100644 --- a/RealmContent/Classes/Classes/ContentListDataSource.swift +++ b/RealmContent/Classes/Classes/ContentListDataSource.swift @@ -196,6 +196,7 @@ public class ContentListDataSource: NSObject { case .plain: return 1 case .sectionsByTag: + precondition(sections != nil, "You need to set sectioned style and use loadContent(from:) before asking for data back") return sections!.count } } @@ -206,10 +207,13 @@ public class ContentListDataSource: NSObject { - returns: the number of items in the section */ public func numberOfItemsIn(section: Int) -> Int { + precondition(results != nil, "You need to use loadContent(from:) before asking for data back") + switch style { case .plain: return results!.count case .sectionsByTag: + precondition(sections != nil, "You need to set sectioned style and use loadContent(from:) before asking for data back") return sections![section].count } } @@ -224,6 +228,7 @@ public class ContentListDataSource: NSObject { case .plain: return nil case .sectionsByTag: + precondition(sections != nil, "You need to set sectioned style and use loadContent(from:) before asking for data back") return sections![section].title } } @@ -235,10 +240,14 @@ public class ContentListDataSource: NSObject { - returns: a `ContentPage` found for the given section/index */ public func itemAt(section: Int = -1, index: Int) -> ContentPage { + precondition(results != nil, "You need to use loadContent(from:) before asking for data back") + switch style { case .plain: return results![index] case .sectionsByTag: + precondition(sections != nil, "You need to set sectioned style and use loadContent(from:) before asking for data back") + let offset = sections![section].start return results![offset + index] } diff --git a/RealmContent/Classes/View/ContentViewController.swift b/RealmContent/Classes/View/ContentViewController.swift index 3ec158b..cd57622 100644 --- a/RealmContent/Classes/View/ContentViewController.swift +++ b/RealmContent/Classes/View/ContentViewController.swift @@ -8,7 +8,6 @@ import Foundation import UIKit import SafariServices import RealmSwift -import NSString_Color import Kingfisher /** diff --git a/assets/pexels-photo-248797.jpg b/assets/pexels-photo-248797.jpg new file mode 100644 index 0000000..384994e Binary files /dev/null and b/assets/pexels-photo-248797.jpg differ diff --git a/assets/pexels-photo-296230.jpg b/assets/pexels-photo-296230.jpg new file mode 100644 index 0000000..8dfc33b Binary files /dev/null and b/assets/pexels-photo-296230.jpg differ diff --git a/assets/pexels-photo.jpg b/assets/pexels-photo.jpg new file mode 100644 index 0000000..8a2f660 Binary files /dev/null and b/assets/pexels-photo.jpg differ