swift常用三方

swift 常用三方


使用pod导入所有用到的三方


用到的三方

target '' do
end
platform :ios, '8.0'
use_frameworks!
pod 'ReachabilitySwift'
pod 'SnapKit', '~> 4.0.0'
pod 'Alamofire'
pod 'RxSwift'
pod 'RxCocoa'
pod 'Moya'
pod 'ObjectMapper'
pod 'Result', '~> 3.0.0'
pod 'Moya/RxSwift'
pod 'Masonry'
pod 'DGElasticPullToRefresh'
pod 'WebViewJavascriptBridge', '~> 6.0'
pod 'JPush'
pod 'WechatOpenSDK'

ReachabilitySwift


git地址: https://github.com/ashleymills/Reachability.swift

简介:进行网络判断的三方,可通过通知直接进行网络的通知,从而判断页面的状态等

举例:

/* 实时监控网络 */
var reachability:Reachability = Reachability()! // 必须为全局参数,不然通知方法不调用

// 添加网络通知
NotificationCenter.default.addObserver(self, selector: #selector(reachabilityChanged(_:)), name: .reachabilityChanged, object: reachability)

// 开启通知
do{
    try reachability.startNotifier()
}catch{
    print("could not start reachability notifier")
}

// 网络改变时调用方法
@objc func reachabilityChanged(_ note: Notification) {
    let reachability = note.object as! Reachability

    switch reachability.connection {
        case .wifi:
            print("************ WiFi")
        case .cellular:
            print("************ Cellular")
        case .none:
            print("************ reachable")
    }
}

// 移除消息通知
deinit {
    // 关闭网络状态消息监听
    reachability.stopNotifier()
    // 移除网络状态消息通知
    NotificationCenter.default.removeObserver(self, name: .reachabilityChanged, object: reachability)
}

/* 自主检测网络 */
let reachability = Reachability()!

reachability.whenReachable = { reachability in
    if reachability.connection == .wifi {
        print("Reachable via WiFi")
    } else {
        print("Reachable via Cellular")
    }
}

reachability.whenUnreachable = { _ in
    print("Not reachable")
}

do {
    try reachability.startNotifier()
} catch {
    print("Unable to start notifier")
}

Alamofire


git地址: https://github.com/Alamofire/Alamofire

简介:swift版的afnetworking,用于网络接口的申请

举例:

/*  接口post请求
*  url: 传过来的url
*  param: 传过来的接口个性参数
*  complete:接口返回的参数
*/
class func post(url: String?, param: Parameters, complete: @escaping (HTTPURLResponse?, Result<Any>) -> Void ) -> Void {

    // 如果发过来的链接长度为空,则直接返回,不做任何反应
    guard let urlString = url, strlen(url) > 0 else {
        return
    }

    Alamofire.request(urlString, method: .post, parameters: param).responseJSON { (response) in
        complete(response.response, response.result)
    }
}

/*  接口get请求
*  url: 传过来的url
*  complete:接口返回的参数
*/
class func get(url: String?, complete: @escaping (HTTPURLResponse?, Result<Any>) -> Void ) -> Void {

    // 如果发过来的链接长度为空,则直接返回,不做任何反应
    guard let urlString = url, strlen(url) > 0 else {
        return
    }

    Alamofire.request(urlString, method: .get).responseJSON { (response) in
        complete(response.response, response.result)
    }
}

调用接口实例

let urlString = "http://www.gonghuizhudi.com/jiekou.php"
HYHttpTool.post(url: urlString, param: [:]) { (response, result) in
    let dic: NSDictionary = result.value as! NSDictionary
    print(dic.value(forKey: "headers") as Any)
}

用到的扩展

// 扩充String
extension String {

    /*
    * 将json字符串在转化为json字典
    */
    static func getDictionaryFromJSONString(jsonString:String) ->NSDictionary{

        let jsonData:Data = jsonString.data(using: .utf8)!

        let dict = try? JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers)
        if dict != nil {
            return dict as! NSDictionary
        }
        return NSDictionary()
    }

    /*
    * 将json字典转化为json字符串
    */
    static func getJSONStringFromDictionary(dictionary:NSDictionary) -> String {
        if (!JSONSerialization.isValidJSONObject(dictionary)) {
            print("无法解析出JSONString")
            return ""
        }
        let data : NSData! = try? JSONSerialization.data(withJSONObject: dictionary, options: []) as NSData!
        let JSONString = NSString(data:data as Data,encoding: String.Encoding.utf8.rawValue)
        return JSONString! as String
    }
}

Moya


git地址: https://github.com/Moya/Moya

简介:一个网络接口申请方法,基于Alamofire的高度封装

举例:

DGElasticPullToRefresh


git地址: https://github.com/gontovnik/DGElasticPullToRefresh.git

简介:一个下拉刷新的三方,用于webview的页面的下拉刷新

举例:

class BaseWebView: UIWebView {

    override func draw(_ rect: CGRect) {
        super.draw(rect)

        self.scrollView.backgroundColor = UIColor(red: 45.0/255.0, green: 45.0/255.0, blue: 45.0/255.0, alpha: 1)
        self.scrollView.alwaysBounceVertical = false

        // 添加webview下拉刷新方法
        let loadingView = DGElasticPullToRefreshLoadingViewCircle()
        loadingView.tintColor = UIColor(red: 78/255.0, green: 221/255.0, blue: 200/255.0, alpha: 1.0)
        self.scrollView.dg_addPullToRefreshWithActionHandler({ [weak self] () -> Void in
            print("触发下拉刷新")
            self?.reload()
        }, loadingView: loadingView)
        self.scrollView.dg_setPullToRefreshFillColor(UIColor(red: 57/255.0, green: 67/255.0, blue: 89/255.0, alpha: 1.0))
        self.scrollView.dg_setPullToRefreshBackgroundColor(UIColor.blue)
    }

    // 页面消失时移除掉
    deinit {
        self.scrollView.dg_removePullToRefresh()
    }
}

// 在调用完毕后调取 webView.scrollView.dg_stopLoading() 停止动画即可

SnapKit


git地址: https://github.com/SnapKit/SnapKit

简介:可进行页面布局的适配,轻量级Autolayout封装,用于swift

举例:

import SnapKit

class MyViewController: UIViewController {

    lazy var box = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.addSubview(box)
        box.snp.makeConstraints { (make) -> Void in
            make.width.height.equalTo(50)
            make.center.equalTo(self.view)
        }
    }
}

Masonry


git地址: https://github.com/SnapKit/Masonry

简介:可进行页面布局的适配,轻量级Autolayout封装,用于OC

举例:

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);

[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(superview.mas_top).with.offset(padding.top); //with is an optional semantic filler
    make.left.equalTo(superview.mas_left).with.offset(padding.left);
    make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom);
    make.right.equalTo(superview.mas_right).with.offset(-padding.right);
}];

MBProgressHUD


git地址: https://github.com/matej/MBProgressHUD

简介:OC中经典的用于页面加载的动画,进行swift简单的封装

举例:


extension MBProgressHUD {

    /* 显示动画 */
    class func showHUD() {
        let hud: MBProgressHUD = MBProgressHUD.showAdded(to: UIApplication.shared.windows.last!, animated: true)
        hud.removeFromSuperViewOnHide = true
        hud.bezelView.backgroundColor = UIColor.black
        hud.activityIndicatorColor = UIColor.white
    }

    /* 在view上显示菊花动画 */
    func showHUD(view: UIView) {
        let hud: MBProgressHUD = MBProgressHUD.showAdded(to: view, animated: true)
        hud.removeFromSuperViewOnHide = true
        hud.bezelView.backgroundColor = UIColor.black
        hud.activityIndicatorColor = UIColor.white
    }


    /* 关闭view上动画 */
    class func hideHUDForView(view: UIView) {
        hide(for: view, animated: true)
    }

    /* 关闭window上动画 */
    class func hideHUD() {
        hide(for: UIApplication.shared.windows.last!, animated: true)
    }


    /* 显示成功 */
    class func showSucess(success: String, view: UIView) {
        show(text: success, icon: "success.png", view: view)
    }

    /* window上显示成功 */
    class func showSuccess(success: String) {
        show(text: success, icon: "success.png", view: UIApplication.shared.windows.last!)
    }

    /* 显示失败 */
    class func showError(error: String, view: UIView) {
        show(text: error, icon: "error.png", view: view)
    }

    /* 显示失败 */
    class func showError(error: String) {
        show(text: error, icon: "error.png", view: UIApplication.shared.windows.last!)
    }

    /* 显示要展示的消息 */
    class func showMessage(message: String) -> MBProgressHUD {
        return MBProgressHUD.showMessage(message: message, view: UIApplication.shared.windows.last!)
    }

    /* 显示要展示的消息 */
    class func showMessage(message: String, view: UIView) ->MBProgressHUD {

        let hud: MBProgressHUD = MBProgressHUD.showAdded(to: view, animated: true)
        hud.label.text = message
        hud.contentColor = UIColor.white
        hud.removeFromSuperViewOnHide = true
        hud.bezelView.backgroundColor = UIColor.black
        hud.activityIndicatorColor = UIColor.white
        return hud
    }

    /* 私有共用方法 */
    private class func show(text: String, icon: String, view: UIView) {

        let hud: MBProgressHUD = MBProgressHUD.showAdded(to: view, animated: true)
        hud.label.text = text
        hud.contentColor = UIColor.white
        hud.customView = UIImageView.init(image: UIImage(named: "MBP_\(icon)"))
        hud.bezelView.backgroundColor = UIColor.black
        hud.mode = MBProgressHUDMode.customView
        hud.removeFromSuperViewOnHide = true
        hud.hide(animated: true, afterDelay: 1.5)
    }

}

WebViewJavascriptBridge


git地址: https://github.com/marcuswestin/WebViewJavascriptBridge.git

简介:用于js与原生之间的交互

举例:

import WebViewJavascriptBridge

var bridge: WebViewJavascriptBridge?

WebViewJavascriptBridge.enableLogging()
bridge = WebViewJavascriptBridge.init(webView)!
bridge?.setWebViewDelegate(self)
bridge?.registerHandler("openThirdPartPage") { (data, responseCallback) in
    print("data =========== \(String(describing: data))")

    let dict: NSDictionary  = data as! NSDictionary
    self.openThirdPartPageWithData(dict: dict)
    responseCallback!(data)
}

bridge?.disableJavscriptAlertBoxSafetyTimeout()

JPush


简介:极光推送,用于远程消息推送

举例:

func JPushSetupWithApplication(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) {

    print("设置极光推送")
    //极光推送部署
    let entity = JPUSHRegisterEntity.init()
    JPUSHService.setBadge(0)
    entity.types = Int(JPAuthorizationOptions.alert.rawValue | JPAuthorizationOptions.sound.rawValue | JPAuthorizationOptions.badge.rawValue)
    JPUSHService.register(forRemoteNotificationConfig: entity, delegate: self)
    JPUSHService.setup(withOption: launchOptions, appKey: "42727d5f4e9b75940b5c81e6", channel: "App Store", apsForProduction:true)
    #if DEBUG
        // 自己测试打tag值,方便自己测试
        let ingredients: Set = ["myself"]
        JPUSHService.setTags(ingredients, completion: { (iResCode, iTags, seq) in
            print("tags ================ \(String(describing: iTags))")
        }, seq: 1)
    #else
        print(" ************** release环境")
    #endif

    JPUSHService.registrationIDCompletionHandler { (resCode, registrationID) in
    }
    JPUSHService.setLogOFF()
    registerPushNotifications()
}
@available(iOS 10.0, *) // 在点击推送过来的小框的时候点击会调取此方法
func jpushNotificationCenter(_ center: UNUserNotificationCenter!, didReceive response: UNNotificationResponse!, withCompletionHandler completionHandler: (() -> Void)!) {
    let userInfo = response.notification.request.content.userInfo
    if (response.notification.request.trigger?.isKind(of: UNPushNotificationTrigger.self))!{
        JPUSHService.handleRemoteNotification(userInfo)
        JPushManageUserInfo(userinfo: userInfo as NSDictionary)
    }
    completionHandler()
}


@available(iOS 10.0, *) // 在推送提示小框将要显示的时候会调这个方法
func jpushNotificationCenter(_ center: UNUserNotificationCenter!, willPresent notification: UNNotification!, withCompletionHandler completionHandler: ((Int) -> Void)!) {

    let userInfo = notification.request.content.userInfo

    if (notification.request.trigger?.isKind(of: UNPushNotificationTrigger.self))!{
    //            PrintLog("iOS10 前台收到远程通知:\(userInfo)")
        JPUSHService.handleRemoteNotification(userInfo)
    }else {
    // 判断为本地通知
    //            PrintLog("iOS10 前台收到本地通知:\(userInfo)")
    }
    completionHandler(Int(UNAuthorizationOptions.alert.rawValue | UNAuthorizationOptions.sound.rawValue | UNAuthorizationOptions.badge.rawValue))// 需要执行这个方法,选择是否提醒用户,有badge、sound、alert三种类型可以选择设置

}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
    JPUSHService.handleRemoteNotification(userInfo)
    JPushManageUserInfo(userinfo: userInfo as NSDictionary)
}

func registerPushNotifications() {
    DispatchQueue.main.async {
        let set = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
        UIApplication.shared.registerUserNotificationSettings(set)
    }

}

func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) {
    if notificationSettings.types != UIUserNotificationType() {
        application.registerForRemoteNotifications()
    }
}

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

    let device = NSData(data: deviceToken)
    let deviceId = device.description.replacingOccurrences(of:"<", with:"").replacingOccurrences(of:">", with:"").replacingOccurrences(of:" ", with:"")
    print("deviceToken ======= \(deviceId)")
    JPUSHService.registerDeviceToken(deviceToken)
    if (UserDefaults.standard.object(forKey: "PushDeviceInfo") == nil){
        UserDefaults.standard.setValue(deviceId, forKey: "PushDeviceInfo")
        UserDefaults.standard.synchronize()
    }
}

// 处理得到的推送信息
func JPushManageUserInfo(userinfo: NSDictionary) {
    JPInfoManageTool.shared.navController = navController
    JPInfoManageTool.JPushManageUserInfo(userInfo: userinfo)
}

WechatLogin


相关资料:
iOS接入指南
移动应用微信登录开发指南
个人日记保存点
https://github.com/anchoriteFili/WechatLogTest

简介:用于微信的登录的简单封装

创建HYHttpTool.swift

import UIKit

let WXAPPID = "wx0cd8451d269de523"
let WXSECRET = ""
let USER_DEFAULT = UserDefaults.standard // 获取userDefault
let WXRefreshToken = "WXLogTool_refreshToken"
let WXAccessToken = "WXLogTool_accessToken"
let WXOpenID = "WXLogTool_openid"
let WXUnionid = "WXLogTool_unionid"


class WXLogTool: NSObject, WXApiDelegate {
    
    /**
     * 创建单例,使用实例:let ClassName = HYHttpTool.shared
     */
    static let shared = WXLogTool.init()
    private override init() {}
    
    /// 注册appid
    func registerApp() {
        WXApi.registerApp(WXAPPID)
    }
    
    /// 收到一个来自微信的请求,第三方应用程序处理完后调用sendResp向微信发送结果
    ///
    /// - Parameter req: 具体请求内容,是自动释放的
    func onReq(_ req: BaseReq!) {
        
        if req.isKind(of: GetMessageFromWXReq.self) {
            // 微信请求APP提供内容,需要app提供内容后使用senRsp返回
            print("微信请求App提供内容,App要调用sendResp:GetMessageFromWXResp返回给微信")
        } else if req.isKind(of: ShowMessageFromWXReq.self) {
            
            let tmp: ShowMessageFromWXReq = req as! ShowMessageFromWXReq
            
            // 显示微信传过来的内容
            let msg: WXMediaMessage = tmp.message
            let obj: WXAppExtendObject = msg.mediaObject as! WXAppExtendObject
            
            print("标题:\(msg.title) 内容:\(msg.description) 附带信息:\(obj.extInfo) 缩略图:\(msg.thumbData.count)")
        } else if req.isKind(of: LaunchFromWXReq.self) {
            // 从微信启动app
            print("从微信启动app")
        }
    }
    
    /// 发送一个sendReq后,收到微信的回应
    ///
    /// - Parameter resp: 具体的回应内容,是自动释放的
    func onResp(_ resp: BaseResp!) {
        
        switch resp.errCode {
        case 0: // 用户同意
            // 调用相关方法
            let aresp: SendAuthResp = resp as! SendAuthResp
            print("code *********** \(aresp.code)")
            weChatCallBackWithCode(code: aresp.code)
            break
        case -4: // 用户拒绝授权
            break
        case -2: // 用户取消
            break
        default:
            break
        }
        
    }
    
    
    /** https://api.weixin.qq.com/sns/oauth2/access_token
     *  链接返回数据
     access_token : 接口调用凭证
     *  expires_in : access_token接口调用凭证超时时间,单位(秒)
     *  refresh_token : 用户刷新access_token
     *  openid : 授权用户唯一标识
     *  scope : 用户授权的作用域,使用逗号(,)分隔
     *  unionid : 当且仅当该移动应用已获得该用户的userinfo授权时,才会出现该字段
     */
    func weChatCallBackWithCode(code: String) {
        
        let urlString = "https://api.weixin.qq.com/sns/oauth2/access_token"
        print("urlString ************** \(urlString)")
        
        HYHttpTool.post(url: urlString, param: ["appid":WXAPPID,"secret":WXSECRET,"code":code,"grant_type":"authorization_code",]) { [weak self] (response, result) in
            print("code 获取 ************ \(String(describing: result.value))")
            
            let dic: NSDictionary = result.value as! NSDictionary
            if let errmsg = dic.value(forKey: "errmsg") {
                print("errmsg ************** \(errmsg)")
                return
            }
            
            USER_DEFAULT.set(dic.value(forKey: "refresh_token") as! String, forKey: WXRefreshToken)
            USER_DEFAULT.set(dic.value(forKey: "access_token") as! String, forKey: WXAccessToken)
            USER_DEFAULT.set(dic.value(forKey: "openid") as! String, forKey: WXOpenID)
            

            self?.getUserInfoWithAccessToken(accessToken:  dic.value(forKey: "access_token") as! String, openId: dic.value(forKey: "openid") as! String)
        }
        
    }
    
    /// 获取微信用户信息方法
    ///
    /// - Parameters:
    ///   - accessToken: 接口调用凭证
    ///   - openId: 授权用户唯一标识
    func getUserInfoWithAccessToken(accessToken: String, openId: String) {
        
        let urlString = "https://api.weixin.qq.com/sns/userinfo"
        
        HYHttpTool.post(url: urlString, param: ["access_token":accessToken,"openid":openId]) { (response, result) in
            print("获取微信用户信息方法 ************ \(String(describing: result.value))")
            let dic: NSDictionary = result.value as! NSDictionary
            
            if let errmsg = dic.value(forKey: "errmsg") {
                print("errmsg ************** \(errmsg)")
                return
            }
        }
    }
    
    
    /// 使用refresh_token刷新access_token
    ///
    /// - Parameter refreshToken: 用户刷新access_token
    func refreshAccessToken(refreshToken: String) {
        
        let urlString = "https://api.weixin.qq.com/sns/oauth2/refresh_token"
        
        HYHttpTool.post(url: urlString, param: ["appid":WXAPPID,"grant_type":"refresh_token","refresh_token":refreshToken]) { [weak self] (response, result) in
            print("使用refresh_token刷新access_token ************ \(String(describing: result.value))")
            let dic: NSDictionary = result.value as! NSDictionary
            
            if let errmsg = dic.value(forKey: "errmsg") {
                // 如果刷新失败,表示过期,可进行再次申请授权
                self?.sendAuthRequest()
                print("errmsg ************** \(errmsg)")
            } else {
                // 如果刷新成功,则根据refreshToken获取获取相关信息
                
                USER_DEFAULT.set(dic.value(forKey: "refresh_token") as! String, forKey: WXRefreshToken)
                USER_DEFAULT.set(dic.value(forKey: "access_token") as! String, forKey: WXAccessToken)
                USER_DEFAULT.set(dic.value(forKey: "openid") as! String, forKey: WXOpenID)
                
                self?.getUserInfoWithAccessToken(accessToken:  dic.value(forKey: "access_token")  as! String, openId: dic.value(forKey: "openid") as! String)
            }
        }
    }
    
    
    /// 判断本地的 access_token 是否可用
    ///
    /// - Parameters:
    ///   - access_token: 调用接口凭证
    ///   - openId: 普通用户标识,对该公众帐号唯一
    ///   - complete: 返回处理结果
    func accessTokenUsable(access_token: String, openId: String, complete: @escaping(Bool) -> Void) {
        
        let urlString = "https://api.weixin.qq.com/sns/auth"
        
        HYHttpTool.post(url: urlString, param: ["access_token":access_token,"openid":openId]) { (response, result) in
            print("判断本地的 access_token 是否可用 ************ \(String(describing: result.value))")
            let dic: NSDictionary = result.value as! NSDictionary
            
            if let errmsg = dic.value(forKey: "errmsg") {
                print("errmsg ************** \(errmsg)")
                
                if errmsg as! String == "ok" {
                    complete(true)
                } else {
                    complete(false)
                }
            }
        }
    }
    
    /// 登录点击方法
    func weChatLogin() {
        
        if WXApi.isWXAppInstalled() {
            print("****** 安装了微信APP *********")
        } else {
            print("****** 未安装微信 *********")
            return
        }
        
        if (USER_DEFAULT.object(forKey: WXAccessToken) != nil) {

            accessTokenUsable(access_token: USER_DEFAULT.object(forKey: WXAccessToken) as! String, openId: USER_DEFAULT.object(forKey: WXOpenID) as! String, complete: { [weak self] (isOK) in

                if isOK {
                    print("isOK === yes")
                    // 如果还可以用,则直接去申请用户信息
                    self?.getUserInfoWithAccessToken(accessToken:  USER_DEFAULT.object(forKey: WXAccessToken) as! String, openId: USER_DEFAULT.object(forKey: WXOpenID) as! String)
                } else {
                    print("isOK === no")
                    // 如果不可以用,则调取refreshAccessToken
                    // 如果存在则使用refresh_token刷新access_token
                    self?.refreshAccessToken(refreshToken: USER_DEFAULT.object(forKey: WXRefreshToken) as! String)
                }

            })
        } else {
            // 如果不存在则直接授权
            sendAuthRequest()
        }
    }
    
    /// 授权方法,直接跳转到微信进行授权
    func sendAuthRequest() {
        let req: SendAuthReq = SendAuthReq()
        req.scope = "snsapi_userinfo"
        req.state = "WechatLogTest"
        WXApi.send(req)
    }

}
Appdelegate中设置相关环境
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        // 注册信息
        WXLogTool.shared.registerApp()
        return true
    }

    func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
        return WXApi.handleOpen(url, delegate: WXLogTool.shared) // 设置代理
    }


© 2017. All rights reserved.

Powered by Hydejack v7.5.0