From 30dc3b84af206a69f1ca60a8467e8f4515b94706 Mon Sep 17 00:00:00 2001 From: Yoshinori Sano Date: Tue, 29 Sep 2015 13:31:48 +0900 Subject: [PATCH] Add base implementation of auto loading example. --- RxExample/RxExample.xcodeproj/project.pbxproj | 13 ++ ...tHubSearchRepositoriesViewController.swift | 119 ++++++++++++++++++ RxExample/RxExample/iOS/LaunchScreen.xib | 4 +- RxExample/RxExample/iOS/Main.storyboard | 61 ++++++++- 4 files changed, 192 insertions(+), 5 deletions(-) create mode 100644 RxExample/RxExample/Examples/AutoLoading/GitHubSearchRepositoriesViewController.swift diff --git a/RxExample/RxExample.xcodeproj/project.pbxproj b/RxExample/RxExample.xcodeproj/project.pbxproj index b24cae01..8c9bbfa2 100644 --- a/RxExample/RxExample.xcodeproj/project.pbxproj +++ b/RxExample/RxExample.xcodeproj/project.pbxproj @@ -294,6 +294,7 @@ C8DF92EA1B0B38C0009BCF9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C8DF92E91B0B38C0009BCF9A /* Images.xcassets */; }; C8DF92EB1B0B38C0009BCF9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C8DF92E91B0B38C0009BCF9A /* Images.xcassets */; }; C8DF92F61B0B43A4009BCF9A /* IntroductionExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8DF92F51B0B43A4009BCF9A /* IntroductionExampleViewController.swift */; }; + EC91FB951BBA144400973245 /* GitHubSearchRepositoriesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC91FB941BBA144400973245 /* GitHubSearchRepositoriesViewController.swift */; settings = {ASSET_TAGS = (); }; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -564,6 +565,7 @@ C8DF92F01B0B3E67009BCF9A /* Info-OSX.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-OSX.plist"; sourceTree = ""; }; C8DF92F21B0B3E71009BCF9A /* Info-iOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = ""; }; C8DF92F51B0B43A4009BCF9A /* IntroductionExampleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = IntroductionExampleViewController.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + EC91FB941BBA144400973245 /* GitHubSearchRepositoriesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GitHubSearchRepositoriesViewController.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1074,6 +1076,7 @@ 07A5C3D91B70B6B8001EFE5C /* 06 Calculator */, C859B9A21B45C5D900D012D7 /* 07 PartialUpdates */, C8A57F711B40AF4E00D5570A /* 08 CoreData */, + EC91FB931BBA12E800973245 /* 09 AutoLoading */, ); path = Examples; sourceTree = ""; @@ -1197,6 +1200,15 @@ path = Introduction; sourceTree = ""; }; + EC91FB931BBA12E800973245 /* 09 AutoLoading */ = { + isa = PBXGroup; + children = ( + EC91FB941BBA144400973245 /* GitHubSearchRepositoriesViewController.swift */, + ); + name = "09 AutoLoading"; + path = AutoLoading; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -1569,6 +1581,7 @@ C83367251AD029AE00C668A7 /* ImageService.swift in Sources */, C86E2F471AE5A0CA00C31024 /* WikipediaSearchResult.swift in Sources */, C890A65A1AEBD28A00AFF7E6 /* GitHubAPI.swift in Sources */, + EC91FB951BBA144400973245 /* GitHubSearchRepositoriesViewController.swift in Sources */, C8A2A2C81B4049E300F11F09 /* PseudoRandomGenerator.swift in Sources */, C84B91381B8A282000C9CCCF /* RxTableViewSectionedAnimatedDataSource.swift in Sources */, C88C78721B3EB0A00061C5AB /* SectionedViewType.swift in Sources */, diff --git a/RxExample/RxExample/Examples/AutoLoading/GitHubSearchRepositoriesViewController.swift b/RxExample/RxExample/Examples/AutoLoading/GitHubSearchRepositoriesViewController.swift new file mode 100644 index 00000000..048f8414 --- /dev/null +++ b/RxExample/RxExample/Examples/AutoLoading/GitHubSearchRepositoriesViewController.swift @@ -0,0 +1,119 @@ +// +// GitHubSearchRepositoriesViewController.swift +// RxExample +// +// Created by yoshinori_sano on 9/29/15. +// Copyright (c) 2015 Krunoslav Zaher. All rights reserved. +// + +import UIKit +#if !RX_NO_MODULE +import RxSwift +import RxCocoa +#endif + +struct Repository: CustomStringConvertible { + var name: String + + init(name: String) { + self.name = name + } + + var description: String { + return name + } +} + +class GitHubSearchRepositoriesAPI { + + static let sharedAPI = GitHubSearchRepositoriesAPI() + + private init() {} + + func search() -> Observable<[Repository]> { + let url = NSURL(string: "https://api.github.com/search/repositories?q=othello")! + return NSURLSession.sharedSession().rx_JSON(url) + .observeOn(Dependencies.sharedDependencies.backgroundWorkScheduler) + .map { json in + guard let json = json as? [String: AnyObject] else { + throw exampleError("Casting to dictionary failed") + } + return try self.parseJSON(json) + } + .observeOn(Dependencies.sharedDependencies.mainScheduler) + } + + private func parseJSON(json: [String: AnyObject]) throws -> [Repository] { + guard let items = json["items"] as? [[String: AnyObject]] else { + throw exampleError("Can't find results") + } + return try items.map { item in + guard let name = item["name"] as? String else { + throw exampleError("Can't parse repository") + } + return Repository(name: name) + } + } +} + +class GitHubSearchRepositoriesViewController: ViewController, UITableViewDelegate { + + @IBOutlet weak var tableView: UITableView! + + var disposeBag = DisposeBag() + let repositories = Variable([Repository]()) + let dataSource = RxTableViewSectionedReloadDataSource>() + + override func viewDidLoad() { + super.viewDidLoad() + + let allRepositories = repositories + .map { repositories in + return [SectionModel(model: "Repositories", items: repositories)] + } + + dataSource.cellFactory = { (tv, ip, user: Repository) in + let cell = tv.dequeueReusableCellWithIdentifier("Cell")! + cell.textLabel?.text = user.name + return cell + } + + dataSource.titleForHeaderInSection = { [unowned dataSource] sectionIndex in + return dataSource.sectionAtIndex(sectionIndex).model + } + + // reactive data source + allRepositories + .bindTo(tableView.rx_itemsWithDataSource(dataSource)) + .addDisposableTo(disposeBag) + + GitHubSearchRepositoriesAPI.sharedAPI.search() + .subscribeNext { [unowned self] array in + self.repositories.value = array + } + .addDisposableTo(disposeBag) + } + + override func setEditing(editing: Bool, animated: Bool) { + super.setEditing(editing, animated: animated) + tableView.editing = editing + } + + // MARK: Table view delegate + + func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + let title = dataSource.sectionAtIndex(section) + + let label = UILabel(frame: CGRect.zero) + label.text = " \(title)" + label.textColor = UIColor.whiteColor() + label.backgroundColor = UIColor.darkGrayColor() + label.alpha = 0.9 + + return label + } + + func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + return 40 + } +} diff --git a/RxExample/RxExample/iOS/LaunchScreen.xib b/RxExample/RxExample/iOS/LaunchScreen.xib index e2df5a9d..023729e8 100644 --- a/RxExample/RxExample/iOS/LaunchScreen.xib +++ b/RxExample/RxExample/iOS/LaunchScreen.xib @@ -1,7 +1,7 @@ - + - + diff --git a/RxExample/RxExample/iOS/Main.storyboard b/RxExample/RxExample/iOS/Main.storyboard index 9dbff6df..813b8712 100644 --- a/RxExample/RxExample/iOS/Main.storyboard +++ b/RxExample/RxExample/iOS/Main.storyboard @@ -1,7 +1,7 @@ - + - + @@ -23,6 +23,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -487,12 +515,39 @@ + + + + + + + + + + + + + + + - +