Papr icon indicating copy to clipboard operation
Papr copied to clipboard

Unable to get the latest 'isLikedByUser'.

Open RoyDeng opened this issue 3 years ago • 0 comments

I imitated your code. After I press the select button, isLikedByUser is always the initial value.

PostViewCellModel.swift

import Foundation
import RxSwift
import Action
import RealmSwift

protocol PostViewCellModelInput {
    var selectPostAction: Action<Post, Post> { get }
    var unselectPostAction: Action<Post, Post> { get }
}
protocol PostViewCellModelOutput {
    var postData: Observable<Post> { get }
    var isSelected: Observable<Bool> { get }
}
protocol PostViewCellModelType {
    var inputs: PostViewCellModelInput { get }
    var outputs: PostViewCellModelOutput { get }
}

final class PostViewCellModel: PostViewCellModelType, PostViewCellModelInput, PostViewCellModelOutput {
    var inputs: PostViewCellModelInput { return self }
    var outputs: PostViewCellModelOutput { return self }
    
    lazy var selectPostAction: Action<Post, Post> = {
        Action<Post, Post> { [unowned self] post in
            let configuration = Realm.Configuration(deleteRealmIfMigrationNeeded: true)
            let realm = try! Realm(configuration: configuration)
            
            let sharePost = SharePost()
            sharePost.ref = post.ref!
            sharePost.title = post.title
            sharePost.summary = post.summary
            sharePost.url = post.url

            try! realm.write {
                realm.add(sharePost, update: .modified)
            }

            return .just(post)
        }
    }()
    
    lazy var unselectPostAction: Action<Post, Post> = {
        Action<Post, Post> { [unowned self] post in
            let configuration = Realm.Configuration(deleteRealmIfMigrationNeeded: true)
            let realm = try! Realm(configuration: configuration)
            let sharePost = realm.objects(SharePost.self).filter("ref = %@", post.ref!)
            
            if (sharePost.count > 0) {
                try! realm.write {
                    realm.delete(sharePost.first!)
                }
            }
            
            return .just(post)
        }
    }()
 
    var postData: Observable<Post>
    var isSelected: Observable<Bool>
    
    private let service: PostServiceType
    private let cache: Cache
    private let sceneCoordinator: SceneCoordinatorType
    
    init(post: Post, service: PostServiceType = PostService(), cache: Cache = Cache.shared, sceneCoordinator: SceneCoordinatorType = SceneCoordinator.shared) {
        self.service = service
        self.cache = cache
        self.sceneCoordinator = sceneCoordinator
        
        postData = Observable.just(post)
        let cachedPostData = cache.getObject(ofType: Post.self, withId: post.ref ?? "").unwrap()
        
        isSelected = self.postData.merge(with: cachedPostData)
            .map { post in
                let configuration = Realm.Configuration(deleteRealmIfMigrationNeeded: true)
                let realm = try! Realm(configuration: configuration)

                if realm.object(ofType: SharePost.self, forPrimaryKey: post.ref!) != nil {
                    return true
                } else {
                    return false
                }
            }.unwrap()
    }
}

PostViewCell.swift

import Foundation
import UIKit
import RxSwift
import RxCocoa
import RealmSwift

class PostViewCell: UITableViewCell, BindableType, NibIdentifiable & ClassIdentifiable {
    var viewModel: PostViewCellModelType!
    
    @IBOutlet var selectButton: UIButton!
    
    private var disposeBag = DisposeBag()

    func bindViewModel() {
        let inputs = viewModel.inputs
        let outputs = viewModel.outputs
        
        Observable.combineLatest(outputs.isSelected, outputs.postData)
            .bind { [weak self] in
                self?.selectButton.rx.bind(to: $0 ? inputs.unselectPostAction: inputs.selectPostAction, input: $1)
            }
            .disposed(by: disposeBag)

        outputs.isSelected
            .map { $0 ? UIColor.init(red: 210 / 255, green: 233 / 255, blue: 1, alpha: 1) : .clear }
            .bind(to: self.rx.backgroundColor)
            .disposed(by: disposeBag)
    }
}

RoyDeng avatar Nov 10 '20 09:11 RoyDeng