|
//
// 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<UserInfo>
var userInfoObserver: Observable<UserInfo>
var isLogin: Observable<Bool>
init(userInfoStore: UserInfoStore = UserInfoStore()) {
self.userInfoStore = userInfoStore
self.guestLoginResource = GuestLoginResource()
self.wxLoginResource = WXLoginResource()
self.wxTokenResource = WXTokenResource()
self.wxUserinfoResource = WXUserInfoResource()
self.userInfo = BehaviorSubject<UserInfo>(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")
}
|