Oleg G. Oleg G. - 4 months ago 45
Swift Question

How can i make my program reactive in swift with RxSwift

hey !!!

I'm on OSX, the last one, using the last xcode version, and the last version of iOS :)

I've some problems to implement mvvm and reactive programming in my test project.
For reactive i'm using RxSwift libraries from here RxSwift

// so here my implementation of SettingsVC.swift

import UIKit
import SpeedLog
import RxCocoa
import RxSwift
import Eureka

class SettingsVC: FormViewController {
let viewModel = SettingsVM()

override func viewDidLoad() {
super.viewDidLoad()

self.setupFormer()
}

func setupFormer() {
// self.tableView?
// .rx_setDelegate(self)
// .addDisposableTo(disposeBag)
//
// // Setup Observer


self.setRegisterAndLoginRows()
self.setProfileRow()
}

func setRegisterAndLoginRows() {
self.form
+++= ButtonRow("connectDisconnect") {
$0.title = "Connexion"
} .onCellSelection { row in
SpeedLog.print((row.cell.textLabel?.text)! + " called")
UIViewController.pushModal(self, pushModalTo: PushModalTo.Connection)
}

<<< ButtonRow("registration") {
$0.title = "Inscription"
} .onCellSelection { row in
SpeedLog.print((row.cell.textLabel?.text)! + " called")
//UIViewController.pushModal(self, pushModalTo: PushModalTo.Connection)
}
}

func setProfileRow() {
form
+++= Section("Mon compte")

<<< LabelRow("profile") {
$0.title = "Mon profil"
$0.value = "Non enregistré"
let cell = $0
Session.appUser?.username
.asObservable()
.subscribeNext { username in
if let usernameTemp = username {
cell.value = usernameTemp
}
}
.addDisposableTo((Session.appUser?.disposeBag)!)
} .onCellSelection { row in
SpeedLog.print((row.cell.textLabel?.text)! + " called")
UIViewController.pushView(self, pushSettingsTo: PushSettingsTo.MyProfile)
}
}
}

// my SessionManager

import Foundation
import RxSwift

let Session = SessionManager.sharedInstance

class SessionManager {
static let sharedInstance = SessionManager()

var appUser: AppUser?

init() {
self.appUser = nil
}
}

// and my class User, because AppUser just inherit from User

import Foundation
import SpeedLog
import RxSwift

class User {
var username: Variable<String?> = Variable(nil)
var accessToken: Variable<String?> = Variable(nil)
var country: Variable<String?> = Variable(nil)
var created: Variable<NSDate?> = Variable(nil)
var disabled: Variable<Bool?> = Variable(nil)
var displayName: Variable<String?> = Variable(nil)
var email: Variable<String?> = Variable(nil)
var emailVerified: Variable<Bool?> = Variable(nil)
var locale: Variable<LocaleContainer?> = Variable(nil)
var modified: Variable<NSDate?> = Variable(nil)
var phoneNumber: Variable<String?> = Variable(nil)
var phoneVerified: Variable<Bool?> = Variable(nil)
var userID: Variable<String?> = Variable(nil)
var picture: Variable<UIImage?> = Variable(nil)
var pictureURL: Variable<String?> = Variable(nil)
let disposeBag = DisposeBag()

func set(kiiUser: KiiUser) {
self.username.value = kiiUser.username
self.accessToken.value = kiiUser.accessToken
self.country.value = kiiUser.country
self.created.value = kiiUser.created
self.disabled.value = kiiUser.disabled
self.displayName.value = kiiUser.displayName
self.email.value = kiiUser.email
self.emailVerified.value = kiiUser.emailVerified
self.locale.value = kiiUser.locale
self.modified.value = kiiUser.modified
self.phoneNumber.value = kiiUser.phoneNumber
self.phoneVerified.value = kiiUser.phoneVerified
self.userID.value = kiiUser.userID
self.picture.value = UIImage()
self.pictureURL.value = String()
}
}


I've already try to change just the Singleton to Variable() but it doesn't work ..
What i make bad ?
Sorry for my bad english :/

Thanks for your helps

Answer

Hey,

I found a solution to implement Eureka librarie, rxswift, and MVVM, i gonna share it:

SettingsVC

import UIKit
import SpeedLog
import RxCocoa
import RxSwift
import Eureka

class SettingsVC: FormViewController {

private var viewModel: SettingsVM?
private let disposeBag      = DisposeBag()

override func viewDidLoad() {
    super.viewDidLoad()

    self.initUI()
    self.bindViewModel()
}

func initUI() {
    // Settings form rows
    self.form
        +++=    ButtonRow("connectDisconnect")
        <<<     ButtonRow("registration")

    self.form
        +++=    Section("Mon compte")
        <<<     LabelRow("profile")

}

func bindViewModel() {
    self.viewModel = SettingsVM(form: &self.form, vc: self)
} 
}

SettingsVM

import Foundation
import SpeedLog
import RxCocoa
import RxSwift
import RxViewModel
import Eureka

class SettingsVM: RxViewModel {
// Private
private let disposeBag      = DisposeBag()
let vc:                     SettingsVC
let connectDisconnectRow:   ButtonRow?
let inscriptionRow:         ButtonRow?
let myProfileRow:           LabelRow?

init(inout form: Form, vc: SettingsVC) {
    self.vc = vc
    self.connectDisconnectRow   = form.rowByTag("connectDisconnect")
    self.inscriptionRow         = form.rowByTag("registration")
    self.myProfileRow           = form.rowByTag("profile")
    super.init()

    self.configureCell()
}

func configureCell() {
    // Connexion Disconnect button
    connectDisconnectRow?.baseCell.baseRow.title = "Connexion"
    connectDisconnectRow?.onCellSelection { cell, row in
        SpeedLog.print((row.cell.textLabel?.text)! + " called")
        UIViewController.pushModal(self.vc, pushModalTo: PushModalTo.Connection)
    }

    // Inscription button
    inscriptionRow?.baseCell.baseRow.title = "Inscription"
    inscriptionRow?.onCellSelection { cell, row in
        SpeedLog.print((row.cell.textLabel?.text)! + " called")
        UIViewController.pushModal(self.vc, pushModalTo: PushModalTo.Registration)
    }

    // My profile button
    myProfileRow?.baseCell.baseRow.title = "Mon profil"
    myProfileRow?.baseCell.baseRow.baseValue = "Non enregistré"

    _ = Session.appUser.displayName.asObservable().subscribeNext { displayName in
        if displayName != "" && displayName != nil {
            self.myProfileRow?.baseCell.baseRow.baseValue = displayName
        }
        self.myProfileRow?.baseCell.baseRow.reload()
    }
    myProfileRow?.onCellSelection { cell, row in
        SpeedLog.print((row.cell.textLabel?.text)! + " called")
        UIViewController.pushView(self.vc, pushSettingsTo: PushSettingsTo.MyProfile)
    }
}
}

I hope it's gonna help all people who's want to implement that things :) See ya

Comments