// // UserInfoRepository.swift // PaiAi // // Created by FFIB on 16/4/1. // Copyright © 2016年 FFIB. All rights reserved. // import Foundation import RxSwift fileprivate let WXAppid = "wx4e22a0c8ae6d766d" fileprivate let WXSecret = "636ac848016c593575d11143c55c8333" fileprivate struct GuestLoginResource: Resource, Parsable { typealias Model = UserInfo var path: Interfaces { return .guestLogin } var parameter: Parameter = [:] func parse(_ json: JSON) -> UserInfo? { guard let result = json["data"] as? [String: AnyObject] else { return nil } return UserInfo(json: result) } } fileprivate struct WXLoginResource: Resource, Parsable { typealias Model = UserInfo var path: Interfaces { return .authorize } var parameter: Parameter = [:] func parse(_ json: JSON) -> UserInfo? { guard let result = json["data"] as? [String: AnyObject] else { return nil } return UserInfo(json: result) } } fileprivate struct WXTokenResource: Resource, Parsable { typealias Model = [String: AnyObject] var path: Interfaces { return .wxAccessToken } var parameter: Parameter = ["appid": WXAppid, "secret": WXSecret, "grant_type": "authorization_code"] var host: String { return "https://api.weixin.qq.com" } func parse(_ json: JSON) -> [String : AnyObject]? { return json } } fileprivate struct WXUserInfoResource: Resource, Parsable { typealias Model = [String: AnyObject] var path: Interfaces { return .wxUserInfo } var parameter: Parameter = [:] var host: String { return "https://api.weixin.qq.com" } func parse(_ json: JSON) -> [String : AnyObject]? { return json } } final class UserInfoRepository { fileprivate var guestLoginResource: GuestLoginResource fileprivate var wxLoginResource: WXLoginResource fileprivate var wxTokenResource: WXTokenResource fileprivate var wxUserinfoResource: WXUserInfoResource fileprivate var userInfoStore: UserInfoStore fileprivate var userInfo: BehaviorSubject var userInfoObserver: Observable var isLogin: Observable init(userInfoStore: UserInfoStore = UserInfoStore()) { self.userInfoStore = userInfoStore self.guestLoginResource = GuestLoginResource() self.wxLoginResource = WXLoginResource() self.wxTokenResource = WXTokenResource() self.wxUserinfoResource = WXUserInfoResource() self.userInfo = BehaviorSubject(value: UserInfo(json: [:])) self.userInfoObserver = userInfo.asObservable() .flatMapLatest({ (info) in Observable.just(info).distinctUntilChanged() }).share() self.isLogin = userInfo.asObservable() .map { $0.userId != "" } .share() addWXLoginDidFinish() } func guestLogin() { // #if (arch(i386) || arch(x86_64)) // // userInfo.onNext() // SharedUserInfo.userId = "zmouhsF" // SharedUserInfo.name = "游客63" // SharedUserInfo.synchronize() // #else guestLoginResource.parameter["uuid"] = userInfoStore.getUUID() NetworkApi.share.post(resource: guestLoginResource) { (result) in guard case let .success(data) = result else { return } self.userInfo.onNext(data) self.userInfoStore.save(data) } // #endif } func wxLogin() { loginWithWeChat() } fileprivate func loginWithWeChat() { let request = SendAuthReq() request.scope = "snsapi_userinfo,snsapi_base" request.state = "skilogin" WXApi.send(request) } fileprivate func getWXToken(code: String) { wxTokenResource.parameter["code"] = code as AnyObject NetworkApi.share.get(resource: wxTokenResource) { (result) in guard case let .success(data) = result, let token = data["access_token"] as? String, let openId = data["openid"] as? String else { return } self.getWXUserInfo(token: token, openId: openId) } } fileprivate func getWXUserInfo(token: String, openId: String) { wxUserinfoResource.parameter["access_token"] = token as AnyObject wxUserinfoResource.parameter["openid"] = openId as AnyObject NetworkApi.share.get(resource: wxUserinfoResource) { (result) in guard case let .success(data) = result else { return } if let errcode = data["errcode"] as? Int, errcode == 40003 { return } self._wxLogin(data: data) } } fileprivate func _wxLogin(data: [String: AnyObject]) { wxLoginResource.parameter = data NetworkApi.share.post(resource: wxLoginResource) { (result) in guard case let .success(data) = result else { return } self.userInfo.onNext(data) self.userInfoStore.save(data) } } fileprivate func addWXLoginDidFinish() { NotificationCenter.default.addObserver(forName: Notification.WXLoginNotification, object: nil, queue: nil) { (notification) in guard let userInfo = notification.userInfo, let code = userInfo["code"] as? String else { return } self.getWXToken(code: code) } } func loadFromLocal() { userInfo.onNext(userInfoStore.load()) } deinit { NotificationCenter.default.removeObserver(self) } } extension Notification { static let WXLoginNotification = Notification.Name("WXLoginDidFinishNotification") }