swift常用三方
in Document on Swift
- swift 常用三方
- 使用pod导入所有用到的三方
- ReachabilitySwift
- Alamofire
- Moya
- DGElasticPullToRefresh
- SnapKit
- Masonry
- MBProgressHUD
- WebViewJavascriptBridge
- JPush
- WechatLogin
swift 常用三方
- ReachabilitySwift(网络判断)
- Alamofire(swift版afnetworking)
- Moya(用于网络申请)
- DGElasticPullToRefresh(下拉刷新)
- SnapKit(A Swift Autolayout DSL for iOS & OS X)
- Masonry(轻量级Autolayout封装)
- MBProgressHUD(经典OC页面加载动画)
- WebViewJavascriptBridge(用于js交互)
- JPush(极光推送)
- 微信登录
使用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) // 设置代理
}