3

我正在尝试实现以下 RxSwift 示例:

在我的应用程序中使用 facebook 登录 -> 检索用户信息 -> 检索用户的个人资料照片。

我有这三个函数,它们必须按以下顺序执行:requestAccess() -> fetchUserInformation() -> fetchUserPhoto()

func requestAccess() -> Observable<(ACAccount)> {
    return create { observer -> Disposable in
        let accountStore = ACAccountStore()
        let accountType = accountStore.accountTypeWithAccountTypeIdentifier(ACAccountTypeIdentifierFacebook)
        let dictionary: [NSObject : AnyObject] = [ACFacebookAppIdKey:"***APPID***", ACFacebookPermissionsKey:["public_profile", "email", "user_friends"]]

        accountStore.requestAccessToAccountsWithType(accountType, options: dictionary) { granted, error in
            if granted == false || error != nil {
                sendError(observer, error ?? UnknownError)
            } else {
                let accounts = accountStore.accountsWithAccountType(accountType)
                let account = accounts.last as! ACAccount
                sendNext(observer, account)
                sendCompleted(observer)
            }
        }

        return AnonymousDisposable({})
    }
}

func fetchUserInformation(account: ACAccount) -> Observable<User> {
    return create { observer -> Disposable in
        let url = NSURL(string: "https://graph.facebook.com/me")
        let request = SLRequest(forServiceType: SLServiceTypeFacebook, requestMethod: .GET, URL: url, parameters: nil)
        request.account = account

        request.performRequestWithHandler { (data, response, error) -> Void in
            if data == nil || response == nil {
                sendError(observer, error ?? UnknownError)
            } else {
                let result: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil)
                let user = User()
                user.updateInformationWithJSON(result! as! JSONObject)

                sendNext(observer, user)
                sendCompleted(observer)
            }
        }

        return AnonymousDisposable({})
    }
}

func fetchUserPhoto(user: User) -> Observable<AnyObject> {
    return create { observer -> Disposable in
        let url = NSURL(string: "https://graph.facebook.com/***myid***/picture")
        let params = ["redirect":"false", "height":"200", "width":"200"]

        let request = SLRequest(forServiceType: SLServiceTypeFacebook, requestMethod: .GET, URL: url, parameters: params)
        request.account = SocialController.account

        request.performRequestWithHandler { (data, response, error) -> Void in
            if data == nil || response == nil {
                sendError(observer, error ?? UnknownError)
            } else {
                let result: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil)                    
                sendNext(observer, result!)
                sendCompleted(observer)
            }
        }

        return AnonymousDisposable({})
    }
}

我已经尝试过实现这个流程,但感觉不对。解决此问题的最佳方法是什么?

        requestAccess()
        >- subscribeNext { account in
            fetchUserInformation(account)
                >- map { user in return UserViewModel(model: user) }
                >- subscribeNext { viewModel in self.viewModel = viewModel }
        }
4

2 回答 2

4

你试过使用flatMap吗?它相当于thenJavaScript bluebird 或 Q 的世界。map和之间的区别在于flatMapflatMap 必须返回一个Observable<T>然后将在下面的块/闭包中解包。

requestAccess()
   >- flatMap{ account in
      return fetchUserInformation(account)
   }
   >- map { user in 
      return UserViewModel(model:user)
   }
   >- subscribeNext { viewModel in
      self.viewModel = viewModel
   }

花絮 #1:unowned self在引用时考虑使用self以避免保留循环。

花絮 #2:这两者几乎是一回事。

flatMap { return just("hello") }
  >- subscribeNext{ greeting in println(greeting) }

map { return "hello" } 
  >- subscribeNext{ greeting in println(greeting) }
于 2015-08-02T07:14:23.653 回答
0
private
func requestFacebookAccess(_ viewController: UIViewController) -> Observable<LoginManagerLoginResult?> {

    return Observable.create { observer -> Disposable in

        let loginManager = LoginManager()
        loginManager.logIn(permissions: ["public_profile", "email"], from: viewController, handler: { result, error in
            observer.onNext(result)
            observer.onCompleted()

        })

        return Disposables.create()
    }
}
于 2019-05-31T15:32:02.957 回答