begin fixing up the examples

This commit is contained in:
Jamie Pinkham 2016-06-18 01:24:07 -07:00
parent c4cf2e0d12
commit 39a20441e1
71 changed files with 712 additions and 699 deletions

View File

@ -486,7 +486,7 @@ extension DriverConvertibleType {
public func startWith(_ element: E)
-> Driver<E> {
let source = self.asObservable()
.startWith(elements: element)
.startWith(element)
return Driver(source)
}

View File

@ -84,7 +84,7 @@ extension DriverConvertibleType {
@warn_unused_result(message: "http://git.io/rxs.ud")
public func drive(_ onNext: ((E) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil) -> Disposable {
MainScheduler.ensureExecutingOnScheduler()
return self.asObservable().subscribe(onNext, onCompleted: onCompleted, onDisposed: onDisposed)
return self.asObservable().subscribe(onNext: onNext, onCompleted: onCompleted, onDisposed: onDisposed)
}
/**

View File

@ -19,7 +19,7 @@ extension ObservableConvertibleType {
- returns: Driving observable sequence.
*/
@warn_unused_result(message:"http://git.io/rxs.uo")
public func asDriver(_ onErrorJustReturn: E) -> Driver<E> {
public func asDriver(onErrorJustReturn: E) -> Driver<E> {
let source = self
.asObservable()
.observeOn(driverObserveOnScheduler)
@ -34,7 +34,7 @@ extension ObservableConvertibleType {
- returns: Driving observable sequence.
*/
@warn_unused_result(message:"http://git.io/rxs.uo")
public func asDriver(_ onErrorDriveWith: Driver<E>) -> Driver<E> {
public func asDriver(onErrorDriveWith: Driver<E>) -> Driver<E> {
let source = self
.asObservable()
.observeOn(driverObserveOnScheduler)
@ -51,7 +51,7 @@ extension ObservableConvertibleType {
- returns: Driving observable sequence.
*/
@warn_unused_result(message:"http://git.io/rxs.uo")
public func asDriver(_ onErrorRecover: (error: ErrorProtocol) -> Driver<E>) -> Driver<E> {
public func asDriver(onErrorRecover: (error: ErrorProtocol) -> Driver<E>) -> Driver<E> {
let source = self
.asObservable()
.observeOn(driverObserveOnScheduler)

View File

@ -95,7 +95,7 @@ extension ObservableType {
*/
@warn_unused_result(message: "http://git.io/rxs.ud")
public func bindNext(_ onNext: (E) -> Void) -> Disposable {
return subscribe(onNext, onError: { error in
return subscribe(onNext: onNext, onError: { error in
let error = "Binding error: \(error)"
#if DEBUG
rxFatalError(error)

View File

@ -81,7 +81,7 @@ extension ObservableType where E == AnyObject? {
.map { _ in
return Observable.just(nil)
}
.startWith(elements: self.asObservable())
.startWith(self.asObservable())
.switchLatest()
}
}

View File

@ -49,7 +49,7 @@ extension UISearchBar {
.map { a in
return a[1] as? String ?? ""
}
.startWith(elements: text)
.startWith(text)
}
let bindingObserver = UIBindingObserver(UIElement: self) { (searchBar, text: String) in
@ -70,7 +70,7 @@ extension UISearchBar {
.map { a in
return try castOrThrow(Int.self, a[1])
}
.startWith(elements: index)
.startWith(index)
}
let bindingObserver = UIBindingObserver(UIElement: self) { (searchBar, index: Int) in

View File

@ -49,7 +49,7 @@ extension UITextView : RxTextInput {
?? Observable.empty()
return textChanged
.startWith(elements: text)
.startWith(text)
}
let bindingObserver = UIBindingObserver(UIElement: self) { (textView, text: String) in

View File

@ -27,7 +27,7 @@ public class RxCollectionViewSectionedAnimatedDataSource<S: AnimatableSectionMod
super.init()
}
public func collectionView(collectionView: UICollectionView, observedEvent: Event<Element>) {
public func collectionView(_ collectionView: UICollectionView, observedEvent: Event<Element>) {
UIBindingObserver(UIElement: self) { dataSource, newSections in
if !self.dataSet {
self.dataSet = true
@ -35,7 +35,7 @@ public class RxCollectionViewSectionedAnimatedDataSource<S: AnimatableSectionMod
collectionView.reloadData()
}
else {
dispatch_async(dispatch_get_main_queue()) {
DispatchQueue.main.async {
let oldSections = dataSource.sectionModels
do {
let differences = try differencesForSectionedView(oldSections, finalSections: newSections)
@ -55,4 +55,4 @@ public class RxCollectionViewSectionedAnimatedDataSource<S: AnimatableSectionMod
}
}.on(observedEvent)
}
}
}

View File

@ -23,10 +23,10 @@ public class RxCollectionViewSectionedReloadDataSource<S: SectionModelType>
super.init()
}
public func collectionView(collectionView: UICollectionView, observedEvent: Event<Element>) {
public func collectionView(_ collectionView: UICollectionView, observedEvent: Event<Element>) {
UIBindingObserver(UIElement: self) { dataSource, element in
dataSource.setSections(element)
collectionView.reloadData()
}.on(observedEvent)
}
}
}

View File

@ -26,7 +26,7 @@ public class RxTableViewSectionedAnimatedDataSource<S: AnimatableSectionModelTyp
super.init()
}
public func tableView(tableView: UITableView, observedEvent: Event<Element>) {
public func tableView(_ tableView: UITableView, observedEvent: Event<Element>) {
UIBindingObserver(UIElement: self) { dataSource, newSections in
if !self.dataSet {
self.dataSet = true
@ -34,7 +34,7 @@ public class RxTableViewSectionedAnimatedDataSource<S: AnimatableSectionModelTyp
tableView.reloadData()
}
else {
dispatch_async(dispatch_get_main_queue()) {
DispatchQueue.main.async {
let oldSections = dataSource.sectionModels
do {
let differences = try differencesForSectionedView(oldSections, finalSections: newSections)
@ -54,4 +54,4 @@ public class RxTableViewSectionedAnimatedDataSource<S: AnimatableSectionModelTyp
}
}.on(observedEvent)
}
}
}

View File

@ -22,10 +22,10 @@ public class RxTableViewSectionedReloadDataSource<S: SectionModelType>
super.init()
}
public func tableView(tableView: UITableView, observedEvent: Event<Element>) {
public func tableView(_ tableView: UITableView, observedEvent: Event<Element>) {
UIBindingObserver(UIElement: self) { dataSource, element in
dataSource.setSections(element)
tableView.reloadData()
}.on(observedEvent)
}
}
}

View File

@ -14,17 +14,17 @@ import RxCocoa
#endif
extension UITableView {
@available(*, deprecated=0.7, renamed="rx_itemsWithDataSource", message="You can just use normal `rx_itemsWithDataSource` extension.")
@available(*, deprecated:0.7, renamed:"rx_itemsWithDataSource", message:"You can just use normal `rx_itemsWithDataSource` extension.")
public func rx_itemsAnimatedWithDataSource<
DataSource: protocol<RxTableViewDataSourceType, UITableViewDataSource>,
S: SequenceType,
S: Sequence,
O: ObservableType
where
DataSource.Element == S,
O.E == S,
S.Generator.Element: AnimatableSectionModelType
S.Iterator.Element: AnimatableSectionModelType
>
(dataSource: DataSource)
(_ dataSource: DataSource)
-> (source: O)
-> Disposable {
return { source in
@ -34,21 +34,21 @@ extension UITableView {
}
extension UICollectionView {
@available(*, deprecated=0.7, renamed="rx_itemsWithDataSource", message="You can just use normal `rx_itemsWithDataSource` extension.")
@available(*, deprecated:0.7, renamed:"rx_itemsWithDataSource", message:"You can just use normal `rx_itemsWithDataSource` extension.")
public func rx_itemsAnimatedWithDataSource<
DataSource: protocol<RxCollectionViewDataSourceType, UICollectionViewDataSource>,
S: SequenceType,
S: Sequence,
O: ObservableType
where
DataSource.Element == S,
O.E == S,
S.Generator.Element: AnimatableSectionModelType
S.Iterator.Element: AnimatableSectionModelType
>
(dataSource: DataSource)
(_ dataSource: DataSource)
-> (source: O)
-> Disposable {
return { source in
return self.rx_itemsWithDataSource(dataSource)(source: source)
}
}
}
}

View File

@ -17,11 +17,11 @@ public struct AnimationConfiguration {
let reloadAnimation: UITableViewRowAnimation
let deleteAnimation: UITableViewRowAnimation
public init(insertAnimation: UITableViewRowAnimation = .Automatic,
reloadAnimation: UITableViewRowAnimation = .Automatic,
deleteAnimation: UITableViewRowAnimation = .Automatic) {
public init(insertAnimation: UITableViewRowAnimation = .automatic,
reloadAnimation: UITableViewRowAnimation = .automatic,
deleteAnimation: UITableViewRowAnimation = .automatic) {
self.insertAnimation = insertAnimation
self.reloadAnimation = reloadAnimation
self.deleteAnimation = deleteAnimation
}
}
}

View File

@ -11,19 +11,19 @@ import Foundation
import Foundation
extension Array where Element: SectionModelType {
mutating func moveFromSourceIndexPath(sourceIndexPath: NSIndexPath, destinationIndexPath: NSIndexPath) {
let sourceSection = self[sourceIndexPath.section]
mutating func moveFromSourceIndexPath(_ sourceIndexPath: IndexPath, destinationIndexPath: IndexPath) {
let sourceSection = self[(sourceIndexPath as NSIndexPath).section]
var sourceItems = sourceSection.items
let sourceItem = sourceItems.removeAtIndex(sourceIndexPath.item)
let sourceItem = sourceItems.remove(at: (sourceIndexPath as NSIndexPath).item)
let sourceSectionNew = Element(original: sourceSection, items: sourceItems)
self[sourceIndexPath.section] = sourceSectionNew
self[(sourceIndexPath as NSIndexPath).section] = sourceSectionNew
let destinationSection = self[destinationIndexPath.section]
let destinationSection = self[(destinationIndexPath as NSIndexPath).section]
var destinationItems = destinationSection.items
destinationItems.insert(sourceItem, atIndex: destinationIndexPath.item)
destinationItems.insert(sourceItem, at: (destinationIndexPath as NSIndexPath).item)
self[destinationIndexPath.section] = Element(original: destinationSection, items: destinationItems)
self[(destinationIndexPath as NSIndexPath).section] = Element(original: destinationSection, items: destinationItems)
}
}
}

View File

@ -60,7 +60,7 @@ public struct Changeset<S: SectionModelType> {
self.updatedItems = updatedItems
}
public static func initialValue(sections: [S]) -> Changeset<S> {
public static func initialValue(_ sections: [S]) -> Changeset<S> {
return Changeset<S>(
insertedSections: Array(0 ..< sections.count) as [Int],
finalSections: sections,
@ -80,7 +80,7 @@ extension Changeset
: CustomDebugStringConvertible {
public var debugDescription : String {
let serializedSections = "[\n" + finalSections.map { "\($0)" }.joinWithSeparator(",\n") + "\n]\n"
let serializedSections = "[\n" + finalSections.map { "\($0)" }.joined(separator: ",\n") + "\n]\n"
return " >> Final sections"
+ " \n\(serializedSections)"
+ (insertedSections.count > 0 || deletedSections.count > 0 || movedSections.count > 0 || updatedSections.count > 0 ? "\nSections:" : "")

View File

@ -16,50 +16,50 @@ public class _CollectionViewSectionedDataSource
: NSObject
, UICollectionViewDataSource {
func _numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
func _numberOfSectionsInCollectionView(_ collectionView: UICollectionView) -> Int {
return 0
}
public func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
public func numberOfSections(in collectionView: UICollectionView) -> Int {
return _numberOfSectionsInCollectionView(collectionView)
}
func _rx_collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
func _rx_collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 0
}
public func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return _rx_collectionView(collectionView, numberOfItemsInSection: section)
}
func _rx_collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
func _rx_collectionView(_ collectionView: UICollectionView, cellForItemAtIndexPath indexPath: IndexPath) -> UICollectionViewCell {
return (nil as UICollectionViewCell?)!
}
public func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
return _rx_collectionView(collectionView, cellForItemAtIndexPath: indexPath)
}
func _rx_collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
func _rx_collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: IndexPath) -> UICollectionReusableView {
return (nil as UICollectionReusableView?)!
}
public func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
public func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
return _rx_collectionView(collectionView, viewForSupplementaryElementOfKind: kind, atIndexPath: indexPath)
}
func _rx_collectionView(collectionView: UICollectionView, canMoveItemAtIndexPath indexPath: NSIndexPath) -> Bool {
func _rx_collectionView(_ collectionView: UICollectionView, canMoveItemAtIndexPath indexPath: IndexPath) -> Bool {
return true
}
public func collectionView(collectionView: UICollectionView, canMoveItemAtIndexPath indexPath: NSIndexPath) -> Bool {
public func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool {
return _rx_collectionView(collectionView, canMoveItemAtIndexPath: indexPath)
}
func _rx_collectionView(collectionView: UICollectionView, moveItemAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
func _rx_collectionView(_ collectionView: UICollectionView, moveItemAtIndexPath sourceIndexPath: IndexPath, toIndexPath destinationIndexPath: IndexPath) {
}
public func collectionView(collectionView: UICollectionView, moveItemAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
public func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
_rx_collectionView(collectionView, moveItemAtIndexPath: sourceIndexPath, toIndexPath: destinationIndexPath)
}
@ -70,8 +70,8 @@ public class CollectionViewSectionedDataSource<S: SectionModelType>
, SectionedViewDataSourceType {
public typealias I = S.Item
public typealias Section = S
public typealias CellFactory = (CollectionViewSectionedDataSource<S>, UICollectionView, NSIndexPath, I) -> UICollectionViewCell
public typealias SupplementaryViewFactory = (CollectionViewSectionedDataSource<S>, UICollectionView, String, NSIndexPath) -> UICollectionReusableView
public typealias CellFactory = (CollectionViewSectionedDataSource<S>, UICollectionView, IndexPath, I) -> UICollectionViewCell
public typealias SupplementaryViewFactory = (CollectionViewSectionedDataSource<S>, UICollectionView, String, IndexPath) -> UICollectionReusableView
// This structure exists because model can be mutable
// In that case current state value should be preserved.
@ -87,28 +87,28 @@ public class CollectionViewSectionedDataSource<S: SectionModelType>
return _sectionModels.map { Section(original: $0.model, items: $0.items) }
}
public func sectionAtIndex(section: Int) -> S {
public func sectionAtIndex(_ section: Int) -> S {
let sectionModel = self._sectionModels[section]
return S(original: sectionModel.model, items: sectionModel.items)
}
public func itemAtIndexPath(indexPath: NSIndexPath) -> I {
return self._sectionModels[indexPath.section].items[indexPath.item]
public func itemAtIndexPath(_ indexPath: IndexPath) -> I {
return self._sectionModels[(indexPath as NSIndexPath).section].items[(indexPath as NSIndexPath).item]
}
public func modelAtIndexPath(indexPath: NSIndexPath) throws -> Any {
public func modelAtIndexPath(_ indexPath: IndexPath) throws -> Any {
return itemAtIndexPath(indexPath)
}
public func setSections(sections: [S]) {
public func setSections(_ sections: [S]) {
self._sectionModels = sections.map { SectionModelSnapshot(model: $0, items: $0.items) }
}
public var cellFactory: CellFactory! = nil
public var supplementaryViewFactory: SupplementaryViewFactory
public var moveItem: ((CollectionViewSectionedDataSource<S>, sourceIndexPath:NSIndexPath, destinationIndexPath:NSIndexPath) -> Void)?
public var canMoveItemAtIndexPath: ((CollectionViewSectionedDataSource<S>, indexPath:NSIndexPath) -> Bool)?
public var moveItem: ((CollectionViewSectionedDataSource<S>, sourceIndexPath:IndexPath, destinationIndexPath:IndexPath) -> Void)?
public var canMoveItemAtIndexPath: ((CollectionViewSectionedDataSource<S>, indexPath:IndexPath) -> Bool)?
public override init() {
self.cellFactory = {_, _, _, _ in return (nil as UICollectionViewCell?)! }
@ -130,25 +130,25 @@ public class CollectionViewSectionedDataSource<S: SectionModelType>
// UICollectionViewDataSource
override func _numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
override func _numberOfSectionsInCollectionView(_ collectionView: UICollectionView) -> Int {
return _sectionModels.count
}
override func _rx_collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
override func _rx_collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return _sectionModels[section].items.count
}
override func _rx_collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
precondition(indexPath.item < _sectionModels[indexPath.section].items.count)
override func _rx_collectionView(_ collectionView: UICollectionView, cellForItemAtIndexPath indexPath: IndexPath) -> UICollectionViewCell {
precondition((indexPath as NSIndexPath).item < _sectionModels[(indexPath as NSIndexPath).section].items.count)
return cellFactory(self, collectionView, indexPath, itemAtIndexPath(indexPath))
}
override func _rx_collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
override func _rx_collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: IndexPath) -> UICollectionReusableView {
return supplementaryViewFactory(self, collectionView, kind, indexPath)
}
override func _rx_collectionView(collectionView: UICollectionView, canMoveItemAtIndexPath indexPath: NSIndexPath) -> Bool {
override func _rx_collectionView(_ collectionView: UICollectionView, canMoveItemAtIndexPath indexPath: IndexPath) -> Bool {
guard let canMoveItem = canMoveItemAtIndexPath?(self, indexPath: indexPath) else {
return super._rx_collectionView(collectionView, canMoveItemAtIndexPath: indexPath)
}
@ -156,8 +156,8 @@ public class CollectionViewSectionedDataSource<S: SectionModelType>
return canMoveItem
}
override func _rx_collectionView(collectionView: UICollectionView, moveItemAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
override func _rx_collectionView(_ collectionView: UICollectionView, moveItemAtIndexPath sourceIndexPath: IndexPath, toIndexPath destinationIndexPath: IndexPath) {
self._sectionModels.moveFromSourceIndexPath(sourceIndexPath, destinationIndexPath: destinationIndexPath)
}
}
}

View File

@ -9,27 +9,27 @@
import Foundation
enum RxDataSourceError : ErrorProtocol {
case UnwrappingOptional
case PreconditionFailed(message: String)
case unwrappingOptional
case preconditionFailed(message: String)
}
func rxPrecondition(condition: Bool, @autoclosure _ message: () -> String) throws -> () {
func rxPrecondition(_ condition: Bool, _ message: @autoclosure() -> String) throws -> () {
if condition {
return
}
rxDebugFatalError("Precondition failed")
throw RxDataSourceError.PreconditionFailed(message: message())
throw RxDataSourceError.preconditionFailed(message: message())
}
func rxDebugFatalError(error: ErrorProtocol) {
func rxDebugFatalError(_ error: ErrorProtocol) {
rxDebugFatalError("\(error)")
}
func rxDebugFatalError(message: String) {
func rxDebugFatalError(_ message: String) {
#if DEBUG
fatalError(message)
#else
print(message)
#endif
}
}

View File

@ -11,48 +11,48 @@ import Foundation
public enum DifferentiatorError
: ErrorProtocol
, CustomDebugStringConvertible {
case DuplicateItem(item: Any)
case DuplicateSection(section: Any)
case duplicateItem(item: Any)
case duplicateSection(section: Any)
}
extension DifferentiatorError {
public var debugDescription: String {
switch self {
case let .DuplicateItem(item):
case let .duplicateItem(item):
return "Duplicate item \(item)"
case let .DuplicateSection(section):
case let .duplicateSection(section):
return "Duplicate section \(section)"
}
}
}
enum EditEvent : CustomDebugStringConvertible {
case Inserted // can't be found in old sections
case InsertedAutomatically // Item inside section being inserted
case Deleted // Was in old, not in new, in it's place is something "not new" :(, otherwise it's Updated
case DeletedAutomatically // Item inside section that is being deleted
case Moved // same item, but was on different index, and needs explicit move
case MovedAutomatically // don't need to specify any changes for those rows
case Untouched
case inserted // can't be found in old sections
case insertedAutomatically // Item inside section being inserted
case deleted // Was in old, not in new, in it's place is something "not new" :(, otherwise it's Updated
case deletedAutomatically // Item inside section that is being deleted
case moved // same item, but was on different index, and needs explicit move
case movedAutomatically // don't need to specify any changes for those rows
case untouched
}
extension EditEvent {
var debugDescription: String {
get {
switch self {
case .Inserted:
case .inserted:
return "Inserted"
case .InsertedAutomatically:
case .insertedAutomatically:
return "InsertedAutomatically"
case .Deleted:
case .deleted:
return "Deleted"
case .DeletedAutomatically:
case .deletedAutomatically:
return "DeletedAutomatically"
case .Moved:
case .moved:
return "Moved"
case .MovedAutomatically:
case .movedAutomatically:
return "MovedAutomatically"
case .Untouched:
case .untouched:
return "Untouched"
}
}
@ -75,7 +75,7 @@ extension SectionAssociatedData : CustomDebugStringConvertible {
extension SectionAssociatedData {
static var initial: SectionAssociatedData {
return SectionAssociatedData(event: .Untouched, indexAfterDelete: nil, moveIndex: nil)
return SectionAssociatedData(event: .untouched, indexAfterDelete: nil, moveIndex: nil)
}
}
@ -95,18 +95,18 @@ extension ItemAssociatedData : CustomDebugStringConvertible {
extension ItemAssociatedData {
static var initial : ItemAssociatedData {
return ItemAssociatedData(event: .Untouched, indexAfterDelete: nil, moveIndex: nil)
return ItemAssociatedData(event: .untouched, indexAfterDelete: nil, moveIndex: nil)
}
}
func indexSections<S: AnimatableSectionModelType>(sections: [S]) throws -> [S.Identity : Int] {
func indexSections<S: AnimatableSectionModelType>(_ sections: [S]) throws -> [S.Identity : Int] {
var indexedSections: [S.Identity : Int] = [:]
for (i, section) in sections.enumerate() {
for (i, section) in sections.enumerated() {
guard indexedSections[section.identity] == nil else {
#if DEBUG
precondition(indexedSections[section.identity] == nil, "Section \(section) has already been indexed at \(indexedSections[section.identity]!)")
#endif
throw DifferentiatorError.DuplicateItem(item: section)
throw DifferentiatorError.duplicateItem(item: section)
}
indexedSections[section.identity] = i
}
@ -114,7 +114,7 @@ func indexSections<S: AnimatableSectionModelType>(sections: [S]) throws -> [S.Id
return indexedSections
}
func indexSectionItems<S: AnimatableSectionModelType>(sections: [S]) throws -> [S.Item.Identity : (Int, Int)] {
func indexSectionItems<S: AnimatableSectionModelType>(_ sections: [S]) throws -> [S.Item.Identity : (Int, Int)] {
var totalItems = 0
for i in 0 ..< sections.count {
totalItems += sections[i].items.count
@ -124,12 +124,12 @@ func indexSectionItems<S: AnimatableSectionModelType>(sections: [S]) throws -> [
var indexedItems: [S.Item.Identity : (Int, Int)] = Dictionary(minimumCapacity: totalItems * 3)
for i in 0 ..< sections.count {
for (j, item) in sections[i].items.enumerate() {
for (j, item) in sections[i].items.enumerated() {
guard indexedItems[item.identity] == nil else {
#if DEBUG
precondition(indexedItems[item.identity] == nil, "Item \(item) has already been indexed at \(indexedItems[item.identity]!)" )
#endif
throw DifferentiatorError.DuplicateItem(item: item)
throw DifferentiatorError.duplicateItem(item: item)
}
indexedItems[item.identity] = (i, j)
}
@ -263,7 +263,7 @@ to = [
// There maybe exists a better division, but time will tell.
//
public func differencesForSectionedView<S: AnimatableSectionModelType>(
initialSections: [S],
_ initialSections: [S],
finalSections: [S]
)
throws -> [Changeset<S>] {
@ -273,9 +273,9 @@ public func differencesForSectionedView<S: AnimatableSectionModelType>(
var sectionCommands = try CommandGenerator<S>.generatorForInitialSections(initialSections, finalSections: finalSections)
result.appendContentsOf(try sectionCommands.generateDeleteSections())
result.appendContentsOf(try sectionCommands.generateInsertAndMoveSections())
result.appendContentsOf(try sectionCommands.generateNewAndMovedItems())
result.append(contentsOf: try sectionCommands.generateDeleteSections())
result.append(contentsOf: try sectionCommands.generateInsertAndMoveSections())
result.append(contentsOf: try sectionCommands.generateNewAndMovedItems())
return result
}
@ -291,7 +291,7 @@ struct CommandGenerator<S: AnimatableSectionModelType> {
let finalItemData: [[ItemAssociatedData]]
static func generatorForInitialSections(
initialSections: [S],
_ initialSections: [S],
finalSections: [S]
) throws -> CommandGenerator<S> {
@ -314,25 +314,25 @@ struct CommandGenerator<S: AnimatableSectionModelType> {
)
}
static func calculateItemMovementsForInitialSections(initialSections: [S], finalSections: [S],
static func calculateItemMovementsForInitialSections(_ initialSections: [S], finalSections: [S],
initialSectionData: [SectionAssociatedData], finalSectionData: [SectionAssociatedData]) throws -> ([[ItemAssociatedData]], [[ItemAssociatedData]]) {
var initialItemData = initialSections.map { s in
return [ItemAssociatedData](count: s.items.count, repeatedValue: ItemAssociatedData.initial)
return [ItemAssociatedData](repeating: ItemAssociatedData.initial, count: s.items.count)
}
var finalItemData = finalSections.map { s in
return [ItemAssociatedData](count: s.items.count, repeatedValue: ItemAssociatedData.initial)
return [ItemAssociatedData](repeating: ItemAssociatedData.initial, count: s.items.count)
}
let initialItemIndexes = try indexSectionItems(initialSections)
for i in 0 ..< finalSections.count {
for (j, item) in finalSections[i].items.enumerate() {
for (j, item) in finalSections[i].items.enumerated() {
guard let initialItemIndex = initialItemIndexes[item.identity] else {
continue
}
if initialItemData[initialItemIndex.0][initialItemIndex.1].moveIndex != nil {
throw DifferentiatorError.DuplicateItem(item: item)
throw DifferentiatorError.duplicateItem(item: item)
}
initialItemData[initialItemIndex.0][initialItemIndex.1].moveIndex = ItemPath(sectionIndex: i, itemIndex: j)
@ -346,7 +346,7 @@ struct CommandGenerator<S: AnimatableSectionModelType> {
}
while i2 < initialSections[initialSectionIndex].items.count {
if initialItemData[initialSectionIndex][i2].event == .Untouched {
if initialItemData[initialSectionIndex][i2].event == .untouched {
return i2
}
@ -366,15 +366,15 @@ struct CommandGenerator<S: AnimatableSectionModelType> {
for j in 0 ..< initialSections[i].items.count {
guard let finalIndexPath = initialItemData[i][j].moveIndex else {
initialItemData[i][j].event = .Deleted
initialItemData[i][j].event = .deleted
continue
}
// from this point below, section has to be move type because it's initial and not deleted
// because there is no move to inserted section
if finalSectionData[finalIndexPath.sectionIndex].event == .Inserted {
initialItemData[i][j].event = .Deleted
if finalSectionData[finalIndexPath.sectionIndex].event == .inserted {
initialItemData[i][j].event = .deleted
continue
}
@ -394,25 +394,25 @@ struct CommandGenerator<S: AnimatableSectionModelType> {
untouchedIndex = findNextUntouchedOldIndex(originalSectionIndex, untouchedIndex)
guard let originalIndex = finalItemData[i][j].moveIndex else {
finalItemData[i][j].event = .Inserted
finalItemData[i][j].event = .inserted
continue
}
// In case trying to move from deleted section, abort, otherwise it will crash table view
if initialSectionData[originalIndex.sectionIndex].event == .Deleted {
finalItemData[i][j].event = .Inserted
if initialSectionData[originalIndex.sectionIndex].event == .deleted {
finalItemData[i][j].event = .inserted
continue
}
// original section can't be inserted
else if initialSectionData[originalIndex.sectionIndex].event == .Inserted {
else if initialSectionData[originalIndex.sectionIndex].event == .inserted {
try rxPrecondition(false, "New section in initial sections, that is wrong")
}
let initialSectionEvent = initialSectionData[originalIndex.sectionIndex].event
try rxPrecondition(initialSectionEvent == .Moved || initialSectionEvent == .MovedAutomatically, "Section not moved")
try rxPrecondition(initialSectionEvent == .moved || initialSectionEvent == .movedAutomatically, "Section not moved")
let eventType = originalIndex == ItemPath(sectionIndex: originalSectionIndex, itemIndex: untouchedIndex ?? -1)
? EditEvent.MovedAutomatically : EditEvent.Moved
? EditEvent.movedAutomatically : EditEvent.moved
initialItemData[originalIndex.sectionIndex][originalIndex.itemIndex].event = eventType
finalItemData[i][j].event = eventType
@ -423,20 +423,20 @@ struct CommandGenerator<S: AnimatableSectionModelType> {
return (initialItemData, finalItemData)
}
static func calculateSectionMovementsForInitialSections(initialSections: [S], finalSections: [S]) throws -> ([SectionAssociatedData], [SectionAssociatedData]) {
static func calculateSectionMovementsForInitialSections(_ initialSections: [S], finalSections: [S]) throws -> ([SectionAssociatedData], [SectionAssociatedData]) {
let initialSectionIndexes = try indexSections(initialSections)
var initialSectionData = [SectionAssociatedData](count: initialSections.count, repeatedValue: SectionAssociatedData.initial)
var finalSectionData = [SectionAssociatedData](count: finalSections.count, repeatedValue: SectionAssociatedData.initial)
var initialSectionData = [SectionAssociatedData](repeating: SectionAssociatedData.initial, count: initialSections.count)
var finalSectionData = [SectionAssociatedData](repeating: SectionAssociatedData.initial, count: finalSections.count)
for (i, section) in finalSections.enumerate() {
for (i, section) in finalSections.enumerated() {
guard let initialSectionIndex = initialSectionIndexes[section.identity] else {
continue
}
if initialSectionData[initialSectionIndex].moveIndex != nil {
throw DifferentiatorError.DuplicateSection(section: section)
throw DifferentiatorError.duplicateSection(section: section)
}
initialSectionData[initialSectionIndex].moveIndex = i
@ -448,7 +448,7 @@ struct CommandGenerator<S: AnimatableSectionModelType> {
// deleted sections
for i in 0 ..< initialSectionData.count {
if initialSectionData[i].moveIndex == nil {
initialSectionData[i].event = .Deleted
initialSectionData[i].event = .deleted
continue
}
@ -465,7 +465,7 @@ struct CommandGenerator<S: AnimatableSectionModelType> {
}
while i < initialSections.count {
if initialSectionData[i].event == .Untouched {
if initialSectionData[i].event == .untouched {
return i
}
@ -483,20 +483,20 @@ struct CommandGenerator<S: AnimatableSectionModelType> {
// oh, it did exist
if let oldSectionIndex = finalSectionData[i].moveIndex {
let moveType = oldSectionIndex != untouchedOldIndex ? EditEvent.Moved : EditEvent.MovedAutomatically
let moveType = oldSectionIndex != untouchedOldIndex ? EditEvent.moved : EditEvent.movedAutomatically
finalSectionData[i].event = moveType
initialSectionData[oldSectionIndex].event = moveType
}
else {
finalSectionData[i].event = .Inserted
finalSectionData[i].event = .inserted
}
}
// inserted sections
for (i, section) in finalSectionData.enumerate() {
for (i, section) in finalSectionData.enumerated() {
if section.moveIndex == nil {
finalSectionData[i].event == .Inserted
finalSectionData[i].event == .inserted
}
}
@ -512,13 +512,13 @@ struct CommandGenerator<S: AnimatableSectionModelType> {
// mark deleted items {
// 1rst stage again (I know, I know ...)
for (i, initialSection) in initialSections.enumerate() {
for (i, initialSection) in initialSections.enumerated() {
let event = initialSectionData[i].event
// Deleted section will take care of deleting child items.
// In case of moving an item from deleted section, tableview will
// crash anyway, so this is not limiting anything.
if event == .Deleted {
if event == .deleted {
deletedSections.append(i)
continue
}
@ -527,9 +527,9 @@ struct CommandGenerator<S: AnimatableSectionModelType> {
for j in 0 ..< initialSection.items.count {
let event = initialItemData[i][j].event
switch event {
case .Deleted:
case .deleted:
deletedItems.append(ItemPath(sectionIndex: i, itemIndex: j))
case .Moved, .MovedAutomatically:
case .moved, .movedAutomatically:
let finalItemIndex = try initialItemData[i][j].moveIndex.unwrap()
let finalItem = finalSections[finalItemIndex]
if finalItem != initialSections[i].items[j] {
@ -564,11 +564,11 @@ struct CommandGenerator<S: AnimatableSectionModelType> {
for i in 0 ..< initialSections.count {
switch initialSectionData[i].event {
case .Deleted:
case .deleted:
break
case .Moved:
case .moved:
movedSections.append((from: try initialSectionData[i].indexAfterDelete.unwrap(), to: try initialSectionData[i].moveIndex.unwrap()))
case .MovedAutomatically:
case .movedAutomatically:
break
default:
try rxPrecondition(false, "Unhandled case in initial sections")
@ -577,7 +577,7 @@ struct CommandGenerator<S: AnimatableSectionModelType> {
for i in 0 ..< finalSections.count {
switch finalSectionData[i].event {
case .Inserted:
case .inserted:
insertedSections.append(i)
default:
break
@ -589,22 +589,22 @@ struct CommandGenerator<S: AnimatableSectionModelType> {
}
// sections should be in place, but items should be original without deleted ones
let sectionsAfterChange: [S] = try self.finalSections.enumerate().map { i, s -> S in
let sectionsAfterChange: [S] = try self.finalSections.enumerated().map { i, s -> S in
let event = self.finalSectionData[i].event
if event == .Inserted {
if event == .inserted {
// it's already set up
return s
}
else if event == .Moved || event == .MovedAutomatically {
else if event == .moved || event == .movedAutomatically {
let originalSectionIndex = try finalSectionData[i].moveIndex.unwrap()
let originalSection = initialSections[originalSectionIndex]
var items: [S.Item] = []
for (j, _) in originalSection.items.enumerate() {
for (j, _) in originalSection.items.enumerated() {
let initialData = self.initialItemData[originalSectionIndex][j]
guard initialData.event != .Deleted else {
guard initialData.event != .deleted else {
continue
}
@ -642,21 +642,21 @@ struct CommandGenerator<S: AnimatableSectionModelType> {
let sectionEvent = finalSectionData[i].event
// new and deleted sections cause reload automatically
if sectionEvent != .Moved && sectionEvent != .MovedAutomatically {
if sectionEvent != .moved && sectionEvent != .movedAutomatically {
continue
}
for j in 0 ..< finalSection.items.count {
let currentItemEvent = finalItemData[i][j].event
try rxPrecondition(currentItemEvent != .Untouched, "Current event is not untouched")
try rxPrecondition(currentItemEvent != .untouched, "Current event is not untouched")
let event = finalItemData[i][j].event
switch event {
case .Inserted:
case .inserted:
insertedItems.append(ItemPath(sectionIndex: i, itemIndex: j))
case .Moved:
case .moved:
let originalIndex = try finalItemData[i][j].moveIndex.unwrap()
let finalSectionIndex = try initialSectionData[originalIndex.sectionIndex].moveIndex.unwrap()
let moveFromItemWithIndex = try initialItemData[originalIndex.sectionIndex][originalIndex.itemIndex].indexAfterDelete.unwrap()
@ -682,4 +682,4 @@ struct CommandGenerator<S: AnimatableSectionModelType> {
movedItems: movedItems
)]
}
}
}

View File

@ -15,7 +15,7 @@ extension Optional {
}
else {
rxDebugFatalError("Error during unwrapping optional")
throw RxDataSourceError.UnwrappingOptional
throw RxDataSourceError.unwrappingOptional
}
}
}
}

View File

@ -17,82 +17,82 @@ public class _TableViewSectionedDataSource
: NSObject
, UITableViewDataSource {
func _numberOfSectionsInTableView(tableView: UITableView) -> Int {
func _numberOfSectionsInTableView(_ tableView: UITableView) -> Int {
return 1
}
public func numberOfSectionsInTableView(tableView: UITableView) -> Int {
public func numberOfSections(in tableView: UITableView) -> Int {
return _numberOfSectionsInTableView(tableView)
}
func _rx_tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
func _rx_tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 0
}
public func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return _rx_tableView(tableView, numberOfRowsInSection: section)
}
func _rx_tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
func _rx_tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell {
return (nil as UITableViewCell?)!
}
public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return _rx_tableView(tableView, cellForRowAtIndexPath: indexPath)
}
func _rx_tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
func _rx_tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return nil
}
public func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
public func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return _rx_tableView(tableView, titleForHeaderInSection: section)
}
func _rx_tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String? {
func _rx_tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return nil
}
public func tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String? {
public func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return _rx_tableView(tableView, titleForFooterInSection: section)
}
func _rx_tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
func _rx_tableView(_ tableView: UITableView, canEditRowAtIndexPath indexPath: IndexPath) -> Bool {
return true
}
public func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
public func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return _rx_tableView(tableView, canEditRowAtIndexPath: indexPath)
}
func _rx_tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
func _rx_tableView(_ tableView: UITableView, canMoveRowAtIndexPath indexPath: IndexPath) -> Bool {
return false
}
public func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
public func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return _rx_tableView(tableView, canMoveRowAtIndexPath: indexPath)
}
func _sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {
func _sectionIndexTitlesForTableView(_ tableView: UITableView) -> [String]? {
return nil
}
public func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {
public func sectionIndexTitles(for tableView: UITableView) -> [String]? {
return _sectionIndexTitlesForTableView(tableView)
}
func _rx_tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
func _rx_tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
return 0
}
public func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
public func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
return _rx_tableView(tableView, sectionForSectionIndexTitle: title, atIndex: index)
}
func _rx_tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
func _rx_tableView(_ tableView: UITableView, moveRowAtIndexPath sourceIndexPath: IndexPath, toIndexPath destinationIndexPath: IndexPath) {
}
public func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
public func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
_rx_tableView(tableView, moveRowAtIndexPath: sourceIndexPath, toIndexPath: destinationIndexPath)
}
}
@ -103,7 +103,7 @@ public class RxTableViewSectionedDataSource<S: SectionModelType>
public typealias I = S.Item
public typealias Section = S
public typealias CellFactory = (RxTableViewSectionedDataSource<S>, UITableView, NSIndexPath, I) -> UITableViewCell
public typealias CellFactory = (RxTableViewSectionedDataSource<S>, UITableView, IndexPath, I) -> UITableViewCell
// This structure exists because model can be mutable
// In that case current state value should be preserved.
@ -119,26 +119,26 @@ public class RxTableViewSectionedDataSource<S: SectionModelType>
return _sectionModels.map { Section(original: $0.model, items: $0.items) }
}
public func sectionAtIndex(section: Int) -> S {
public func sectionAtIndex(_ section: Int) -> S {
let sectionModel = _sectionModels[section]
return Section(original: sectionModel.model, items: sectionModel.items)
}
public func itemAtIndexPath(indexPath: NSIndexPath) -> I {
return self._sectionModels[indexPath.section].items[indexPath.item]
public func itemAtIndexPath(_ indexPath: IndexPath) -> I {
return self._sectionModels[(indexPath as NSIndexPath).section].items[(indexPath as NSIndexPath).item]
}
public func setItem(item item: I, indexPath: NSIndexPath) {
var section = self._sectionModels[indexPath.section]
section.items[indexPath.item] = item
self._sectionModels[indexPath.section] = section
public func setItem(item: I, indexPath: IndexPath) {
var section = self._sectionModels[(indexPath as NSIndexPath).section]
section.items[(indexPath as NSIndexPath).item] = item
self._sectionModels[(indexPath as NSIndexPath).section] = section
}
public func modelAtIndexPath(indexPath: NSIndexPath) throws -> Any {
public func modelAtIndexPath(_ indexPath: IndexPath) throws -> Any {
return itemAtIndexPath(indexPath)
}
public func setSections(sections: [S]) {
public func setSections(_ sections: [S]) {
self._sectionModels = sections.map { SectionModelSnapshot(model: $0, items: $0.items) }
}
@ -147,13 +147,13 @@ public class RxTableViewSectionedDataSource<S: SectionModelType>
public var titleForHeaderInSection: ((RxTableViewSectionedDataSource<S>, section: Int) -> String?)?
public var titleForFooterInSection: ((RxTableViewSectionedDataSource<S>, section: Int) -> String?)?
public var canEditRowAtIndexPath: ((RxTableViewSectionedDataSource<S>, indexPath: NSIndexPath) -> Bool)?
public var canMoveRowAtIndexPath: ((RxTableViewSectionedDataSource<S>, indexPath: NSIndexPath) -> Bool)?
public var canEditRowAtIndexPath: ((RxTableViewSectionedDataSource<S>, indexPath: IndexPath) -> Bool)?
public var canMoveRowAtIndexPath: ((RxTableViewSectionedDataSource<S>, indexPath: IndexPath) -> Bool)?
public var sectionIndexTitles: ((RxTableViewSectionedDataSource<S>) -> [String]?)?
public var sectionForSectionIndexTitle:((RxTableViewSectionedDataSource<S>, title: String, index: Int) -> Int)?
public var rowAnimation: UITableViewRowAnimation = .Automatic
public var rowAnimation: UITableViewRowAnimation = .automatic
public override init() {
super.init()
@ -168,29 +168,29 @@ public class RxTableViewSectionedDataSource<S: SectionModelType>
// UITableViewDataSource
override func _numberOfSectionsInTableView(tableView: UITableView) -> Int {
override func _numberOfSectionsInTableView(_ tableView: UITableView) -> Int {
return _sectionModels.count
}
override func _rx_tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
override func _rx_tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return _sectionModels[section].items.count
}
override func _rx_tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
precondition(indexPath.item < _sectionModels[indexPath.section].items.count)
override func _rx_tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell {
precondition((indexPath as NSIndexPath).item < _sectionModels[(indexPath as NSIndexPath).section].items.count)
return configureCell(self, tableView, indexPath, itemAtIndexPath(indexPath))
}
override func _rx_tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
override func _rx_tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return titleForHeaderInSection?(self, section: section)
}
override func _rx_tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String? {
override func _rx_tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return titleForFooterInSection?(self, section: section)
}
override func _rx_tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
override func _rx_tableView(_ tableView: UITableView, canEditRowAtIndexPath indexPath: IndexPath) -> Bool {
guard let canEditRow = canEditRowAtIndexPath?(self, indexPath: indexPath) else {
return super._rx_tableView(tableView, canEditRowAtIndexPath: indexPath)
}
@ -198,7 +198,7 @@ public class RxTableViewSectionedDataSource<S: SectionModelType>
return canEditRow
}
override func _rx_tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
override func _rx_tableView(_ tableView: UITableView, canMoveRowAtIndexPath indexPath: IndexPath) -> Bool {
guard let canMoveRow = canMoveRowAtIndexPath?(self, indexPath: indexPath) else {
return super._rx_tableView(tableView, canMoveRowAtIndexPath: indexPath)
}
@ -206,11 +206,11 @@ public class RxTableViewSectionedDataSource<S: SectionModelType>
return canMoveRow
}
override func _rx_tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
override func _rx_tableView(_ tableView: UITableView, moveRowAtIndexPath sourceIndexPath: IndexPath, toIndexPath destinationIndexPath: IndexPath) {
self._sectionModels.moveFromSourceIndexPath(sourceIndexPath, destinationIndexPath: destinationIndexPath)
}
override func _sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {
override func _sectionIndexTitlesForTableView(_ tableView: UITableView) -> [String]? {
guard let titles = sectionIndexTitles?(self) else {
return super._sectionIndexTitlesForTableView(tableView)
}
@ -218,7 +218,7 @@ public class RxTableViewSectionedDataSource<S: SectionModelType>
return titles
}
override func _rx_tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
override func _rx_tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
guard let section = sectionForSectionIndexTitle?(self, title: title, index: index) else {
return super._rx_tableView(tableView, sectionForSectionIndexTitle: title, atIndex: index)
}

View File

@ -9,49 +9,49 @@
import Foundation
import UIKit
func indexSet(values: [Int]) -> NSIndexSet {
func indexSet(_ values: [Int]) -> IndexSet {
let indexSet = NSMutableIndexSet()
for i in values {
indexSet.addIndex(i)
indexSet.add(i)
}
return indexSet
return indexSet as IndexSet
}
extension UITableView : SectionedViewType {
public func insertItemsAtIndexPaths(paths: [NSIndexPath], animationStyle: UITableViewRowAnimation) {
self.insertRowsAtIndexPaths(paths, withRowAnimation: animationStyle)
public func insertItemsAtIndexPaths(_ paths: [IndexPath], animationStyle: UITableViewRowAnimation) {
self.insertRows(at: paths, with: animationStyle)
}
public func deleteItemsAtIndexPaths(paths: [NSIndexPath], animationStyle: UITableViewRowAnimation) {
self.deleteRowsAtIndexPaths(paths, withRowAnimation: animationStyle)
public func deleteItemsAtIndexPaths(_ paths: [IndexPath], animationStyle: UITableViewRowAnimation) {
self.deleteRows(at: paths, with: animationStyle)
}
public func moveItemAtIndexPath(from: NSIndexPath, to: NSIndexPath) {
self.moveRowAtIndexPath(from, toIndexPath: to)
public func moveItemAtIndexPath(_ from: IndexPath, to: IndexPath) {
self.moveRow(at: from, to: to)
}
public func reloadItemsAtIndexPaths(paths: [NSIndexPath], animationStyle: UITableViewRowAnimation) {
self.reloadRowsAtIndexPaths(paths, withRowAnimation: animationStyle)
public func reloadItemsAtIndexPaths(_ paths: [IndexPath], animationStyle: UITableViewRowAnimation) {
self.reloadRows(at: paths, with: animationStyle)
}
public func insertSections(sections: [Int], animationStyle: UITableViewRowAnimation) {
self.insertSections(indexSet(sections), withRowAnimation: animationStyle)
public func insertSections(_ sections: [Int], animationStyle: UITableViewRowAnimation) {
self.insertSections(indexSet(sections), with: animationStyle)
}
public func deleteSections(sections: [Int], animationStyle: UITableViewRowAnimation) {
self.deleteSections(indexSet(sections), withRowAnimation: animationStyle)
public func deleteSections(_ sections: [Int], animationStyle: UITableViewRowAnimation) {
self.deleteSections(indexSet(sections), with: animationStyle)
}
public func moveSection(from: Int, to: Int) {
public func moveSection(_ from: Int, to: Int) {
self.moveSection(from, toSection: to)
}
public func reloadSections(sections: [Int], animationStyle: UITableViewRowAnimation) {
self.reloadSections(indexSet(sections), withRowAnimation: animationStyle)
public func reloadSections(_ sections: [Int], animationStyle: UITableViewRowAnimation) {
self.reloadSections(indexSet(sections), with: animationStyle)
}
public func performBatchUpdates<S: SectionModelType>(changes: Changeset<S>, animationConfiguration: AnimationConfiguration) {
public func performBatchUpdates<S: SectionModelType>(_ changes: Changeset<S>, animationConfiguration: AnimationConfiguration) {
self.beginUpdates()
_performBatchUpdates(self, changes: changes, animationConfiguration: animationConfiguration)
self.endUpdates()
@ -59,39 +59,39 @@ extension UITableView : SectionedViewType {
}
extension UICollectionView : SectionedViewType {
public func insertItemsAtIndexPaths(paths: [NSIndexPath], animationStyle: UITableViewRowAnimation) {
self.insertItemsAtIndexPaths(paths)
public func insertItemsAtIndexPaths(_ paths: [IndexPath], animationStyle: UITableViewRowAnimation) {
self.insertItems(at: paths)
}
public func deleteItemsAtIndexPaths(paths: [NSIndexPath], animationStyle: UITableViewRowAnimation) {
self.deleteItemsAtIndexPaths(paths)
public func deleteItemsAtIndexPaths(_ paths: [IndexPath], animationStyle: UITableViewRowAnimation) {
self.deleteItems(at: paths)
}
public func moveItemAtIndexPath(from: NSIndexPath, to: NSIndexPath) {
self.moveItemAtIndexPath(from, toIndexPath: to)
public func moveItemAtIndexPath(_ from: IndexPath, to: IndexPath) {
self.moveItem(at: from, to: to)
}
public func reloadItemsAtIndexPaths(paths: [NSIndexPath], animationStyle: UITableViewRowAnimation) {
self.reloadItemsAtIndexPaths(paths)
public func reloadItemsAtIndexPaths(_ paths: [IndexPath], animationStyle: UITableViewRowAnimation) {
self.reloadItems(at: paths)
}
public func insertSections(sections: [Int], animationStyle: UITableViewRowAnimation) {
public func insertSections(_ sections: [Int], animationStyle: UITableViewRowAnimation) {
self.insertSections(indexSet(sections))
}
public func deleteSections(sections: [Int], animationStyle: UITableViewRowAnimation) {
public func deleteSections(_ sections: [Int], animationStyle: UITableViewRowAnimation) {
self.deleteSections(indexSet(sections))
}
public func moveSection(from: Int, to: Int) {
public func moveSection(_ from: Int, to: Int) {
self.moveSection(from, toSection: to)
}
public func reloadSections(sections: [Int], animationStyle: UITableViewRowAnimation) {
public func reloadSections(_ sections: [Int], animationStyle: UITableViewRowAnimation) {
self.reloadSections(indexSet(sections))
}
public func performBatchUpdates<S: SectionModelType>(changes: Changeset<S>, animationConfiguration: AnimationConfiguration) {
public func performBatchUpdates<S: SectionModelType>(_ changes: Changeset<S>, animationConfiguration: AnimationConfiguration) {
self.performBatchUpdates({ () -> Void in
_performBatchUpdates(self, changes: changes, animationConfiguration: animationConfiguration)
}, completion: { (completed: Bool) -> Void in
@ -100,20 +100,20 @@ extension UICollectionView : SectionedViewType {
}
public protocol SectionedViewType {
func insertItemsAtIndexPaths(paths: [NSIndexPath], animationStyle: UITableViewRowAnimation)
func deleteItemsAtIndexPaths(paths: [NSIndexPath], animationStyle: UITableViewRowAnimation)
func moveItemAtIndexPath(from: NSIndexPath, to: NSIndexPath)
func reloadItemsAtIndexPaths(paths: [NSIndexPath], animationStyle: UITableViewRowAnimation)
func insertItemsAtIndexPaths(_ paths: [IndexPath], animationStyle: UITableViewRowAnimation)
func deleteItemsAtIndexPaths(_ paths: [IndexPath], animationStyle: UITableViewRowAnimation)
func moveItemAtIndexPath(_ from: IndexPath, to: IndexPath)
func reloadItemsAtIndexPaths(_ paths: [IndexPath], animationStyle: UITableViewRowAnimation)
func insertSections(sections: [Int], animationStyle: UITableViewRowAnimation)
func deleteSections(sections: [Int], animationStyle: UITableViewRowAnimation)
func moveSection(from: Int, to: Int)
func reloadSections(sections: [Int], animationStyle: UITableViewRowAnimation)
func insertSections(_ sections: [Int], animationStyle: UITableViewRowAnimation)
func deleteSections(_ sections: [Int], animationStyle: UITableViewRowAnimation)
func moveSection(_ from: Int, to: Int)
func reloadSections(_ sections: [Int], animationStyle: UITableViewRowAnimation)
func performBatchUpdates<S>(changes: Changeset<S>, animationConfiguration: AnimationConfiguration)
func performBatchUpdates<S>(_ changes: Changeset<S>, animationConfiguration: AnimationConfiguration)
}
func _performBatchUpdates<V: SectionedViewType, S: SectionModelType>(view: V, changes: Changeset<S>, animationConfiguration:AnimationConfiguration) {
func _performBatchUpdates<V: SectionedViewType, S: SectionModelType>(_ view: V, changes: Changeset<S>, animationConfiguration:AnimationConfiguration) {
typealias I = S.Item
view.deleteSections(changes.deletedSections, animationStyle: animationConfiguration.deleteAnimation)
@ -126,22 +126,22 @@ func _performBatchUpdates<V: SectionedViewType, S: SectionModelType>(view: V, ch
}
view.deleteItemsAtIndexPaths(
changes.deletedItems.map { NSIndexPath(forItem: $0.itemIndex, inSection: $0.sectionIndex) },
changes.deletedItems.map { IndexPath(item: $0.itemIndex, section: $0.sectionIndex) },
animationStyle: animationConfiguration.deleteAnimation
)
view.insertItemsAtIndexPaths(
changes.insertedItems.map { NSIndexPath(forItem: $0.itemIndex, inSection: $0.sectionIndex) },
changes.insertedItems.map { IndexPath(item: $0.itemIndex, section: $0.sectionIndex) },
animationStyle: animationConfiguration.insertAnimation
)
view.reloadItemsAtIndexPaths(
changes.updatedItems.map { NSIndexPath(forItem: $0.itemIndex, inSection: $0.sectionIndex) },
changes.updatedItems.map { IndexPath(item: $0.itemIndex, section: $0.sectionIndex) },
animationStyle: animationConfiguration.reloadAnimation
)
for (from, to) in changes.movedItems {
view.moveItemAtIndexPath(
NSIndexPath(forItem: from.itemIndex, inSection: from.sectionIndex),
to: NSIndexPath(forItem: to.itemIndex, inSection: to.sectionIndex)
IndexPath(item: from.itemIndex, section: from.sectionIndex),
to: IndexPath(item: to.itemIndex, section: to.sectionIndex)
)
}
}
}

View File

@ -1912,6 +1912,7 @@
TargetAttributes = {
C83366DC1AD0293800C668A7 = {
CreatedOnToolsVersion = 6.2;
LastSwiftMigration = 0800;
};
C849EF601C3190360048AC4A = {
CreatedOnToolsVersion = 7.2;
@ -2729,6 +2730,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "io.rx.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "RxExample-iOS";
SDKROOT = iphoneos;
SWIFT_VERSION = 3.0;
};
name = Debug;
};
@ -2743,6 +2745,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "io.rx.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "RxExample-iOS";
SDKROOT = iphoneos;
SWIFT_VERSION = 3.0;
};
name = Release;
};
@ -2873,6 +2876,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "io.rx.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "RxExample-iOS";
SDKROOT = iphoneos;
SWIFT_VERSION = 3.0;
};
name = "Release-Tests";
};

View File

@ -19,23 +19,23 @@ import Foundation
let MB = 1024 * 1024
func exampleError(error: String, location: String = "\(#file):\(#line)") -> NSError {
func exampleError(_ error: String, location: String = "\(#file):\(#line)") -> NSError {
return NSError(domain: "ExampleError", code: -1, userInfo: [NSLocalizedDescriptionKey: "\(location): \(error)"])
}
extension String {
func toFloat() -> Float? {
let numberFormatter = NSNumberFormatter()
return numberFormatter.numberFromString(self)?.floatValue
let numberFormatter = NumberFormatter()
return numberFormatter.number(from: self)?.floatValue
}
func toDouble() -> Double? {
let numberFormatter = NSNumberFormatter()
return numberFormatter.numberFromString(self)?.doubleValue
let numberFormatter = NumberFormatter()
return numberFormatter.number(from: self)?.doubleValue
}
}
func showAlert(message: String) {
func showAlert(_ message: String) {
#if os(iOS)
UIAlertView(title: "RxExample", message: message, delegate: nil, cancelButtonTitle: "OK").show()
#elseif os(OSX)
@ -43,4 +43,4 @@ func showAlert(message: String) {
alert.messageText = message
alert.runModal()
#endif
}
}

View File

@ -58,7 +58,7 @@ class APIWrappersViewController: ViewController {
override func viewDidLoad() {
super.viewDidLoad()
datePicker.date = NSDate(timeIntervalSince1970: 0)
datePicker.date = Date(timeIntervalSince1970: 0)
// MARK: UIBarButtonItem
@ -125,7 +125,7 @@ class APIWrappersViewController: ViewController {
// MARK: UIDatePicker
// also test two way binding
let dateValue = Variable(NSDate(timeIntervalSince1970: 0))
let dateValue = Variable(Date(timeIntervalSince1970: 0))
datePicker.rx_date <-> dateValue
@ -199,7 +199,7 @@ class APIWrappersViewController: ViewController {
}
func debug(string: String) {
func debug(_ string: String) {
print(string)
debugLabel.text = string
}

View File

@ -9,11 +9,11 @@
import Foundation
enum Action {
case Clear
case ChangeSign
case Percent
case Operation(Operator)
case Equal
case AddNumber(Character)
case AddDot
}
case clear
case changeSign
case percent
case operation(Operator)
case equal
case addNumber(Character)
case addDot
}

View File

@ -9,7 +9,7 @@
import Foundation
struct CalculatorState {
static let CLEAR_STATE = CalculatorState(previousNumber: nil, action: .Clear, currentNumber: "0", inScreen: "0", replace: true)
static let CLEAR_STATE = CalculatorState(previousNumber: nil, action: .clear, currentNumber: "0", inScreen: "0", replace: true)
let previousNumber: String!
let action: Action
@ -19,64 +19,64 @@ struct CalculatorState {
}
extension CalculatorState {
func tranformState(x: Action) -> CalculatorState {
func tranformState(_ x: Action) -> CalculatorState {
switch x {
case .Clear:
case .clear:
return CalculatorState.CLEAR_STATE
case .AddNumber(let c):
case .addNumber(let c):
return addNumber(c)
case .AddDot:
case .addDot:
return self.addDot()
case .ChangeSign:
case .changeSign:
let d = "\(-Double(self.inScreen)!)"
return CalculatorState(previousNumber: previousNumber, action: action, currentNumber: d, inScreen: d, replace: true)
case .Percent:
case .percent:
let d = "\(Double(self.inScreen)!/100)"
return CalculatorState(previousNumber: previousNumber, action: action, currentNumber: d, inScreen: d, replace: true)
case .Operation(let o):
case .operation(let o):
return performOperation(o)
case .Equal:
case .equal:
return performEqual()
}
}
func addNumber(char: Character) -> CalculatorState {
func addNumber(_ char: Character) -> CalculatorState {
let cn = currentNumber == nil || replace ? String(char) : inScreen + String(char)
return CalculatorState(previousNumber: previousNumber, action: action, currentNumber: cn, inScreen: cn, replace: false)
}
func addDot() -> CalculatorState {
let cn = inScreen.rangeOfString(".") == nil ? currentNumber + "." : currentNumber
return CalculatorState(previousNumber: previousNumber, action: action, currentNumber: cn, inScreen: cn, replace: false)
let cn = inScreen.range(of: ".") == nil ? currentNumber + "." : currentNumber
return CalculatorState(previousNumber: previousNumber, action: action, currentNumber: cn, inScreen: cn!, replace: false)
}
func performOperation(o: Operator) -> CalculatorState {
func performOperation(_ o: Operator) -> CalculatorState {
if previousNumber == nil {
return CalculatorState(previousNumber: currentNumber, action: .Operation(o), currentNumber: nil, inScreen: currentNumber, replace: true)
return CalculatorState(previousNumber: currentNumber, action: .operation(o), currentNumber: nil, inScreen: currentNumber, replace: true)
}
else {
let previous = Double(previousNumber)!
let current = Double(inScreen)!
switch action {
case .Operation(let op):
case .operation(let op):
switch op {
case .Addition:
case .addition:
let result = "\(previous + current)"
return CalculatorState(previousNumber: result, action: .Operation(o), currentNumber: nil, inScreen: result, replace: true)
case .Subtraction:
return CalculatorState(previousNumber: result, action: .operation(o), currentNumber: nil, inScreen: result, replace: true)
case .subtraction:
let result = "\(previous - current)"
return CalculatorState(previousNumber: result, action: .Operation(o), currentNumber: nil, inScreen: result, replace: true)
case .Multiplication:
return CalculatorState(previousNumber: result, action: .operation(o), currentNumber: nil, inScreen: result, replace: true)
case .multiplication:
let result = "\(previous * current)"
return CalculatorState(previousNumber: result, action: .Operation(o), currentNumber: nil, inScreen: result, replace: true)
case .Division:
return CalculatorState(previousNumber: result, action: .operation(o), currentNumber: nil, inScreen: result, replace: true)
case .division:
let result = "\(previous / current)"
return CalculatorState(previousNumber: result, action: .Operation(o), currentNumber: nil, inScreen: result, replace: true)
return CalculatorState(previousNumber: result, action: .operation(o), currentNumber: nil, inScreen: result, replace: true)
}
default:
return CalculatorState(previousNumber: nil, action: .Operation(o), currentNumber: currentNumber, inScreen: inScreen, replace: true)
return CalculatorState(previousNumber: nil, action: .operation(o), currentNumber: currentNumber, inScreen: inScreen, replace: true)
}
}
@ -88,25 +88,25 @@ extension CalculatorState {
let current = Double(inScreen)!
switch action {
case .Operation(let op):
case .operation(let op):
switch op {
case .Addition:
case .addition:
let result = "\(previous! + current)"
return CalculatorState(previousNumber: nil, action: .Clear, currentNumber: result, inScreen: result, replace: true)
case .Subtraction:
return CalculatorState(previousNumber: nil, action: .clear, currentNumber: result, inScreen: result, replace: true)
case .subtraction:
let result = "\(previous! - current)"
return CalculatorState(previousNumber: nil, action: .Clear, currentNumber: result, inScreen: result, replace: true)
case .Multiplication:
return CalculatorState(previousNumber: nil, action: .clear, currentNumber: result, inScreen: result, replace: true)
case .multiplication:
let result = "\(previous! * current)"
return CalculatorState(previousNumber: nil, action: .Clear, currentNumber: result, inScreen: result, replace: true)
case .Division:
return CalculatorState(previousNumber: nil, action: .clear, currentNumber: result, inScreen: result, replace: true)
case .division:
let result = previous! / current
let resultText = result == Double.infinity ? "0" : "\(result)"
return CalculatorState(previousNumber: nil, action: .Clear, currentNumber: resultText, inScreen: resultText, replace: true)
return CalculatorState(previousNumber: nil, action: .clear, currentNumber: resultText, inScreen: resultText, replace: true)
}
default:
return CalculatorState(previousNumber: nil, action: .Clear, currentNumber: currentNumber, inScreen: inScreen, replace: true)
return CalculatorState(previousNumber: nil, action: .clear, currentNumber: currentNumber, inScreen: inScreen, replace: true)
}
}
}
}

View File

@ -43,30 +43,30 @@ class CalculatorViewController: ViewController {
override func viewDidLoad() {
let commands:[Observable<Action>] = [
allClearButton.rx_tap.map { _ in .Clear },
allClearButton.rx_tap.map { _ in .clear },
changeSignButton.rx_tap.map { _ in .ChangeSign },
percentButton.rx_tap.map { _ in .Percent },
changeSignButton.rx_tap.map { _ in .changeSign },
percentButton.rx_tap.map { _ in .percent },
divideButton.rx_tap.map { _ in .Operation(.Division) },
multiplyButton.rx_tap.map { _ in .Operation(.Multiplication) },
minusButton.rx_tap.map { _ in .Operation(.Subtraction) },
plusButton.rx_tap.map { _ in .Operation(.Addition) },
divideButton.rx_tap.map { _ in .operation(.division) },
multiplyButton.rx_tap.map { _ in .operation(.multiplication) },
minusButton.rx_tap.map { _ in .operation(.subtraction) },
plusButton.rx_tap.map { _ in .operation(.addition) },
equalButton.rx_tap.map { _ in .Equal },
equalButton.rx_tap.map { _ in .equal },
dotButton.rx_tap.map { _ in .AddDot },
dotButton.rx_tap.map { _ in .addDot },
zeroButton.rx_tap.map { _ in .AddNumber("0") },
oneButton.rx_tap.map { _ in .AddNumber("1") },
twoButton.rx_tap.map { _ in .AddNumber("2") },
threeButton.rx_tap.map { _ in .AddNumber("3") },
fourButton.rx_tap.map { _ in .AddNumber("4") },
fiveButton.rx_tap.map { _ in .AddNumber("5") },
sixButton.rx_tap.map { _ in .AddNumber("6") },
sevenButton.rx_tap.map { _ in .AddNumber("7") },
eightButton.rx_tap.map { _ in .AddNumber("8") },
nineButton.rx_tap.map { _ in .AddNumber("9") }
zeroButton.rx_tap.map { _ in .addNumber("0") },
oneButton.rx_tap.map { _ in .addNumber("1") },
twoButton.rx_tap.map { _ in .addNumber("2") },
threeButton.rx_tap.map { _ in .addNumber("3") },
fourButton.rx_tap.map { _ in .addNumber("4") },
fiveButton.rx_tap.map { _ in .addNumber("5") },
sixButton.rx_tap.map { _ in .addNumber("6") },
sevenButton.rx_tap.map { _ in .addNumber("7") },
eightButton.rx_tap.map { _ in .addNumber("8") },
nineButton.rx_tap.map { _ in .addNumber("9") }
]
commands
@ -77,17 +77,17 @@ class CalculatorViewController: ViewController {
}
.debug("debugging")
.subscribeNext { [weak self] calState in
self?.resultLabel.text = self?.prettyFormat(calState.inScreen)
self?.resultLabel.text = calState.inScreen
switch calState.action {
case .Operation(let operation):
case .operation(let operation):
switch operation {
case .Addition:
case .addition:
self?.lastSignLabel.text = "+"
case .Subtraction:
case .subtraction:
self?.lastSignLabel.text = "-"
case .Multiplication:
case .multiplication:
self?.lastSignLabel.text = "x"
case .Division:
case .division:
self?.lastSignLabel.text = "/"
}
default:
@ -97,10 +97,11 @@ class CalculatorViewController: ViewController {
.addDisposableTo(disposeBag)
}
//swifts string api sucks
func prettyFormat(str: String) -> String {
if str.hasSuffix(".0") {
return str.substringToIndex(str.endIndex.predecessor().predecessor())
// return str[str.startIndex..<str.endIndex.pre]
}
return str
}

View File

@ -9,8 +9,8 @@
import Foundation
enum Operator {
case Addition
case Subtraction
case Multiplication
case Division
}
case addition
case subtraction
case multiplication
case division
}

View File

@ -19,7 +19,7 @@ class Dependencies {
// *****************************************************************************************
static let sharedDependencies = Dependencies() // Singleton
let URLSession = NSURLSession.sharedSession()
let URLSession = Foundation.URLSession.shared()
let backgroundWorkScheduler: ImmediateSchedulerType
let mainScheduler: SerialDispatchQueueScheduler
let wireframe: Wireframe
@ -28,10 +28,10 @@ class Dependencies {
private init() {
wireframe = DefaultWireframe()
let operationQueue = NSOperationQueue()
let operationQueue = OperationQueue()
operationQueue.maxConcurrentOperationCount = 2
#if !RX_NO_MODULE
operationQueue.qualityOfService = NSQualityOfService.UserInitiated
operationQueue.qualityOfService = QualityOfService.userInitiated
#endif
backgroundWorkScheduler = OperationQueueScheduler(operationQueue: operationQueue)

View File

@ -25,12 +25,12 @@ private extension UIView {
var rx_driveAuthorization: AnyObserver<Bool> {
return UIBindingObserver(UIElement: self) { view, authorized in
if authorized {
view.hidden = true
view.superview?.sendSubviewToBack(view)
view.isHidden = true
view.superview?.sendSubview(toBack:view)
}
else {
view.hidden = false
view.superview?.bringSubviewToFront(view)
view.isHidden = false
view.superview?.bringSubview(toFront:view)
}
}.asObserver()
}
@ -70,7 +70,7 @@ class GeolocationViewController: ViewController {
}
private func openAppPreferences() {
UIApplication.sharedApplication().openURL(NSURL(string: UIApplicationOpenSettingsURLString)!)
UIApplication.shared().openURL(URL(string: UIApplicationOpenSettingsURLString)!)
}
}

View File

@ -34,8 +34,8 @@ extension Repository {
ServiceState state.
*/
enum ServiceState {
case Online
case Offline
case online
case offline
}
/**
@ -45,14 +45,14 @@ enum SearchRepositoryResponse {
/**
New repositories just fetched
*/
case Repositories(repositories: [Repository], nextURL: NSURL?)
case repositories(repositories: [Repository], nextURL: URL?)
/**
In case there was some problem fetching data from service, this will be returned.
It really doesn't matter if that is a failure in network layer, parsing error or something else.
In case data can't be read and parsed properly, something is wrong with server response.
*/
case ServiceOffline
case serviceOffline
/**
This example uses unauthenticated GitHub API. That API does have throttling policy and you won't
@ -62,7 +62,7 @@ enum SearchRepositoryResponse {
Just search like mad, and everything will be handled right.
*/
case LimitExceeded
case limitExceeded
}
/**
@ -117,15 +117,15 @@ extension GitHubSearchRepositoriesAPI {
/**
Public fascade for search.
*/
func search(query: String, loadNextPageTrigger: Observable<Void>) -> Observable<RepositoriesState> {
func search(_ query: String, loadNextPageTrigger: Observable<Void>) -> Observable<RepositoriesState> {
let escapedQuery = query.URLEscaped
let url = NSURL(string: "https://api.github.com/search/repositories?q=\(escapedQuery)")!
let url = URL(string: "https://api.github.com/search/repositories?q=\(escapedQuery)")!
return recursivelySearch([], loadNextURL: url, loadNextPageTrigger: loadNextPageTrigger)
// Here we go again
.startWith(RepositoriesState.empty)
}
private func recursivelySearch(loadedSoFar: [Repository], loadNextURL: NSURL, loadNextPageTrigger: Observable<Void>) -> Observable<RepositoriesState> {
private func recursivelySearch(_ loadedSoFar: [Repository], loadNextURL: URL, loadNextPageTrigger: Observable<Void>) -> Observable<RepositoriesState> {
return loadSearchURL(loadNextURL).flatMap { searchResponse -> Observable<RepositoriesState> in
switch searchResponse {
/**
@ -133,18 +133,18 @@ extension GitHubSearchRepositoriesAPI {
It will retry until either battery drains, you become angry and close the app or evil machine comes back
from the future, steals your device and Googles Sarah Connor's address.
*/
case .ServiceOffline:
return Observable.just(RepositoriesState(repositories: loadedSoFar, serviceState: .Offline, limitExceeded: false))
case .serviceOffline:
return Observable.just(RepositoriesState(repositories: loadedSoFar, serviceState: .offline, limitExceeded: false))
case .LimitExceeded:
return Observable.just(RepositoriesState(repositories: loadedSoFar, serviceState: .Online, limitExceeded: true))
case .limitExceeded:
return Observable.just(RepositoriesState(repositories: loadedSoFar, serviceState: .online, limitExceeded: true))
case let .Repositories(newPageRepositories, maybeNextURL):
case let .repositories(newPageRepositories, maybeNextURL):
var loadedRepositories = loadedSoFar
loadedRepositories.appendContentsOf(newPageRepositories)
loadedRepositories.append(contentsOf: newPageRepositories)
let appenedRepositories = RepositoriesState(repositories: loadedRepositories, serviceState: .Online, limitExceeded: false)
let appenedRepositories = RepositoriesState(repositories: loadedRepositories, serviceState: .online, limitExceeded: false)
// if next page can't be loaded, just return what was loaded, and stop
guard let nextURL = maybeNextURL else {
@ -163,15 +163,15 @@ extension GitHubSearchRepositoriesAPI {
}
}
private func loadSearchURL(searchURL: NSURL) -> Observable<SearchRepositoryResponse> {
return NSURLSession.sharedSession()
.rx_response(NSURLRequest(URL: searchURL))
private func loadSearchURL(_ searchURL: URL) -> Observable<SearchRepositoryResponse> {
return URLSession.shared()
.rx_response(URLRequest(url: searchURL))
.retry(3)
.trackActivity(self.activityIndicator)
.observeOn(Dependencies.sharedDependencies.backgroundWorkScheduler)
.map { data, httpResponse -> SearchRepositoryResponse in
if httpResponse.statusCode == 403 {
return .LimitExceeded
return .limitExceeded
}
let jsonRoot = try GitHubSearchRepositoriesAPI.parseJSON(httpResponse, data: data)
@ -184,9 +184,9 @@ extension GitHubSearchRepositoriesAPI {
let nextURL = try GitHubSearchRepositoriesAPI.parseNextURL(httpResponse)
return .Repositories(repositories: repositories, nextURL: nextURL)
return .repositories(repositories: repositories, nextURL: nextURL)
}
.retryOnBecomesReachable(.ServiceOffline, reachabilityService: _reachabilityService)
.retryOnBecomesReachable(.serviceOffline, reachabilityService: _reachabilityService)
}
}
@ -195,22 +195,22 @@ extension GitHubSearchRepositoriesAPI {
extension GitHubSearchRepositoriesAPI {
private static let parseLinksPattern = "\\s*,?\\s*<([^\\>]*)>\\s*;\\s*rel=\"([^\"]*)\""
private static let linksRegex = try! NSRegularExpression(pattern: parseLinksPattern, options: [.AllowCommentsAndWhitespace])
private static let linksRegex = try! RegularExpression(pattern: parseLinksPattern, options: [.allowCommentsAndWhitespace])
private static func parseLinks(links: String) throws -> [String: String] {
private static func parseLinks(_ links: String) throws -> [String: String] {
let length = (links as NSString).length
let matches = GitHubSearchRepositoriesAPI.linksRegex.matchesInString(links, options: NSMatchingOptions(), range: NSRange(location: 0, length: length))
let matches = GitHubSearchRepositoriesAPI.linksRegex.matches(in: links, options: RegularExpression.MatchingOptions(), range: NSRange(location: 0, length: length))
var result: [String: String] = [:]
for m in matches {
let matches = (1 ..< m.numberOfRanges).map { rangeIndex -> String in
let range = m.rangeAtIndex(rangeIndex)
let startIndex = links.startIndex.advancedBy(range.location)
let endIndex = startIndex.advancedBy(range.length)
let range = m.range(at: rangeIndex)
let startIndex = links.characters.index(links.startIndex, offsetBy: range.location)
let endIndex = links.characters.index(links.startIndex, offsetBy: range.location + range.length)
let stringRange = startIndex ..< endIndex
return links.substringWithRange(stringRange)
return links.substring(with: stringRange)
}
if matches.count != 2 {
@ -223,7 +223,7 @@ extension GitHubSearchRepositoriesAPI {
return result
}
private static func parseNextURL(httpResponse: NSHTTPURLResponse) throws -> NSURL? {
private static func parseNextURL(_ httpResponse: HTTPURLResponse) throws -> URL? {
guard let serializedLinks = httpResponse.allHeaderFields["Link"] as? String else {
return nil
}
@ -234,22 +234,22 @@ extension GitHubSearchRepositoriesAPI {
return nil
}
guard let nextUrl = NSURL(string: nextPageURL) else {
guard let nextUrl = URL(string: nextPageURL) else {
throw exampleError("Error parsing next url `\(nextPageURL)`")
}
return nextUrl
}
private static func parseJSON(httpResponse: NSHTTPURLResponse, data: NSData) throws -> AnyObject {
private static func parseJSON(_ httpResponse: HTTPURLResponse, data: Data) throws -> AnyObject {
if !(200 ..< 300 ~= httpResponse.statusCode) {
throw exampleError("Call failed")
}
return try NSJSONSerialization.JSONObjectWithData(data ?? NSData(), options: [])
return try JSONSerialization.jsonObject(with: data ?? Data(), options: [])
}
private static func parseRepositories(json: [String: AnyObject]) throws -> [Repository] {
private static func parseRepositories(_ json: [String: AnyObject]) throws -> [Repository] {
guard let items = json["items"] as? [[String: AnyObject]] else {
throw exampleError("Can't find items")
}

View File

@ -12,10 +12,16 @@ import RxSwift
import RxCocoa
#endif
extension UIScrollView {
func isNearBottomEdge(edgeOffset: CGFloat = 20.0) -> Bool {
return self.contentOffset.y + self.frame.size.height + edgeOffset > self.contentSize.height
}
}
class GitHubSearchRepositoriesViewController: ViewController, UITableViewDelegate {
static let startLoadingOffset: CGFloat = 20.0
static func isNearTheBottomEdge(contentOffset: CGPoint, _ tableView: UITableView) -> Bool {
static func isNearTheBottomEdge(_ contentOffset: CGPoint, _ tableView: UITableView) -> Bool {
return contentOffset.y + tableView.frame.size.height + startLoadingOffset > tableView.contentSize.height
}
@ -27,11 +33,10 @@ class GitHubSearchRepositoriesViewController: ViewController, UITableViewDelegat
override func viewDidLoad() {
super.viewDidLoad()
let tableView = self.tableView
let searchBar = self.searchBar
dataSource.configureCell = { (_, tv, ip, repository: Repository) in
let cell = tv.dequeueReusableCellWithIdentifier("Cell")!
let cell = tv.dequeueReusableCell(withIdentifier: "Cell")!
cell.textLabel?.text = repository.name
cell.detailTextLabel?.text = repository.url
return cell
@ -43,14 +48,14 @@ class GitHubSearchRepositoriesViewController: ViewController, UITableViewDelegat
}
let loadNextPageTrigger = tableView.rx_contentOffset
.flatMap { offset in
GitHubSearchRepositoriesViewController.isNearTheBottomEdge(offset, tableView)
? Observable.just()
let loadNextPageTrigger = self.tableView.rx_contentOffset
.flatMap { _ in
self.tableView.isNearBottomEdge(edgeOffset: 20.0)
? Observable.just(())
: Observable.empty()
}
let searchResult = searchBar.rx_text.asDriver()
let searchResult = self.searchBar.rx_text.asDriver()
.throttle(0.3)
.distinctUntilChanged()
.flatMapLatest { query -> Driver<RepositoriesState> in
@ -82,8 +87,8 @@ class GitHubSearchRepositoriesViewController: ViewController, UITableViewDelegat
// dismiss keyboard on scroll
tableView.rx_contentOffset
.subscribe { _ in
if searchBar.isFirstResponder() {
_ = searchBar.resignFirstResponder()
if self.searchBar.isFirstResponder() {
_ = self.searchBar.resignFirstResponder()
}
}
.addDisposableTo(disposeBag)
@ -95,14 +100,14 @@ class GitHubSearchRepositoriesViewController: ViewController, UITableViewDelegat
// activity indicator in status bar
// {
GitHubSearchRepositoriesAPI.sharedAPI.activityIndicator
.drive(UIApplication.sharedApplication().rx_networkActivityIndicatorVisible)
.drive(UIApplication.shared().rx_networkActivityIndicatorVisible)
.addDisposableTo(disposeBag)
// }
}
// MARK: Table view delegate
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 30
}

View File

@ -23,7 +23,8 @@ extension UINavigationController {
return UIBindingObserver(UIElement: self) { navigationController, maybeServiceState in
// if nil is being bound, then don't change color, it's not perfect, but :)
if let serviceState = maybeServiceState {
let isOffline = serviceState ?? .Online == .Offline
let safeState = (serviceState ?? .online)
let isOffline = safeState == .offline
self.navigationBar.backgroundColor = isOffline
? Colors.OfflineColor

View File

@ -16,13 +16,13 @@ import RxCocoa
extension ValidationResult: CustomStringConvertible {
var description: String {
switch self {
case let .OK(message):
case let .ok(message):
return message
case .Empty:
case .empty:
return ""
case .Validating:
case .validating:
return "validating ..."
case let .Failed(message):
case let .failed(message):
return message
}
}
@ -30,19 +30,19 @@ extension ValidationResult: CustomStringConvertible {
struct ValidationColors {
static let okColor = UIColor(red: 138.0 / 255.0, green: 221.0 / 255.0, blue: 109.0 / 255.0, alpha: 1.0)
static let errorColor = UIColor.redColor()
static let errorColor = UIColor.red()
}
extension ValidationResult {
var textColor: UIColor {
switch self {
case .OK:
case .ok:
return ValidationColors.okColor
case .Empty:
return UIColor.blackColor()
case .Validating:
return UIColor.blackColor()
case .Failed:
case .empty:
return UIColor.black()
case .validating:
return UIColor.black()
case .failed:
return ValidationColors.errorColor
}
}
@ -55,4 +55,4 @@ extension UILabel {
label.text = result.description
}.asObserver()
}
}
}

View File

@ -25,75 +25,76 @@ class GitHubDefaultValidationService: GitHubValidationService {
let minPasswordCount = 5
func validateUsername(username: String) -> Observable<ValidationResult> {
func validateUsername(_ username: String) -> Observable<ValidationResult> {
if username.characters.count == 0 {
return Observable.just(.Empty)
return Observable.just(.empty)
}
// this obviously won't be
if username.rangeOfCharacterFromSet(NSCharacterSet.alphanumericCharacterSet().invertedSet) != nil {
return Observable.just(.Failed(message: "Username can only contain numbers or digits"))
if username.rangeOfCharacter(from: CharacterSet.alphanumerics.inverted) != nil {
return Observable.just(.failed(message: "Username can only contain numbers or digits"))
}
let loadingValue = ValidationResult.Validating
let loadingValue = ValidationResult.validating
return API
.usernameAvailable(username)
.map { available in
if available {
return .OK(message: "Username available")
return .ok(message: "Username available")
}
else {
return .Failed(message: "Username already taken")
return .failed(message: "Username already taken")
}
}
.startWith(loadingValue)
}
func validatePassword(password: String) -> ValidationResult {
func validatePassword(_ password: String) -> ValidationResult {
let numberOfCharacters = password.characters.count
if numberOfCharacters == 0 {
return .Empty
return .empty
}
if numberOfCharacters < minPasswordCount {
return .Failed(message: "Password must be at least \(minPasswordCount) characters")
return .failed(message: "Password must be at least \(minPasswordCount) characters")
}
return .OK(message: "Password acceptable")
return .ok(message: "Password acceptable")
}
func validateRepeatedPassword(password: String, repeatedPassword: String) -> ValidationResult {
func validateRepeatedPassword(_ password: String, repeatedPassword: String) -> ValidationResult {
if repeatedPassword.characters.count == 0 {
return .Empty
return .empty
}
if repeatedPassword == password {
return .OK(message: "Password repeated")
return .ok(message: "Password repeated")
}
else {
return .Failed(message: "Password different")
return .failed(message: "Password different")
}
}
}
class GitHubDefaultAPI : GitHubAPI {
let URLSession: NSURLSession
let URLSession: Foundation.URLSession
static let sharedAPI = GitHubDefaultAPI(
URLSession: NSURLSession.sharedSession()
URLSession: Foundation.URLSession.shared()
)
init(URLSession: NSURLSession) {
init(URLSession: Foundation.URLSession) {
self.URLSession = URLSession
}
func usernameAvailable(username: String) -> Observable<Bool> {
func usernameAvailable(_ username: String) -> Observable<Bool> {
// this is ofc just mock, but good enough
let URL = NSURL(string: "https://github.com/\(username.URLEscaped)")!
let request = NSURLRequest(URL: URL)
let url = URL(string: "https://github.com/\(username.URLEscaped)")!
let request = URLRequest(url: url)
return self.URLSession.rx_response(request)
.map { (maybeData, response) in
return response.statusCode == 404
@ -101,7 +102,7 @@ class GitHubDefaultAPI : GitHubAPI {
.catchErrorJustReturn(false)
}
func signup(username: String, password: String) -> Observable<Bool> {
func signup(_ username: String, password: String) -> Observable<Bool> {
// this is also just a mock
let signupResult = arc4random() % 5 == 0 ? false : true
return Observable.just(signupResult)
@ -109,4 +110,4 @@ class GitHubDefaultAPI : GitHubAPI {
.throttle(0.4, scheduler: MainScheduler.instance)
.take(1)
}
}
}

View File

@ -13,31 +13,31 @@ import RxCocoa
#endif
enum ValidationResult {
case OK(message: String)
case Empty
case Validating
case Failed(message: String)
case ok(message: String)
case empty
case validating
case failed(message: String)
}
enum SignupState {
case SignedUp(signedUp: Bool)
case signedUp(signedUp: Bool)
}
protocol GitHubAPI {
func usernameAvailable(username: String) -> Observable<Bool>
func signup(username: String, password: String) -> Observable<Bool>
func usernameAvailable(_ username: String) -> Observable<Bool>
func signup(_ username: String, password: String) -> Observable<Bool>
}
protocol GitHubValidationService {
func validateUsername(username: String) -> Observable<ValidationResult>
func validatePassword(password: String) -> ValidationResult
func validateRepeatedPassword(password: String, repeatedPassword: String) -> ValidationResult
func validateUsername(_ username: String) -> Observable<ValidationResult>
func validatePassword(_ password: String) -> ValidationResult
func validateRepeatedPassword(_ password: String, repeatedPassword: String) -> ValidationResult
}
extension ValidationResult {
var isValid: Bool {
switch self {
case .OK:
case .ok:
return true
default:
return false

View File

@ -46,7 +46,7 @@ class GitHubSignupViewController2 : ViewController {
// bind results to {
viewModel.signupEnabled
.driveNext { [weak self] valid in
self?.signupOutlet.enabled = valid
self?.signupOutlet.isEnabled = valid
self?.signupOutlet.alpha = valid ? 1.0 : 0.5
}
.addDisposableTo(disposeBag)
@ -91,13 +91,13 @@ class GitHubSignupViewController2 : ViewController {
// This will work well with UINavigationController, but has an assumption that view controller will
// never be added as a child view controller. If we didn't recreate the dispose bag here,
// then our resources would never be properly released.
override func willMoveToParentViewController(parent: UIViewController?) {
override func willMove(toParentViewController parent: UIViewController?) {
if let parent = parent {
assert(parent.isKindOfClass(UINavigationController), "Please read comments")
assert(parent as? UINavigationController != nil, "Please read comments")
}
else {
self.disposeBag = DisposeBag()
}
}
}
}

View File

@ -78,7 +78,7 @@ class GithubSignupViewModel2 {
validatedUsername = input.username
.flatMapLatest { username in
return validationService.validateUsername(username)
.asDriver(onErrorJustReturn: .Failed(message: "Error contacting server"))
.asDriver(onErrorJustReturn: .failed(message: "Error contacting server"))
}
validatedPassword = input.password
@ -123,4 +123,4 @@ class GithubSignupViewModel2 {
}
.distinctUntilChanged()
}
}
}

View File

@ -46,7 +46,7 @@ class GitHubSignupViewController1 : ViewController {
// bind results to {
viewModel.signupEnabled
.subscribeNext { [weak self] valid in
self?.signupOutlet.enabled = valid
self?.signupOutlet.isEnabled = valid
self?.signupOutlet.alpha = valid ? 1.0 : 0.5
}
.addDisposableTo(disposeBag)
@ -91,13 +91,15 @@ class GitHubSignupViewController1 : ViewController {
// This will work well with UINavigationController, but has an assumption that view controller will
// never be added as a child view controller. If we didn't recreate the dispose bag here,
// then our resources would never be properly released.
override func willMoveToParentViewController(parent: UIViewController?) {
override func willMove(toParentViewController parent: UIViewController?) {
if let parent = parent {
assert(parent.isKindOfClass(UINavigationController), "Please read comments")
if parent as? UINavigationController == nil {
assert(false, "something")
}
}
else {
self.disposeBag = DisposeBag()
}
}
}
}

View File

@ -69,7 +69,7 @@ class GithubSignupViewModel1 {
.flatMapLatest { username in
return validationService.validateUsername(username)
.observeOn(MainScheduler.instance)
.catchErrorJustReturn(.Failed(message: "Error contacting server"))
.catchErrorJustReturn(.failed(message: "Error contacting server"))
}
.shareReplay(1)
@ -118,4 +118,4 @@ class GithubSignupViewModel1 {
.distinctUntilChanged()
.shareReplay(1)
}
}
}

View File

@ -24,12 +24,12 @@ class ImagePickerController: ViewController {
super.viewDidLoad()
cameraButton.enabled = UIImagePickerController.isSourceTypeAvailable(.Camera)
cameraButton.isEnabled = UIImagePickerController.isSourceTypeAvailable(.camera)
cameraButton.rx_tap
.flatMapLatest { [weak self] _ in
return UIImagePickerController.rx_createWithParent(self) { picker in
picker.sourceType = .Camera
picker.sourceType = .camera
picker.allowsEditing = false
}
.flatMap { $0.rx_didFinishPickingMediaWithInfo }
@ -44,7 +44,7 @@ class ImagePickerController: ViewController {
galleryButton.rx_tap
.flatMapLatest { [weak self] _ in
return UIImagePickerController.rx_createWithParent(self) { picker in
picker.sourceType = .PhotoLibrary
picker.sourceType = .photoLibrary
picker.allowsEditing = false
}
.flatMap {
@ -61,7 +61,7 @@ class ImagePickerController: ViewController {
cropButton.rx_tap
.flatMapLatest { [weak self] _ in
return UIImagePickerController.rx_createWithParent(self) { picker in
picker.sourceType = .PhotoLibrary
picker.sourceType = .photoLibrary
picker.allowsEditing = true
}
.flatMap { $0.rx_didFinishPickingMediaWithInfo }

View File

@ -13,9 +13,9 @@ import UIKit
import RxCocoa
#endif
func dismissViewController(viewController: UIViewController, animated: Bool) {
func dismissViewController(_ viewController: UIViewController, animated: Bool) {
if viewController.isBeingDismissed() || viewController.isBeingPresented() {
dispatch_async(dispatch_get_main_queue()) {
DispatchQueue.main.async {
dismissViewController(viewController, animated: animated)
}
@ -23,12 +23,12 @@ func dismissViewController(viewController: UIViewController, animated: Bool) {
}
if viewController.presentingViewController != nil {
viewController.dismissViewControllerAnimated(animated, completion: nil)
viewController.dismiss(animated: animated, completion: nil)
}
}
extension UIImagePickerController {
static func rx_createWithParent(parent: UIViewController?, animated: Bool = true, configureImagePicker: (UIImagePickerController) throws -> () = { x in }) -> Observable<UIImagePickerController> {
static func rx_createWithParent(_ parent: UIViewController?, animated: Bool = true, configureImagePicker: (UIImagePickerController) throws -> () = { x in }) -> Observable<UIImagePickerController> {
return Observable.create { [weak parent] observer in
let imagePicker = UIImagePickerController()
let dismissDisposable = imagePicker
@ -44,21 +44,21 @@ extension UIImagePickerController {
try configureImagePicker(imagePicker)
}
catch let error {
observer.on(.Error(error))
observer.on(.error(error))
return NopDisposable.instance
}
guard let parent = parent else {
observer.on(.Completed)
observer.on(.completed)
return NopDisposable.instance
}
parent.presentViewController(imagePicker, animated: animated, completion: nil)
observer.on(.Next(imagePicker))
parent.present(imagePicker, animated: animated, completion: nil)
observer.on(.next(imagePicker))
return CompositeDisposable(dismissDisposable, AnonymousDisposable {
dismissViewController(imagePicker, animated: animated)
})
}
}
}
}

View File

@ -44,8 +44,8 @@ class SimpleTableViewExampleSectionedViewController
])
dataSource.configureCell = { (_, tv, indexPath, element) in
let cell = tv.dequeueReusableCellWithIdentifier("Cell")!
cell.textLabel?.text = "\(element) @ row \(indexPath.row)"
let cell = tv.dequeueReusableCell(withIdentifier: "Cell")!
cell.textLabel?.text = "\(element) @ row \((indexPath as NSIndexPath).row)"
return cell
}
@ -68,9 +68,9 @@ class SimpleTableViewExampleSectionedViewController
.addDisposableTo(disposeBag)
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let label = UILabel(frame: CGRect.zero)
label.text = dataSource.sectionAtIndex(section).model ?? ""
return label
}
}
}

View File

@ -26,7 +26,7 @@ class PartialUpdatesViewController : ViewController {
@IBOutlet weak var partialUpdatesTableViewOutlet: UITableView!
@IBOutlet weak var partialUpdatesCollectionViewOutlet: UICollectionView!
var timer: NSTimer? = nil
var timer: Timer? = nil
static let initialValue: [AnimatableSectionModel<String, Int>] = [
NumberSection(model: "section 1", items: [1, 2, 3]),
@ -123,22 +123,22 @@ class PartialUpdatesViewController : ViewController {
partialUpdatesCollectionViewOutlet.rx_itemSelected
.subscribeNext { [weak self] i in
print("Let me guess, it's .... It's \(self?.generator.sections[i.section].items[i.item]), isn't it? Yeah, I've got it.")
print("Let me guess, it's .... It's \(self?.generator.sections[i.section].items[i.item!]), isn't it? Yeah, I've got it.")
}
.addDisposableTo(disposeBag)
Observable.of(partialUpdatesTableViewOutlet.rx_itemSelected, reloadTableViewOutlet.rx_itemSelected)
.merge()
.subscribeNext { [weak self] i in
print("I have a feeling it's .... \(self?.generator.sections[i.section].items[i.item])?")
print("I have a feeling it's .... \(self?.generator.sections[i.section].items[i.item!])?")
}
.addDisposableTo(disposeBag)
}
func skinTableViewDataSource(dataSource: RxTableViewSectionedDataSource<NumberSection>) {
func skinTableViewDataSource(_ dataSource: RxTableViewSectionedDataSource<NumberSection>) {
dataSource.configureCell = { (_, tv, ip, i) in
let cell = tv.dequeueReusableCellWithIdentifier("Cell")
?? UITableViewCell(style:.Default, reuseIdentifier: "Cell")
let cell = tv.dequeueReusableCell(withIdentifier: "Cell")
?? UITableViewCell(style:.default, reuseIdentifier: "Cell")
cell.textLabel!.text = "\(i)"
@ -150,9 +150,9 @@ class PartialUpdatesViewController : ViewController {
}
}
func skinCollectionViewDataSource(dataSource: CollectionViewSectionedDataSource<NumberSection>) {
func skinCollectionViewDataSource(_ dataSource: CollectionViewSectionedDataSource<NumberSection>) {
dataSource.cellFactory = { (_, cv, ip, i) in
let cell = cv.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: ip) as! NumberCell
let cell = cv.dequeueReusableCell(withReuseIdentifier: "Cell", for: ip as IndexPath) as! NumberCell
cell.value!.text = "\(i)"
@ -160,15 +160,15 @@ class PartialUpdatesViewController : ViewController {
}
dataSource.supplementaryViewFactory = { (dataSource, cv, kind, ip) in
let section = cv.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "Section", forIndexPath: ip) as! NumberSectionView
let section = cv.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "Section", for: ip as IndexPath) as! NumberSectionView
section.value!.text = "\(dataSource.sectionAtIndex(ip.section).model)"
section.value!.text = "\(dataSource.sectionAtIndex((ip as NSIndexPath).section).model)"
return section
}
}
override func viewWillDisappear(animated: Bool) {
override func viewWillDisappear(_ animated: Bool) {
self.timer?.invalidate()
}

View File

@ -25,10 +25,10 @@ class DetailViewController: ViewController {
imageView.makeRoundedCorners(5)
let url = NSURL(string: user.imageURL)!
let request = NSURLRequest(URL: url)
let url = URL(string: user.imageURL)!
let request = URLRequest(url: url)
NSURLSession.sharedSession().rx_data(request)
URLSession.shared().rx_data(request)
.map { data in
UIImage(data: data)
}

View File

@ -18,8 +18,8 @@ class RandomUserAPI {
private init() {}
func getExampleUserResultSet() -> Observable<[User]> {
let url = NSURL(string: "http://api.randomuser.me/?results=20")!
return NSURLSession.sharedSession().rx_JSON(url)
let url = URL(string: "http://api.randomuser.me/?results=20")!
return URLSession.shared().rx_JSON(url)
.map { json in
guard let json = json as? [String: AnyObject] else {
throw exampleError("Casting to dictionary failed")
@ -29,7 +29,7 @@ class RandomUserAPI {
}
}
private func parseJSON(json: [String: AnyObject]) throws -> [User] {
private func parseJSON(_ json: [String: AnyObject]) throws -> [User] {
guard let results = json["results"] as? [[String: AnyObject]] else {
throw exampleError("Can't find results")
}
@ -47,8 +47,8 @@ class RandomUserAPI {
}
let returnUser = User(
firstName: firstName.capitalizedString,
lastName: lastName.capitalizedString,
firstName: firstName.capitalized,
lastName: lastName.capitalized,
imageURL: imageURL
)
return returnUser
@ -56,4 +56,4 @@ class RandomUserAPI {
return searchResults
}
}
}

View File

@ -25,21 +25,21 @@ struct TableViewEditingCommandsViewModel {
let favoriteUsers: [User]
let users: [User]
func executeCommand(command: TableViewEditingCommand) -> TableViewEditingCommandsViewModel {
func executeCommand(_ command: TableViewEditingCommand) -> TableViewEditingCommandsViewModel {
switch command {
case let .SetUsers(users):
case let .setUsers(users):
return TableViewEditingCommandsViewModel(favoriteUsers: favoriteUsers, users: users)
case let .SetFavoriteUsers(favoriteUsers):
case let .setFavoriteUsers(favoriteUsers):
return TableViewEditingCommandsViewModel(favoriteUsers: favoriteUsers, users: users)
case let .DeleteUser(indexPath):
case let .deleteUser(indexPath):
var all = [self.favoriteUsers, self.users]
all[indexPath.section].removeAtIndex(indexPath.row)
all[(indexPath as NSIndexPath).section].remove(at: (indexPath as NSIndexPath).row)
return TableViewEditingCommandsViewModel(favoriteUsers: all[0], users: all[1])
case let .MoveUser(from, to):
case let .moveUser(from, to):
var all = [self.favoriteUsers, self.users]
let user = all[from.section][from.row]
all[from.section].removeAtIndex(from.row)
all[to.section].insert(user, atIndex: to.row)
let user = all[(from as NSIndexPath).section][(from as NSIndexPath).row]
all[(from as NSIndexPath).section].remove(at: (from as NSIndexPath).row)
all[(to as NSIndexPath).section].insert(user, at: (to as NSIndexPath).row)
return TableViewEditingCommandsViewModel(favoriteUsers: all[0], users: all[1])
}
@ -47,10 +47,10 @@ struct TableViewEditingCommandsViewModel {
}
enum TableViewEditingCommand {
case SetUsers(users: [User])
case SetFavoriteUsers(favoriteUsers: [User])
case DeleteUser(indexPath: NSIndexPath)
case MoveUser(from: NSIndexPath, to: NSIndexPath)
case setUsers(users: [User])
case setFavoriteUsers(favoriteUsers: [User])
case deleteUser(indexPath: IndexPath)
case moveUser(from: IndexPath, to: IndexPath)
}
class TableViewWithEditingCommandsViewController: ViewController, UITableViewDelegate {
@ -77,14 +77,14 @@ class TableViewWithEditingCommandsViewController: ViewController, UITableViewDel
let loadFavoriteUsers = RandomUserAPI.sharedAPI
.getExampleUserResultSet()
.map(TableViewEditingCommand.SetUsers)
.map(TableViewEditingCommand.setUsers)
let initialLoadCommand = Observable.just(TableViewEditingCommand.SetFavoriteUsers(favoriteUsers: [superMan, watMan]))
let initialLoadCommand = Observable.just(TableViewEditingCommand.setFavoriteUsers(favoriteUsers: [superMan, watMan]))
.concat(loadFavoriteUsers)
.observeOn(MainScheduler.instance)
let deleteUserCommand = tableView.rx_itemDeleted.map(TableViewEditingCommand.DeleteUser)
let moveUserCommand = tableView.rx_itemMoved.map(TableViewEditingCommand.MoveUser)
let deleteUserCommand = tableView.rx_itemDeleted.map(TableViewEditingCommand.deleteUser)
let moveUserCommand = tableView.rx_itemMoved.map(TableViewEditingCommand.moveUser)
let initialState = TableViewEditingCommandsViewModel(favoriteUsers: [], users: [])
@ -119,35 +119,35 @@ class TableViewWithEditingCommandsViewController: ViewController, UITableViewDel
.addDisposableTo(disposeBag)
}
override func setEditing(editing: Bool, animated: Bool) {
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
tableView.editing = editing
tableView.isEditing = editing
}
// MARK: Table view delegate ;)
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let title = dataSource.sectionAtIndex(section)
let label = UILabel(frame: CGRect.zero)
// hacky I know :)
label.text = " \(title)"
label.textColor = UIColor.whiteColor()
label.backgroundColor = UIColor.darkGrayColor()
label.textColor = UIColor.white()
label.backgroundColor = UIColor.darkGray()
label.alpha = 0.9
return label
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40
}
// MARK: Navigation
private func showDetailsForUser(user: User) {
let storyboard = UIStoryboard(name: "Main", bundle: NSBundle(identifier: "RxExample-iOS"))
let viewController = storyboard.instantiateViewControllerWithIdentifier("DetailViewController") as! DetailViewController
private func showDetailsForUser(_ user: User) {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle(identifier: "RxExample-iOS"))
let viewController = storyboard.instantiateViewController(withIdentifier: "DetailViewController") as! DetailViewController
viewController.user = user
self.navigationController?.pushViewController(viewController, animated: true)
}
@ -158,7 +158,7 @@ class TableViewWithEditingCommandsViewController: ViewController, UITableViewDel
let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, User>>()
dataSource.configureCell = { (_, tv, ip, user: User) in
let cell = tv.dequeueReusableCellWithIdentifier("Cell")!
let cell = tv.dequeueReusableCell(withIdentifier: "Cell")!
cell.textLabel?.text = user.firstName + " " + user.lastName
return cell
}

View File

@ -10,9 +10,9 @@ import UIKit
extension UIImageView {
func makeRoundedCorners(radius: CGFloat) {
func makeRoundedCorners(_ radius: CGFloat) {
self.layer.cornerRadius = self.frame.size.width / 2
self.layer.borderColor = UIColor.darkGrayColor().CGColor
self.layer.borderColor = UIColor.darkGray().cgColor
self.layer.borderWidth = radius
self.layer.masksToBounds = true
}

View File

@ -16,7 +16,7 @@ class SearchResultViewModel {
let searchResult: WikipediaSearchResult
var title: Driver<String>
var imageURLs: Driver<[NSURL]>
var imageURLs: Driver<[URL]>
let API = DefaultWikipediaAPI.sharedAPI
let $: Dependencies = Dependencies.sharedDependencies
@ -35,10 +35,10 @@ class SearchResultViewModel {
// private methods
func configureTitle(imageURLs: Observable<[NSURL]>) -> Observable<String> {
func configureTitle(_ imageURLs: Observable<[URL]>) -> Observable<String> {
let searchResult = self.searchResult
let loadingValue: [NSURL]? = nil
let loadingValue: [URL]? = nil
return imageURLs
.map(Optional.init)
@ -54,7 +54,7 @@ class SearchResultViewModel {
.retryOnBecomesReachable("⚠️ Service offline ⚠️", reachabilityService: $.reachabilityService)
}
func configureImageURLs() -> Observable<[NSURL]> {
func configureImageURLs() -> Observable<[URL]> {
let searchResult = self.searchResult
return API.articleContent(searchResult)
.observeOn($.backgroundWorkScheduler)

View File

@ -23,7 +23,7 @@ public class CollectionViewImageCell: UICollectionViewCell {
let disposeBag = DisposeBag()
self.downloadableImage?
.asDriver(onErrorJustReturn: DownloadableImage.OfflinePlaceholder)
.asDriver(onErrorJustReturn: DownloadableImage.offlinePlaceholder)
.drive(imageOutlet.rxex_downloadableImageAnimated(kCATransitionFade))
.addDisposableTo(disposeBag)
@ -39,4 +39,4 @@ public class CollectionViewImageCell: UICollectionViewCell {
deinit {
}
}
}

View File

@ -26,7 +26,7 @@ public class WikipediaSearchCell: UITableViewCell {
public override func awakeFromNib() {
super.awakeFromNib()
self.imagesOutlet.registerNib(UINib(nibName: "WikipediaImageCell", bundle: nil), forCellWithReuseIdentifier: "ImageCell")
self.imagesOutlet.register(UINib(nibName: "WikipediaImageCell", bundle: nil), forCellWithReuseIdentifier: "ImageCell")
}
var viewModel: SearchResultViewModel! {
@ -42,8 +42,8 @@ public class WikipediaSearchCell: UITableViewCell {
let reachabilityService = Dependencies.sharedDependencies.reachabilityService
viewModel.imageURLs
.drive(self.imagesOutlet.rx_itemsWithCellIdentifier("ImageCell", cellType: CollectionViewImageCell.self)) { [weak self] (_, URL, cell) in
cell.downloadableImage = self?.imageService.imageFromURL(URL, reachabilityService: reachabilityService) ?? Observable.empty()
.drive(self.imagesOutlet.rx_itemsWithCellIdentifier("ImageCell", cellType: CollectionViewImageCell.self)) { [weak self] (_, url, cell) in
cell.downloadableImage = self?.imageService.imageFromURL(url, reachabilityService: reachabilityService) ?? Observable.empty()
}
.addDisposableTo(disposeBag)

View File

@ -41,11 +41,11 @@ class WikipediaSearchViewController: ViewController {
let searchBar = self.searchBar
let searchBarContainer = self.searchBarContainer
searchBarContainer.addSubview(searchBar)
searchBar.frame = searchBarContainer.bounds
searchBar.autoresizingMask = .FlexibleWidth
searchBarContainer?.addSubview(searchBar)
searchBar.frame = (searchBarContainer?.bounds)!
searchBar.autoresizingMask = .flexibleWidth
resultsViewController.edgesForExtendedLayout = UIRectEdge.None
resultsViewController.edgesForExtendedLayout = UIRectEdge()
configureTableDataSource()
configureKeyboardDismissesOnScroll()
@ -54,7 +54,7 @@ class WikipediaSearchViewController: ViewController {
}
func configureTableDataSource() {
resultsTableView.registerNib(UINib(nibName: "WikipediaSearchCell", bundle: nil), forCellReuseIdentifier: "WikipediaSearchCell")
resultsTableView.register(UINib(nibName: "WikipediaSearchCell", bundle: nil), forCellReuseIdentifier: "WikipediaSearchCell")
resultsTableView.rowHeight = 194
@ -118,7 +118,7 @@ class WikipediaSearchViewController: ViewController {
DefaultImageService.sharedImageService.loadingImage
) { $0 || $1 }
.distinctUntilChanged()
.drive(UIApplication.sharedApplication().rx_networkActivityIndicatorVisible)
.drive(UIApplication.shared().rx_networkActivityIndicatorVisible)
.addDisposableTo(disposeBag)
}
}

View File

@ -12,15 +12,15 @@ import RxSwift
import RxCocoa
#endif
func apiError(error: String) -> NSError {
func apiError(_ error: String) -> NSError {
return NSError(domain: "WikipediaAPI", code: -1, userInfo: [NSLocalizedDescriptionKey: error])
}
public let WikipediaParseError = apiError("Error during parsing")
protocol WikipediaAPI {
func getSearchResults(query: String) -> Observable<[WikipediaSearchResult]>
func articleContent(searchResult: WikipediaSearchResult) -> Observable<WikipediaPage>
func getSearchResults(_ query: String) -> Observable<[WikipediaSearchResult]>
func articleContent(_ searchResult: WikipediaSearchResult) -> Observable<WikipediaPage>
}
class DefaultWikipediaAPI: WikipediaAPI {
@ -33,17 +33,17 @@ class DefaultWikipediaAPI: WikipediaAPI {
private init() {}
private func rx_JSON(URL: NSURL) -> Observable<AnyObject> {
private func rx_JSON(_ url: URL) -> Observable<AnyObject> {
return $.URLSession
.rx_JSON(URL)
.rx_JSON(url)
.trackActivity(loadingWikipediaData)
}
// Example wikipedia response http://en.wikipedia.org/w/api.php?action=opensearch&search=Rx
func getSearchResults(query: String) -> Observable<[WikipediaSearchResult]> {
func getSearchResults(_ query: String) -> Observable<[WikipediaSearchResult]> {
let escapedQuery = query.URLEscaped
let urlContent = "http://en.wikipedia.org/w/api.php?action=opensearch&search=\(escapedQuery)"
let url = NSURL(string: urlContent)!
let url = URL(string: urlContent)!
return rx_JSON(url)
.observeOn($.backgroundWorkScheduler)
@ -58,9 +58,9 @@ class DefaultWikipediaAPI: WikipediaAPI {
}
// http://en.wikipedia.org/w/api.php?action=parse&page=rx&format=json
func articleContent(searchResult: WikipediaSearchResult) -> Observable<WikipediaPage> {
func articleContent(_ searchResult: WikipediaSearchResult) -> Observable<WikipediaPage> {
let escapedPage = searchResult.title.URLEscaped
guard let url = NSURL(string: "http://en.wikipedia.org/w/api.php?action=parse&page=\(escapedPage)&format=json") else {
guard let url = URL(string: "http://en.wikipedia.org/w/api.php?action=parse&page=\(escapedPage)&format=json") else {
return Observable.error(apiError("Can't create url"))
}
@ -74,4 +74,4 @@ class DefaultWikipediaAPI: WikipediaAPI {
}
.observeOn($.mainScheduler)
}
}
}

View File

@ -21,12 +21,12 @@ struct WikipediaPage {
}
// tedious parsing part
static func parseJSON(json: NSDictionary) throws -> WikipediaPage {
guard let title = json.valueForKey("parse")?.valueForKey("title") as? String,
let text = json.valueForKey("parse")?.valueForKey("text")?.valueForKey("*") as? String else {
static func parseJSON(_ json: NSDictionary) throws -> WikipediaPage {
guard let title = json.value(forKey: "parse")?.value(forKey: "title") as? String,
let text = json.value(forKey: "parse")?.value(forKey: "text")?.value(forKey: "*") as? String else {
throw apiError("Error parsing page content")
}
return WikipediaPage(title: title, text: text)
}
}
}

View File

@ -14,16 +14,16 @@ import RxSwift
struct WikipediaSearchResult: CustomDebugStringConvertible {
let title: String
let description: String
let URL: NSURL
let URL: Foundation.URL
init(title: String, description: String, URL: NSURL) {
init(title: String, description: String, URL: Foundation.URL) {
self.title = title
self.description = description
self.URL = URL
}
// tedious parsing part
static func parseJSON(json: [AnyObject]) throws -> [WikipediaSearchResult] {
static func parseJSON(_ json: [AnyObject]) throws -> [WikipediaSearchResult] {
let rootArrayTyped = json.map { $0 as? [AnyObject] }
.filter { $0 != nil }
.map { $0! }
@ -42,7 +42,7 @@ struct WikipediaSearchResult: CustomDebugStringConvertible {
guard let titleString = title as? String,
let descriptionString = description as? String,
let urlString = url as? String,
let URL = NSURL(string: urlString) else {
let URL = Foundation.URL(string: urlString) else {
throw WikipediaParseError
}
@ -57,4 +57,4 @@ extension WikipediaSearchResult {
var debugDescription: String {
return "[\(title)](\(URL))"
}
}
}

View File

@ -19,12 +19,12 @@ import UIKit
infix operator <-> {
}
func nonMarkedText(textInput: UITextInput) -> String? {
func nonMarkedText(_ textInput: UITextInput) -> String? {
let start = textInput.beginningOfDocument
let end = textInput.endOfDocument
guard let rangeAll = textInput.textRangeFromPosition(start, toPosition: end),
text = textInput.textInRange(rangeAll) else {
guard let rangeAll = textInput.textRange(from: start, to: end),
text = textInput.text(in: rangeAll) else {
return nil
}
@ -32,12 +32,12 @@ func nonMarkedText(textInput: UITextInput) -> String? {
return text
}
guard let startRange = textInput.textRangeFromPosition(start, toPosition: markedTextRange.start),
endRange = textInput.textRangeFromPosition(markedTextRange.end, toPosition: end) else {
guard let startRange = textInput.textRange(from: start, to: markedTextRange.start),
endRange = textInput.textRange(from: markedTextRange.end, to: end) else {
return text
}
return (textInput.textInRange(startRange) ?? "") + (textInput.textInRange(endRange) ?? "")
return (textInput.text(in: startRange) ?? "") + (textInput.text(in: endRange) ?? "")
}
func <-> (textInput: RxTextInput, variable: Variable<String>) -> Disposable {

View File

@ -39,7 +39,7 @@ When all activities complete `false` will be sent.
public class ActivityIndicator : DriverConvertibleType {
public typealias E = Bool
private let _lock = NSRecursiveLock()
private let _lock = RecursiveLock()
private let _variable = Variable(0)
private let _loading: Driver<Bool>
@ -47,22 +47,15 @@ public class ActivityIndicator : DriverConvertibleType {
_loading = _variable.asObservable()
.map { $0 > 0 }
.distinctUntilChanged()
<<<<<<< 6b259b6618bc93a56405726866e1a103f72a49ad
.asDriver(onErrorRecover: ActivityIndicator.ifItStillErrors)
=======
.asDriver { (error: ErrorProtocol) -> Driver<Bool> in
_ = fatalError("Loader can't fail")
return Driver.empty()
}
>>>>>>> Changes for Swift 3.0.
}
private static func ifItStillErrors(error: ErrorType) -> Driver<Bool> {
_ = fatalError("Loader can't fail")
}
private func trackActivityOfObservable<O: ObservableConvertibleType>(source: O) -> Observable<O.E> {
private func trackActivityOfObservable<O: ObservableConvertibleType>(_ source: O) -> Observable<O.E> {
return Observable.using({ () -> ActivityToken<O.E> in
self.increment()
return ActivityToken(source: source.asObservable(), disposeAction: self.decrement)
@ -89,7 +82,7 @@ public class ActivityIndicator : DriverConvertibleType {
}
public extension ObservableConvertibleType {
public func trackActivity(activityIndicator: ActivityIndicator) -> Observable<E> {
public func trackActivity(_ activityIndicator: ActivityIndicator) -> Observable<E> {
return activityIndicator.trackActivityOfObservable(self)
}
}
}

View File

@ -17,7 +17,7 @@ import RxSwift
#endif
enum DownloadableImage{
case Content(image:Image)
case OfflinePlaceholder
case content(image:Image)
case offlinePlaceholder
}

View File

@ -35,10 +35,10 @@ class GeolocationService {
.rx_didChangeAuthorizationStatus
.startWith(status)
}
.asDriver(onErrorJustReturn: CLAuthorizationStatus.NotDetermined)
.asDriver(onErrorJustReturn: CLAuthorizationStatus.notDetermined)
.map {
switch $0 {
case .AuthorizedAlways:
case .authorizedAlways:
return true
default:
return false
@ -57,4 +57,4 @@ class GeolocationService {
locationManager.startUpdatingLocation()
}
}
}

View File

@ -8,29 +8,29 @@
import Foundation
func parseImageURLsfromHTML(html: NSString) throws -> [NSURL] {
let regularExpression = try NSRegularExpression(pattern: "<img[^>]*src=\"([^\"]+)\"[^>]*>", options: [])
func parseImageURLsfromHTML(_ html: NSString) throws -> [URL] {
let regularExpression = try RegularExpression(pattern: "<img[^>]*src=\"([^\"]+)\"[^>]*>", options: [])
let matches = regularExpression.matchesInString(html as String, options: [], range: NSMakeRange(0, html.length))
let matches = regularExpression.matches(in: html as String, options: [], range: NSMakeRange(0, html.length))
return matches.map { match -> NSURL? in
return matches.map { match -> URL? in
if match.numberOfRanges != 2 {
return nil
}
let url = html.substringWithRange(match.rangeAtIndex(1))
let url = html.substring(with: match.range(at: 1))
var absoluteURLString = url
if url.hasPrefix("//") {
absoluteURLString = "http:" + url
}
return NSURL(string: absoluteURLString)
return URL(string: absoluteURLString)
}.filter { $0 != nil }.map { $0! }
}
func parseImageURLsfromHTMLSuitableForDisplay(html: NSString) throws -> [NSURL] {
func parseImageURLsfromHTMLSuitableForDisplay(_ html: NSString) throws -> [URL] {
return try parseImageURLsfromHTML(html).filter {
return $0.absoluteString.rangeOfString(".svg.") == nil
return $0.absoluteString?.range(of: ".svg.") == nil
}
}
}

View File

@ -19,7 +19,7 @@ import RxCocoa
#endif
protocol ImageService {
func imageFromURL(URL: NSURL, reachabilityService: ReachabilityService) -> Observable<DownloadableImage>
func imageFromURL(_ url: URL, reachabilityService: ReachabilityService) -> Observable<DownloadableImage>
}
class DefaultImageService: ImageService {
@ -29,10 +29,10 @@ class DefaultImageService: ImageService {
let $: Dependencies = Dependencies.sharedDependencies
// 1st level cache
private let _imageCache = NSCache()
private let _imageCache = Cache<AnyObject, AnyObject>()
// 2nd level cache
private let _imageDataCache = NSCache()
private let _imageDataCache = Cache<AnyObject, AnyObject>()
let loadingImage = ActivityIndicator()
@ -43,7 +43,7 @@ class DefaultImageService: ImageService {
_imageCache.countLimit = 20
}
private func decodeImage(imageData: NSData) -> Observable<Image> {
private func decodeImage(_ imageData: Data) -> Observable<Image> {
return Observable.just(imageData)
.observeOn($.backgroundWorkScheduler)
.map { data in
@ -55,9 +55,9 @@ class DefaultImageService: ImageService {
}
}
private func _imageFromURL(URL: NSURL) -> Observable<Image> {
private func _imageFromURL(_ url: URL) -> Observable<Image> {
return Observable.deferred {
let maybeImage = self._imageCache.objectForKey(URL) as? Image
let maybeImage = self._imageCache.object(forKey: url) as? Image
let decodedImage: Observable<Image>
@ -66,7 +66,7 @@ class DefaultImageService: ImageService {
decodedImage = Observable.just(image)
}
else {
let cachedData = self._imageDataCache.objectForKey(URL) as? NSData
let cachedData = self._imageDataCache.object(forKey: url) as? Data
// does image data cache contain anything
if let cachedData = cachedData {
@ -74,9 +74,9 @@ class DefaultImageService: ImageService {
}
else {
// fetch from network
decodedImage = self.$.URLSession.rx_data(NSURLRequest(URL: URL))
decodedImage = self.$.URLSession.rx_data(URLRequest(url: url))
.doOnNext { data in
self._imageDataCache.setObject(data, forKey: URL)
self._imageDataCache.setObject(data, forKey: url)
}
.flatMap(self.decodeImage)
.trackActivity(self.loadingImage)
@ -84,7 +84,7 @@ class DefaultImageService: ImageService {
}
return decodedImage.doOnNext { image in
self._imageCache.setObject(image, forKey: URL)
self._imageCache.setObject(image, forKey: url)
}
}
}
@ -97,10 +97,10 @@ class DefaultImageService: ImageService {
After image is sucessfully downloaded, sequence is completed.
*/
func imageFromURL(URL: NSURL, reachabilityService: ReachabilityService) -> Observable<DownloadableImage> {
return _imageFromURL(URL)
.map { DownloadableImage.Content(image: $0) }
.retryOnBecomesReachable(DownloadableImage.OfflinePlaceholder, reachabilityService: reachabilityService)
.startWith(.Content(image: Image()))
func imageFromURL(_ url: URL, reachabilityService: ReachabilityService) -> Observable<DownloadableImage> {
return _imageFromURL(url)
.map { DownloadableImage.content(image: $0) }
.retryOnBecomesReachable(DownloadableImage.offlinePlaceholder, reachabilityService: reachabilityService)
.startWith(.content(image: Image()))
}
}

View File

@ -52,7 +52,7 @@ class Randomizer {
self.unusedItems = []
}
func countTotalItemsInSections(sections: [NumberSection]) -> Int {
func countTotalItemsInSections(_ sections: [NumberSection]) -> Int {
return sections.reduce(0) { p, s in
return p + s.items.count
}
@ -73,7 +73,7 @@ class Randomizer {
for section in unusedSections {
let index = rng.get_random() % (sections.count + 1)
if insertSections {
sections.insert(NumberSection(model: section, items: []), atIndex: index)
sections.insert(NumberSection(model: section, items: []), at: index)
}
else {
nextUnusedSections.append(section)
@ -90,7 +90,7 @@ class Randomizer {
if rng.get_random() % 2 == 0 {
let itemIndex = rng.get_random() % (itemCount + 1)
if insertItems {
sections[sectionIndex].items.insert(unusedValue, atIndex: itemIndex)
sections[sectionIndex].items.insert(unusedValue, at: itemIndex)
}
else {
nextUnusedItems.append(unusedValue)
@ -99,14 +99,14 @@ class Randomizer {
// update
else {
if itemCount == 0 {
sections[sectionIndex].items.insert(unusedValue, atIndex: 0)
sections[sectionIndex].items.insert(unusedValue, at: 0)
continue
}
let itemIndex = rng.get_random() % itemCount
if reloadItems {
nextUnusedItems.append(sections[sectionIndex].items.removeAtIndex(itemIndex))
sections[sectionIndex].items.insert(unusedValue, atIndex: itemIndex)
nextUnusedItems.append(sections[sectionIndex].items.remove(at: itemIndex))
sections[sectionIndex].items.insert(unusedValue, at: itemIndex)
}
else {
@ -141,9 +141,9 @@ class Randomizer {
let nextRandom = rng.get_random()
if moveItems {
let item = sections[sourceSectionIndex].items.removeAtIndex(sourceItemIndex)
let item = sections[sourceSectionIndex].items.remove(at: sourceItemIndex)
let targetItemIndex = nextRandom % (self.sections[destinationSectionIndex].items.count + 1)
sections[destinationSectionIndex].items.insert(item, atIndex: targetItemIndex)
sections[destinationSectionIndex].items.insert(item, at: targetItemIndex)
}
}
@ -167,7 +167,7 @@ class Randomizer {
let sourceItemIndex = rng.get_random() % sectionItemCount
if deleteItems {
nextUnusedItems.append(sections[sourceSectionIndex].items.removeAtIndex(sourceItemIndex))
nextUnusedItems.append(sections[sourceSectionIndex].items.remove(at: sourceItemIndex))
}
}
@ -184,8 +184,8 @@ class Randomizer {
let targetIndex = rng.get_random() % sections.count
if explicitlyMoveSections {
let section = sections.removeAtIndex(sectionIndex)
sections.insert(section, atIndex: targetIndex)
let section = sections.remove(at: sectionIndex)
sections.insert(section, at: targetIndex)
}
}
@ -201,7 +201,7 @@ class Randomizer {
let sectionIndex = rng.get_random() % sections.count
if deleteSections {
let section = sections.removeAtIndex(sectionIndex)
let section = sections.remove(at: sectionIndex)
for item in section.items {
nextUnusedItems.append(item)
@ -217,4 +217,4 @@ class Randomizer {
unusedSections = nextUnusedSections
unusedItems = nextUnusedItems
}
}
}

View File

@ -29,18 +29,19 @@ import SystemConfiguration
import Foundation
enum ReachabilityError: ErrorProtocol {
case FailedToCreateWithAddress(sockaddr_in)
case FailedToCreateWithHostname(String)
case UnableToSetCallback
case UnableToSetDispatchQueue
case failedToCreateWithAddress(sockaddr_in)
case failedToCreateWithHostname(String)
case unableToSetCallback
case unableToSetDispatchQueue
}
public let ReachabilityChangedNotification = "ReachabilityChangedNotification"
func callback(reachability:SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutablePointer<Void>) {
let reachability = Unmanaged<Reachability>.fromOpaque(COpaquePointer(info)).takeUnretainedValue()
func callback(_ reachability:SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutablePointer<Void>?) {
guard let info = info else { return }
let reachability = Unmanaged<Reachability>.fromOpaque(OpaquePointer(info)).takeUnretainedValue()
dispatch_async(dispatch_get_main_queue()) {
DispatchQueue.main.async {
reachability.reachabilityChanged(flags)
}
}
@ -53,15 +54,15 @@ public class Reachability: NSObject {
public enum NetworkStatus: CustomStringConvertible {
case NotReachable, ReachableViaWiFi, ReachableViaWWAN
case notReachable, reachableViaWiFi, reachableViaWWAN
public var description: String {
switch self {
case .ReachableViaWWAN:
case .reachableViaWWAN:
return "Cellular"
case .ReachableViaWiFi:
case .reachableViaWiFi:
return "WiFi"
case .NotReachable:
case .notReachable:
return "No Connection"
}
}
@ -72,19 +73,19 @@ public class Reachability: NSObject {
public var whenReachable: NetworkReachable?
public var whenUnreachable: NetworkUnreachable?
public var reachableOnWWAN: Bool
public var notificationCenter = NSNotificationCenter.defaultCenter()
public var notificationCenter = NotificationCenter.default()
public var currentReachabilityStatus: NetworkStatus {
if isReachable() {
if isReachableViaWiFi() {
return .ReachableViaWiFi
return .reachableViaWiFi
}
if isRunningOnDevice {
return .ReachableViaWWAN
return .reachableViaWWAN
}
}
return .NotReachable
return .notReachable
}
public var currentReachabilityString: String {
@ -100,8 +101,8 @@ public class Reachability: NSObject {
public convenience init(hostname: String) throws {
let nodename = (hostname as NSString).UTF8String
guard let ref = SCNetworkReachabilityCreateWithName(nil, nodename) else { throw ReachabilityError.FailedToCreateWithHostname(hostname) }
let nodename = (hostname as NSString).utf8String
guard let ref = SCNetworkReachabilityCreateWithName(nil, nodename!) else { throw ReachabilityError.failedToCreateWithHostname(hostname) }
self.init(reachabilityRef: ref)
}
@ -114,7 +115,7 @@ public class Reachability: NSObject {
guard let ref = withUnsafePointer(&zeroAddress, {
SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0))
}) else { throw ReachabilityError.FailedToCreateWithAddress(zeroAddress) }
}) else { throw ReachabilityError.failedToCreateWithAddress(zeroAddress) }
return Reachability(reachabilityRef: ref)
}
@ -131,7 +132,7 @@ public class Reachability: NSObject {
guard let ref = withUnsafePointer(&localWifiAddress, {
SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0))
}) else { throw ReachabilityError.FailedToCreateWithAddress(localWifiAddress) }
}) else { throw ReachabilityError.failedToCreateWithAddress(localWifiAddress) }
return Reachability(reachabilityRef: ref)
}
@ -142,16 +143,21 @@ public class Reachability: NSObject {
if notifierRunning { return }
var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
context.info = UnsafeMutablePointer(Unmanaged.passUnretained(self).toOpaque())
let u = Unmanaged.passUnretained(self).toOpaque()
//context.info = u as? UnsafeMutablePointer<Void>
if !SCNetworkReachabilitySetCallback(reachabilityRef!, callback, &context) {
stopNotifier()
throw ReachabilityError.UnableToSetCallback
throw ReachabilityError.unableToSetCallback
}
if !SCNetworkReachabilitySetDispatchQueue(reachabilityRef!, reachabilitySerialQueue) {
stopNotifier()
throw ReachabilityError.UnableToSetDispatchQueue
throw ReachabilityError.unableToSetDispatchQueue
}
notifierRunning = true
@ -222,9 +228,9 @@ public class Reachability: NSObject {
private var notifierRunning = false
private var reachabilityRef: SCNetworkReachability?
private let reachabilitySerialQueue = dispatch_queue_create("uk.co.ashleymills.reachability", DISPATCH_QUEUE_SERIAL)
private let reachabilitySerialQueue = DispatchQueue(label: "uk.co.ashleymills.reachability", attributes: DispatchQueueAttributes.serial)
private func reachabilityChanged(flags: SCNetworkReachabilityFlags) {
private func reachabilityChanged(_ flags: SCNetworkReachabilityFlags) {
if isReachableWithFlags(flags) {
if let block = whenReachable {
block(self)
@ -235,10 +241,10 @@ public class Reachability: NSObject {
}
}
notificationCenter.postNotificationName(ReachabilityChangedNotification, object:self)
notificationCenter.post(name: Notification.Name(rawValue: ReachabilityChangedNotification), object:self)
}
private func isReachableWithFlags(flags: SCNetworkReachabilityFlags) -> Bool {
private func isReachableWithFlags(_ flags: SCNetworkReachabilityFlags) -> Bool {
let reachable = isReachable(flags)
@ -260,7 +266,7 @@ public class Reachability: NSObject {
return true
}
private func isReachableWithTest(test: (SCNetworkReachabilityFlags) -> (Bool)) -> Bool {
private func isReachableWithTest(_ test: (SCNetworkReachabilityFlags) -> (Bool)) -> Bool {
if let reachabilityRef = reachabilityRef {
@ -303,43 +309,43 @@ public class Reachability: NSObject {
})
}
private func isOnWWAN(flags: SCNetworkReachabilityFlags) -> Bool {
private func isOnWWAN(_ flags: SCNetworkReachabilityFlags) -> Bool {
#if os(iOS)
return flags.contains(.IsWWAN)
return flags.contains(.iswwan)
#else
return false
#endif
}
private func isReachable(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.Reachable)
private func isReachable(_ flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.reachable)
}
private func isConnectionRequired(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.ConnectionRequired)
private func isConnectionRequired(_ flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.connectionRequired)
}
private func isInterventionRequired(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.InterventionRequired)
private func isInterventionRequired(_ flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.interventionRequired)
}
private func isConnectionOnTraffic(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.ConnectionOnTraffic)
private func isConnectionOnTraffic(_ flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.connectionOnTraffic)
}
private func isConnectionOnDemand(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.ConnectionOnDemand)
private func isConnectionOnDemand(_ flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.connectionOnDemand)
}
func isConnectionOnTrafficOrDemand(flags: SCNetworkReachabilityFlags) -> Bool {
return !flags.intersect([.ConnectionOnTraffic, .ConnectionOnDemand]).isEmpty
func isConnectionOnTrafficOrDemand(_ flags: SCNetworkReachabilityFlags) -> Bool {
return !flags.intersection([.connectionOnTraffic, .connectionOnDemand]).isEmpty
}
private func isTransientConnection(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.TransientConnection)
private func isTransientConnection(_ flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.transientConnection)
}
private func isLocalAddress(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.IsLocalAddress)
private func isLocalAddress(_ flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.isLocalAddress)
}
private func isDirect(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.IsDirect)
private func isDirect(_ flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.isDirect)
}
private func isConnectionRequiredOrTransient(flags: SCNetworkReachabilityFlags) -> Bool {
let testcase:SCNetworkReachabilityFlags = [.ConnectionRequired, .TransientConnection]
return flags.intersect(testcase) == testcase
private func isConnectionRequiredOrTransient(_ flags: SCNetworkReachabilityFlags) -> Bool {
let testcase:SCNetworkReachabilityFlags = [.connectionRequired, .transientConnection]
return flags.intersection(testcase) == testcase
}
private var reachabilityFlags: SCNetworkReachabilityFlags {

View File

@ -13,7 +13,7 @@ import Foundation
public enum ReachabilityStatus {
case Reachable(viaWiFi: Bool)
case Unreachable
case unreachable
}
extension ReachabilityStatus {
@ -21,7 +21,7 @@ extension ReachabilityStatus {
switch self {
case .Reachable:
return true
case .Unreachable:
case .unreachable:
return false
}
}
@ -44,20 +44,20 @@ class DefaultReachabilityService
init() throws {
let reachabilityRef = try Reachability.reachabilityForInternetConnection()
let reachabilitySubject = BehaviorSubject<ReachabilityStatus>(value: .Unreachable)
let reachabilitySubject = BehaviorSubject<ReachabilityStatus>(value: .unreachable)
// so main thread isn't blocked when reachability via WiFi is checked
let backgroundQueue = dispatch_queue_create("reachability.wificheck", DISPATCH_QUEUE_SERIAL)
let backgroundQueue = DispatchQueue(label: "reachability.wificheck", attributes: DispatchQueueAttributes.serial)
reachabilityRef.whenReachable = { reachability in
dispatch_async(backgroundQueue) {
reachabilitySubject.on(.Next(.Reachable(viaWiFi: reachabilityRef.isReachableViaWiFi())))
backgroundQueue.async {
reachabilitySubject.on(.next(.Reachable(viaWiFi: reachabilityRef.isReachableViaWiFi())))
}
}
reachabilityRef.whenUnreachable = { reachability in
dispatch_async(backgroundQueue) {
reachabilitySubject.on(.Next(.Unreachable))
backgroundQueue.async {
reachabilitySubject.on(.next(.unreachable))
}
}
@ -72,7 +72,7 @@ class DefaultReachabilityService
}
extension ObservableConvertibleType {
func retryOnBecomesReachable(valueOnFailure:E, reachabilityService: ReachabilityService) -> Observable<E> {
func retryOnBecomesReachable(_ valueOnFailure:E, reachabilityService: ReachabilityService) -> Observable<E> {
return self.asObservable()
.catchError { (e) -> Observable<E> in
reachabilityService.reachability

View File

@ -14,10 +14,10 @@ import UIKit
extension Image {
func forceLazyImageDecompression() -> Image {
#if os(iOS)
UIGraphicsBeginImageContext(CGSizeMake(1, 1))
self.drawAtPoint(CGPointZero)
UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
self.draw(at: CGPoint.zero)
UIGraphicsEndImageContext()
#endif
return self
}
}
}

View File

@ -20,18 +20,18 @@ extension UIImageView{
return self.rxex_downloadableImageAnimated(nil)
}
func rxex_downloadableImageAnimated(transitionType:String?) -> AnyObserver<DownloadableImage> {
func rxex_downloadableImageAnimated(_ transitionType:String?) -> AnyObserver<DownloadableImage> {
return UIBindingObserver(UIElement: self) { imageView, image in
for subview in imageView.subviews {
subview.removeFromSuperview()
}
switch image {
case .Content(let image):
case .content(let image):
imageView.rx_image.onNext(image)
case .OfflinePlaceholder:
case .offlinePlaceholder:
let label = UILabel(frame: imageView.bounds)
label.textAlignment = .Center
label.font = UIFont.systemFontOfSize(35)
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 35)
label.text = "⚠️"
imageView.addSubview(label)
}

View File

@ -18,22 +18,22 @@ import Cocoa
#endif
enum RetryResult {
case Retry
case Cancel
case retry
case cancel
}
protocol Wireframe {
func openURL(URL: NSURL)
func promptFor<Action: CustomStringConvertible>(message: String, cancelAction: Action, actions: [Action]) -> Observable<Action>
func openURL(_ URL: URL)
func promptFor<Action: CustomStringConvertible>(_ message: String, cancelAction: Action, actions: [Action]) -> Observable<Action>
}
class DefaultWireframe: Wireframe {
static let sharedInstance = DefaultWireframe()
func openURL(URL: NSURL) {
func openURL(_ URL: Foundation.URL) {
#if os(iOS)
UIApplication.sharedApplication().openURL(URL)
UIApplication.shared().openURL(URL)
#elseif os(OSX)
NSWorkspace.sharedWorkspace().openURL(URL)
#endif
@ -42,37 +42,37 @@ class DefaultWireframe: Wireframe {
#if os(iOS)
private static func rootViewController() -> UIViewController {
// cheating, I know
return UIApplication.sharedApplication().keyWindow!.rootViewController!
return UIApplication.shared().keyWindow!.rootViewController!
}
#endif
static func presentAlert(message: String) {
static func presentAlert(_ message: String) {
#if os(iOS)
let alertView = UIAlertController(title: "RxExample", message: message, preferredStyle: .Alert)
alertView.addAction(UIAlertAction(title: "OK", style: .Cancel) { _ in
let alertView = UIAlertController(title: "RxExample", message: message, preferredStyle: .alert)
alertView.addAction(UIAlertAction(title: "OK", style: .cancel) { _ in
})
rootViewController().presentViewController(alertView, animated: true, completion: nil)
rootViewController().present(alertView, animated: true, completion: nil)
#endif
}
func promptFor<Action : CustomStringConvertible>(message: String, cancelAction: Action, actions: [Action]) -> Observable<Action> {
func promptFor<Action : CustomStringConvertible>(_ message: String, cancelAction: Action, actions: [Action]) -> Observable<Action> {
#if os(iOS)
return Observable.create { observer in
let alertView = UIAlertController(title: "RxExample", message: message, preferredStyle: .Alert)
alertView.addAction(UIAlertAction(title: cancelAction.description, style: .Cancel) { _ in
observer.on(.Next(cancelAction))
let alertView = UIAlertController(title: "RxExample", message: message, preferredStyle: .alert)
alertView.addAction(UIAlertAction(title: cancelAction.description, style: .cancel) { _ in
observer.on(.next(cancelAction))
})
for action in actions {
alertView.addAction(UIAlertAction(title: action.description, style: .Default) { _ in
observer.on(.Next(action))
alertView.addAction(UIAlertAction(title: action.description, style: .default) { _ in
observer.on(.next(action))
})
}
DefaultWireframe.rootViewController().presentViewController(alertView, animated: true, completion: nil)
DefaultWireframe.rootViewController().present(alertView, animated: true, completion: nil)
return AnonymousDisposable {
alertView.dismissViewControllerAnimated(false, completion: nil)
alertView.dismiss(animated:false, completion: nil)
}
}
#elseif os(OSX)
@ -85,10 +85,10 @@ class DefaultWireframe: Wireframe {
extension RetryResult : CustomStringConvertible {
var description: String {
switch self {
case .Retry:
case .retry:
return "Retry"
case .Cancel:
case .cancel:
return "Cancel"
}
}
}
}

View File

@ -10,6 +10,6 @@ import Foundation
extension String {
var URLEscaped: String {
return self.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet()) ?? ""
return self.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? ""
}
}

View File

@ -13,7 +13,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
return true
}

View File

@ -35,7 +35,7 @@ extension ObservableType {
- returns: Subscription object used to unsubscribe from the observable sequence.
*/
@warn_unused_result(message: "http://git.io/rxs.ud")
public func subscribe(_ onNext: ((E) -> Void)? = nil, onError: ((ErrorProtocol) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
public func subscribe(onNext: ((E) -> Void)? = nil, onError: ((ErrorProtocol) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
-> Disposable {
let disposable: Disposable

View File

@ -164,7 +164,7 @@ extension ObservableType {
- returns: The source sequence prepended with the specified values.
*/
@warn_unused_result(message:"http://git.io/rxs.uo")
public func startWith(elements: E ...)
public func startWith(_ elements: E ...)
-> Observable<E> {
return StartWith(source: self.asObservable(), elements: elements)
}
@ -199,7 +199,7 @@ extension ObservableType {
- returns: An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully.
*/
@warn_unused_result(message:"http://git.io/rxs.uo")
public func retry(maxAttemptCount: Int)
public func retry(_ maxAttemptCount: Int)
-> Observable<E> {
return CatchSequence(sources: repeatElement(self.asObservable(), count: maxAttemptCount))
}
@ -251,7 +251,7 @@ extension ObservableType {
- returns: An observable sequence containing the accumulated values.
*/
@warn_unused_result(message:"http://git.io/rxs.uo")
public func scan<A>(seed: A, accumulator: (A, E) throws -> A)
public func scan<A>(_ seed: A, accumulator: (A, E) throws -> A)
-> Observable<A> {
return Scan(source: self.asObservable(), seed: seed, accumulator: accumulator)
}