Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
icanzilb committed Jan 23, 2017
1 parent 9429839 commit 173c321
Show file tree
Hide file tree
Showing 18 changed files with 1,388 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -63,3 +63,4 @@ fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
Pods
10 changes: 10 additions & 0 deletions Podfile
@@ -0,0 +1,10 @@
use_frameworks!

target 'RxSwiftiOS' do
pod 'RxSwift', '3.1.0'
pod 'RxCocoa', '3.1.0'
pod 'Unbox', '2.3.0'
pod 'RealmSwift', '2.2.0'
pod 'RxRealm', '0.5.1'
pod 'RxRealmDataSources', '0.2.1'
end
3 changes: 1 addition & 2 deletions README.md
@@ -1,2 +1 @@
# RxSwiftoniOS
Sample code from my dotSwift 2017 talk in Paris
Sample code from my dotSwift 2017 talk in Paris. Clone and install CocoaPods, then run the app.
445 changes: 445 additions & 0 deletions RxSwiftiOS.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions RxSwiftiOS.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions RxSwiftiOS/AppDelegate.swift
@@ -0,0 +1,14 @@
//
// AppDelegate.swift
// RxSwiftiOS
//
// Created by Marin Todorov on 1/21/17.
// Copyright © 2017 Underplot ltd. All rights reserved.
//

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
}
48 changes: 48 additions & 0 deletions RxSwiftiOS/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,48 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
27 changes: 27 additions & 0 deletions RxSwiftiOS/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11134" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11106"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
428 changes: 428 additions & 0 deletions RxSwiftiOS/Base.lproj/Main.storyboard

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions RxSwiftiOS/Info.plist
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
62 changes: 62 additions & 0 deletions RxSwiftiOS/NewRepoViewController.swift
@@ -0,0 +1,62 @@
//
// NewRepoViewController.swift
// RxSwiftiOS
//
// Created by Marin Todorov on 1/21/17.
// Copyright © 2017 Underplot ltd. All rights reserved.
//

import UIKit

import RxSwift
import RxCocoa

class NewRepoViewController: UITableViewController {

@IBOutlet var id: UITextField!
@IBOutlet var name: UITextField!
@IBOutlet var language: UITextField!
@IBOutlet var saveButton: UIButton!

private let bag = DisposeBag()
private let repo = PublishSubject<Repo>()

lazy var repoObservable: Observable<Repo> = {
return self.repo.asObservable()
}()

override func viewDidLoad() {
super.viewDidLoad()
bindUI()
}

func bindUI() {
// current repo data
let currentRepo = Observable.combineLatest(id.rx.text, name.rx.text, language.rx.text) { id, name, lang -> Repo? in
guard let id = id, let idInt = Int(id),
let name = name, name.characters.count > 1,
let lang = lang, lang.characters.count > 0 else {
return nil
}
return Repo(idInt, name, lang)
}
.shareReplay(1)

// toggle save button
currentRepo
.map { $0 != nil }
.bindTo(saveButton.rx.isEnabled)
.addDisposableTo(bag)

// emit repo when saved
saveButton.rx.tap
.withLatestFrom(currentRepo)
.subscribe(onNext: {[weak self] repo in
if let repo = repo {
self?.repo.onNext(repo)
self?.repo.onCompleted()
}
})
.addDisposableTo(bag)
}
}
59 changes: 59 additions & 0 deletions RxSwiftiOS/PresentViewController.swift
@@ -0,0 +1,59 @@
//
// PresentViewController.swift
// RxSwiftiOS
//
// Created by Marin Todorov on 1/21/17.
// Copyright © 2017 Underplot ltd. All rights reserved.
//

import UIKit
import RxSwift
import RxCocoa

private let initialRepos = [
Repo(1, "EasyAnimation", "Swift"),
Repo(2, "Unbox", "Swift"),
Repo(3, "RxSwift", "Swift")
]

class PresentViewController: UITableViewController {

private let repos = Variable<[Repo]>(initialRepos)
private let bag = DisposeBag()

override func viewDidLoad() {
super.viewDidLoad()

tableView.dataSource = nil
bindUI()
}

func bindUI() {
// display data
repos.asObservable()
.bindTo(tableView.rx.items) { (tableView, row, repo) in
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
cell.textLabel!.text = repo.name
cell.detailTextLabel?.text = repo.language
return cell
}
.addDisposableTo(bag)

// present view controller, observe output
navigationItem.rightBarButtonItem!.rx.tap
.debounce(0.5, scheduler: MainScheduler.instance)
.flatMapFirst {[weak self] _ -> Observable<Repo> in
if let addVC = self?.storyboard?.instantiateViewController(withIdentifier: "NewRepoViewController") as? NewRepoViewController {
self?.navigationController?.pushViewController(addVC, animated: true)
return addVC.repoObservable
}
return Observable.never()
}
.subscribe(onNext: {[weak self] repo in
self?.repos.value.append(repo)
_ = self?.navigationController?.popViewController(animated: true)
})
.addDisposableTo(bag)
}

}
32 changes: 32 additions & 0 deletions RxSwiftiOS/Repo.swift
@@ -0,0 +1,32 @@
//
// Repo.swift
// RxSwiftiOS
//
// Created by Marin Todorov on 1/21/17.
// Copyright © 2017 Underplot ltd. All rights reserved.
//

import Foundation

struct Repo {
let id: Int
let name: String
let language: String

init?(object: [String: Any]) {
guard let id = object["id"] as? Int,
let name = object["name"] as? String,
let language = object["language"] as? String else {
return nil
}
self.id = id
self.name = name
self.language = language
}

init(_ id: Int, _ name: String, _ language: String) {
self.id = id
self.name = name
self.language = language
}
}
60 changes: 60 additions & 0 deletions RxSwiftiOS/SearchGitHubViewController.swift
@@ -0,0 +1,60 @@
//
// ViewController.swift
// RxSwiftiOS
//
// Created by Marin Todorov on 1/21/17.
// Copyright © 2017 Underplot ltd. All rights reserved.
//

import UIKit
import Unbox

import RxSwift
import RxCocoa

class SearchGitHubViewController: UIViewController {

@IBOutlet var tableView: UITableView!
@IBOutlet var searchBar: UISearchBar!

private let bag = DisposeBag()
private let repos = Variable<[Repo]>([])

override func viewDidLoad() {
super.viewDidLoad()
bindUI()
}

func bindUI() {
// observe text, form request, bind table view to result
searchBar.rx.text
.orEmpty
.filter { query in
return query.characters.count > 2
}
.debounce(0.5, scheduler: MainScheduler.instance)
.map { query in
let apiUrl = URL(string: "https://api.github.com/search/repositories?q=" + query)!
return URLRequest(url: apiUrl)
}
.flatMapLatest { request in
return URLSession.shared.rx.json(request: request)
.catchErrorJustReturn([])
}
.map { json -> [Repo] in
guard let json = json as? [String: Any],
let items = json["items"] as? [[String: Any]] else {
return []
}
return items.flatMap(Repo.init)
}

.bindTo(tableView.rx.items) { tableView, row, repo in
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
cell.textLabel!.text = repo.name
cell.detailTextLabel?.text = repo.language
return cell
}
.addDisposableTo(bag)
}
}

0 comments on commit 173c321

Please sign in to comment.