iOS Swift开发 常用库使用说明

这里用于记录下, 在项目中又实际用到的开源库, 方便自己查找, 也是方便同样使用Swift编程的大家, 毕竟现在Swift比较好用的库还不是很多. 这次记录下来的会有很多Objective-C桥接过来的库, 也是重点说下这些桥接库的使用.

桥接教程: 在同个工程中使用 Swift 和 Objective-C(Swift and Objective-C in the Same Project)

网络

获取网络数据

库名: Alamofire - Swift

说明: 很方便从服务器获取数据的网络库

简单使用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
let method: Method = .GET 	// 请求方式
let request: String = "http://httpbin.org/get" // 请求地址
let parameters: [String: String] = ["foo": "bar"] // 请求参数

// MARK: Pod
import Alamofire

Alamofire.request(method, request, parameters: parameters)
.response { request, response, data, error in
println(request)
println(response)
println(data) // 返回值
println(error)
}

// MARK: 手动添加库
// 拖动库源文件到项目目录
request(method, request, parameters: parameters)
.response { request, response, data, error in
println(request)
println(response)
println(data) // 返回值
println(error)
}

// MARK: 上传图片并传递参数

let url = "http://192.168.199.143/index.php"
let parameters = ["action": "upload_avatar", "uid": "61"]
let imageDatas = [
"avatar": UIImagePNGRepresentation(UIImage(named: "100")!)!,
"avatar1": UIImagePNGRepresentation(UIImage(named: "1")!)!
]

复杂实用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
let urlRequest = urlRequestWithComponents(url, parameters: parameters, imageDatas: imageDatas)

upload(urlRequest.0, data: urlRequest.1)
.responseJSON { (request, response, json, error) in
println("REQUEST \(request)")
println("RESPONSE \(response)")
println("JSON \(json!)")
println("ERROR \(error)")
}

// this function creates the required URLRequestConvertible and NSData we need to use Alamofire.upload
func urlRequestWithComponents(urlString:String, parameters:Dictionary<String, String>, imageDatas: Dictionary<String, NSData>) -> (URLRequestConvertible, NSData) {

// create url request to send
var mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: urlString)!)
mutableURLRequest.HTTPMethod = Method.POST.rawValue
let boundaryConstant = "myRandomBoundary12345";
let contentType = "multipart/form-data;boundary="+boundaryConstant
mutableURLRequest.setValue(contentType, forHTTPHeaderField: "Content-Type")

// create upload data to send
let uploadData = NSMutableData()

// add image
for (key, value) in imageDatas {
uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
uploadData.appendData("Content-Disposition: form-data; name=\"\(key)\"; filename=\"\(key).png\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
uploadData.appendData("Content-Type: image/png\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
uploadData.appendData(value)
}

// add parameters
for (key, value) in parameters {
uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
uploadData.appendData("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n\(value)".dataUsingEncoding(NSUTF8StringEncoding)!)
}

uploadData.appendData("\r\n--\(boundaryConstant)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)

// return URLRequestConvertible and NSData
return (ParameterEncoding.URL.encode(mutableURLRequest, parameters: nil).0, uploadData)
}

Ps: 参考资料http://stackoverflow.com

检查网络连接

库名: IJReachability - Swift

说明: 用于判断当前网络环境

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 拖动库源文件到项目目录

if IJReachability.isConnectedToNetwork() {
availabilityLabel.text = "网络连接: 有效"
availabilityLabel.textColor = UIColor.greenColor()
} else {
availabilityLabel.text = "网络连接: 无效"
availabilityLabel.textColor = UIColor.redColor()
}

let statusType = IJReachability.isConnectedToNetworkOfType()
switch statusType {
case .WWAN:
println("连接类型: 移动网络")
case .WiFi:
println("连接类型: WIFI网络")
case .NotConnected:
println("连接类型: 无网络")
}

存储

UserDefaults存储

库名: radex/SwiftyUserDefaults -> MakeHui/SwiftyUserDefaults - Swift

说明: 用于持久化存储数据 (Ps: 本人的对其进行了改良, 可简单的通过串行化存储对象, 当需要大量的进行CRUD操作时不建议使用)

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// 拖动库源文件到项目目录

// MARK: radex/SwiftyUserDefaults
// 存储数据
Defaults["keyName"] = data

// 读取数据
Defaults["keyName"].string // Optional
Defaults["keyName"].stringValue // String
// 其他的类型以此类推

// 判断这个对象是否存在
Defaults.hasKey("keyName") // Bool

// 删除对象
Defaults.remove("keyName")

// MARK: MakeHui/SwiftyUserDefaults

// Ps: 后添加的功能, 理论上所有的值都可以通过这种方式存取 (这里只用来存储对象)

// Model
class Model: NSObject, NSCoding {

var id: Int
var name: String

init(id: Int, name: String){

self.id = id
self.name = name
}

required init(coder aDecoder: NSCoder) {

self.id = aDecoder.decodeObjectForKey("id") as! Int
self.name = aDecoder.decodeObjectForKey("name") as! String
}

func encodeWithCoder(aCoder: NSCoder) {

aCoder.encodeObject(self.id, forKey: "id")
aCoder.encodeObject(self.name, forKey: "name")
}

}


let model = Model(id: 1, name: "Make")

// 存储数据
Defaults["keyName"] = serialization(model)

// 读取数据
let data = deserialization(Defaults["keyName"].dataValue) as! Model

工具

JSON解析

库名: SwiftyJSON - Swift

说明: 用于解析JSON数据

使用:

1
2
3
4
5
6
7
// 拖动库源文件到项目目录

// 通常是配合 Alamofire 食用
let data = JSON(data: data! as NSData)
data[0]["user"]["name"].string // Optional
data[0]["user"]["name"].stringValue // String
// 其他的类型以此类推

图片裁剪

库名: AFImageHelper - Swift

说明: 总之就是用来裁剪图片用的, API 很简洁

使用: 这里就不详细说明了API比较多, 直接看文档 README.md

更新提示

库名: Siren - Swift

说明: 在app右更新的时候提醒用户到AppStore更新应用

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 拖动库源文件到项目目录

// 代码放到 AppDelegate.swift 生命周期函数中, 每次应用启动的时候调用
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

window?.makeKeyAndVisible()

let siren = Siren.sharedInstance

// Required 应用唯一标识
siren.appID = "376771144"

// Optional - Can set differentiated Alerts for Major, Minor, Patch, and Revision Updates
siren.majorUpdateAlertType = .Option
siren.minorUpdateAlertType = .Option
siren.patchUpdateAlertType = .Option
siren.revisionUpdateAlertType = .Option

siren.checkVersion(.Immediately)

return true
}

水平选择列表

UIScrollView水平选择列表 No.1

库名: AppStoreStyleHorizontalScrollView - Swift

说明: 当对scrollView插入相同size的控件时自动计算的宽度, 不在需要手动去计算了, 写入scrollView的空间大小一致时建议实用

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 拖动库源文件到项目目录

// storyboard 设置UIScrollView的Class为ASHorizontalScrollView
@IBOutlet weak var horizontalScrollView: ASHorizontalScrollView!

// 控件大小
self.horizontalScrollView.uniformItemSize = CGSizeMake(50, 50)
//this must be called after changing any size or margin property of this class to get acurrate margin
self.horizontalScrollView.setItemsMarginOnce()
for i in 1...10{
let button = UIButton()
button.backgroundColor = UIColor.blueColor()
button.tag = i
button.addTarget(self, action: "onClick:", forControlEvents: UIControlEvents.TouchUpInside)
self.horizontalScrollView.addItem(button)
}

UIView水平选择列表 No.2

库名: HTHorizontalSelectionList - Objective-C

说明: 当对scrollView插入相同size的控件时自动计算的宽度, 不在需要手动去计算了, 相对于上面的, 配置复杂了些, 但是写入的单个空间的宽度不再锁死了

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// 拖动库源文件到项目目录
// 创建头文件, 下面的代码添加到头文件
#import "HTHorizontalSelectionList.h"

// 1. 从控件库中拖一个UIView到Storyboard 的ViewController中
// 2. 设置UIview的Class为HTHorizontalSelectionList

var carMakes: [String]!
@IBOutlet weak var textSelectionList: HTHorizontalSelectionList!

self.textSelectionList.delegate = self
self.textSelectionList.dataSource = self
self.textSelectionList.selectionIndicatorAnimationMode = HTHorizontalSelectionIndicatorAnimationMode.Normal
self.textSelectionList.showsEdgeFadeEffect = true
self.textSelectionList.selectionIndicatorColor = UIColor.redColor()
self.textSelectionList.setTitleColor(UIColor.grayColor(), forState: UIControlState.Highlighted)
self.textSelectionList.setTitleFont(UIFont.systemFontOfSize(13), forState: UIControlState.Normal)
self.textSelectionList.setTitleFont(UIFont.boldSystemFontOfSize(13), forState: UIControlState.Selected)
self.textSelectionList.setTitleFont(UIFont.boldSystemFontOfSize(13), forState: UIControlState.Highlighted)

self.carMakes = ["All cars", "Audi", "Bitter", "BMW", "Büssing", "Gumpert", "MAN", "Mercedes-Benz", "Multicar", "Neoplan", "NSU", "Opel", "Porsche", "Robur", "Volkswagen", "Wiesmann"]

// HTHorizontalSelectionListDataSource Protocol Methods
func numberOfItemsInSelectionList(selectionList: HTHorizontalSelectionList!) -> Int {

return self.carMakes.count
}

func selectionList(selectionList: HTHorizontalSelectionList!, titleForItemWithIndex index: Int) -> String! {

return self.carMakes[index]
}

// HTHorizontalSelectionListDelegate Protocol Methods
func selectionList(selectionList: HTHorizontalSelectionList!, didSelectButtonWithIndex index: Int) {

println(self.carMakes[index])
}

虚拟键盘不挡住输入框

库名: IQKeyboardManager - Swift

说明: 虚拟键盘不挡住输入框, 使用起来非常简单, 仅需要一行代码就可实现, 效果相对来说比较生硬, 目前来说是个比较不错的解决方案

使用:

1
2
3
4
5
6
7
8
9
// 拖动库源文件到项目目录

// 代码放到 AppDelegate.swift 生命周期函数中, 每次应用启动的时候调用
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

IQKeyboardManager.sharedManager().enable = true

return true
}

UI 界面

上拉下拉刷新

库名: zhaokaiyuan99/PullRefresh -> MakeHui/PullRefresh - Swift

说明: tableview 上拉获取更多, 下拉刷新. (Ps: 作者很久没维护了, 源库目前不能用(作者还没处理我的合并请求). 本人Fork并修改好了, 目前可用. POI~)

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 拖动库源文件到项目目录

override func viewDidLoad() {

// 下拉刷新
self.tableView.addHeaderWithCallback({
// 这里请求数据, 并更新数据源, 刷新tableview

// 结束下拉刷新
self.tableView.headerEndRefreshing()

})

// 上拉获取更多
self.tableView.addFooterWithCallback({
// 这里请求数据, 并更新数据源, 刷新tableview

// 结束上拉获取更多
self.tableView.footerEndRefreshing()
})
}

日历

日历 No.1

库名: CVCalendar - Swift

说明: 日历, 选择日期 (在tableView headerView 中显示不能充满整个屏幕, 待解决)

使用: 设置比较繁琐, 这里就不列出来, 详情README.md

日历 No.2

库名: FSCalendar - Objective-C

说明: 日历, 选择日期

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 拖动库源文件到项目目录
// 创建头文件, 下面的代码添加到头文件
#import "FSCalendar.h"
#import "NSDate+FSExtension.h"

// 1. 从控件库中拖一个UIView到Storyboard 的ViewController中
// 2. 设置UIview的Class为FSCalendar

// 点击日期是获取日期
func calendar(calendar: FSCalendar!, didSelectDate date: NSDate!) {

// 格式化日期
println(date.fs_stringWithFormat("yyyy-MM-dd"))
}

// 关闭title两侧的年和月日
func calendar(calendar: FSCalendar!, hasEventForDate date: NSDate!) -> Bool {

return true
}

倒计时

库名: SwiftCountdownButton - Swift

说明: 设置一个倒计时的button, 在倒计时没有结束时不能点击 (用于获取手机验证码块使用)

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 拖动库源文件到项目目录

// 1. 从控件库中拖一个UIButton到Storyboard 的ViewController中
// 2. 设置UIButton的Class为SwiftCountdownButton

// 3. 设置提示字符: attribute inspector -> State Config -> Default -> 获取验证码
// attribute inspector -> State Config -> Disabled -> second后重新获取
// (Ps: second是关键词会自动替换成秒数)

// 开始倒计时
countdownBtn.maxSecond = 30 // 默认为60
countdownBtn.countdown = true

// 强制结束
countdownBtn.countdown = false

// 判断是否处于倒计时阶段
countdownBtn.countdown // Bool

侧边栏

库名: RESideMenu Objective-C –> SwiftRESideMenu - Objective-C

说明: 类似于QQ的侧边栏效果, 对Storyboard的支持也很好

使用: 直接看 Swift 桥接 Demo https://github.com/MakeHui/SwiftRESideMenu

弹出提示

库名: SVProgressHUD Objective-C

说明: 弹窗, 提示语, 菊花

使用:

1
2
3
4
5
6
7
8
9
10
11
12
// 拖动库源文件到项目目录
// 创建头文件, 下面的代码添加到头文件
#import "SVProgressHUD.h"
SVProgressHUD.show() // 菊花
SVProgressHUD.showWithStatus("please wait...") // 菊花带提示语
SVProgressHUD.showSuccessWithStatus("success")
SVProgressHUD.showErrorWithStatus("error")
SVProgressHUD.showInfoWithStatus("info")
SVProgressHUD.showImage(UIImage(named: "ImageName"), status: "info")

SVProgressHUD.dismiss() // 立即隐藏
SVProgressHUD.dismissWithDelay(2) // 多少秒后隐藏

图片

图片虚化(模糊)处理

图片虚化(模糊)处理 No.1

库名: SABlurImageView - Swift

说明: 图片虚化效果, 应该是给UIImageValue添加了一个虚化图层, 而不是直接处理了整个图片 (Ps: 当ImageView的约束发生改变的时候, 效果会失效, 暂时没找到解决方案)

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 拖动库源文件到项目目录

// 1. 从控件库中拖一个UIImageView到Storyboard 的ViewController中
// 2. 设置UIImageView的Class为SABlurImageView

@IBOutlet var imageView: SABlurImageView!

override func viewDidLayoutSubviews() {

super.viewDidLayoutSubviews()

// 重置约束, 因为使用Storyboard布局的问题, 需要重置约束
// 要不然在, 默认布局尺寸以外的尺寸上会失效
self.imageView.layoutIfNeeded()
// 虚化吹
imageView.configrationForBlurAnimation(boxSize: 100)
imageView.blur(0.8)
}

// viewDidLayoutSubviews方法并不是十分可靠, 所有在这个方法里再执行一次
override func viewDidAppear(animated: Bool) {

super.viewDidAppear(animated)

// 重置约束, 因为使用Storyboard布局的问题, 需要重置约束
// 要不然在, 默认布局尺寸以外的尺寸上会失效
self.imageView.layoutIfNeeded()
// 虚化
imageView.configrationForBlurAnimation(boxSize: 100)
imageView.blur(0.8)
}

图片虚化(模糊)处理 No.2

库名: SwiftUIImageEffects - Swift

说明: 图片虚化效果

使用:

1
2
3
4
5
6
7
8
9
10
11
12
// 拖动库源文件到项目目录

// 直接操作图片
var image: UIimage = UIImage(named: "imageNmae")!
// 作者二次封装好的几个虚化效果, 不满意可自己调整
image.applyLightEffect()
image.applyExtraLightEffect()
image.applyDarkEffect()
// 自定义主色调
image.applyTintEffectWithColor(UIColor.blueColor())
// 完全自定义
image.applyBlurWithRadius(20, tintColor: UIColor(white: 0.11, alpha: 0.73), saturationDeltaFactor: 1.8)

图片缓存异步加载

库名: SDWebImage - Objective-C

说明: 图片异步加载, 并自动缓存上

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 拖动库源文件到项目目录
// 创建头文件, 下面的代码添加到头文件
#import "UIImageView+WebCache.h"

let imageUrl: NSURL = NSURL(string: "http://huyaohui.com/image.png")! // 网络图片路径
let placeholderImage: UIImage = UIImage(named: "imageName")! // 默认图片
// 常用 API
imageView.sd_setImageWithURL(imageUrl, placeholderImage: placeholderImage)


let imageCache = SDImageCache.sharedImageCache()
// 清除缓存
imageCache.clearMemory()
imageCache.clearDisk()
// 获取缓存大小
var imageCacheSize = imageCache.getSize()

// 其他API 查阅 [README.md](https://github.com/rs/SDWebImage/blob/master/README.md)

图片轮播

库名: SDCycleScrollView - Objective-C

说明: 图片轮播

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 拖动库源文件到项目目录
// 创建头文件, 下面的代码添加到头文件
#import "SDCycleScrollView.h"

// 1. 从控件库中拖一个UIView到Storyboard 的ViewController中
// 2. 设置UIview的Class为SDCycleScrollView

@IBOutlet var cycleScrollView: SDCycleScrollView!

var imagesURLStrings: [String] = [
"http://huyaohui.com/image.png",
"http://huyaohui.com/image.png"
]
var placeholderImage: UIImage = UIImage(named: "placeholder")!

cycleScrollView.pageControlAliment = SDCycleScrollViewPageContolAlimentRight
cycleScrollView.placeholderImage = UIImage
cycleScrollView.delegate = self
cycleScrollView.imageURLStringsGroup = imagesURLStrings

// SDCycleScrollViewDelegate 获取点击了第几张图片
func cycleScrollView(cycleScrollView: SDCycleScrollView!, didSelectItemAtIndex index: Int) {

println(index)
}

图片多选

库名: CorePhotoPickerVCManager - Objective-C

说明: 图片多选

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// 拖动库源文件到项目目录
// 创建头文件, 下面的代码添加到头文件
#import "CorePhotoPickerVCManager.h"

// 实现 UIActionSheetDelegate

@IBAction func sheetOnClickAction(sender: UIButton) {
var sheet: UIActionSheet = UIActionSheet()
sheet.title = "请选择"
sheet.delegate = self
sheet.addButtonWithTitle("取消")
sheet.addButtonWithTitle("拍照")
sheet.addButtonWithTitle("相册")
sheet.cancelButtonIndex = 0
sheet.showInView(self.view)
}

func actionSheet(sheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) {

var type: CorePhotoPickerVCMangerType = CorePhotoPickerVCMangerTypeCamera
var typeCode = 0

if buttonIndex == 1 {
type = CorePhotoPickerVCMangerTypeCamera
}
else if buttonIndex == 2 {
type = CorePhotoPickerVCMangerTypeMultiPhoto
typeCode = 1
}

var manager: CorePhotoPickerVCManager = CorePhotoPickerVCManager.sharedCorePhotoPickerVCManager()

// 设置类型
manager.pickerVCManagerType = type

//最多可选3张
manager.maxSelectedPhotoNumber = 9

// 错误处理
// 这里翻译过来没卵用, 说以换了种写法
// if manager.unavailableType.value == CorePhotoPickerUnavailableTypeNone {
// return
// }

// 判断相机是否可用
if typeCode == 0 && !(UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera)) {

println("相机不可用~")
return
}

var pickerVC: UIViewController = manager.imagePickerController

//选取结束
manager.finishPickingMedia = { medias in

if typeCode == 0 && self.cellRowImages.count == 9 {
return
}
else if typeCode == 1 {
self.cellRowImages = []
}

for (key, value) in enumerate(medias) {

self.cellRowImages.append(value.editedImage)
}

self.collectionView.reloadData()
self.tableView.reloadData()
}

self.presentViewController(pickerVC, animated: true, completion: nil)
}

图片浏览器

库名: CorePhotoBroswerVC - Objective-C

说明: 图片浏览器 (Ps: 此库依赖 SDWebImage 等库, 小心使用)

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 拖动库源文件到项目目录
// 创建头文件, 下面的代码添加到头文件
#import "PhotoBroswerVC.h"

var index: UInt = 0 // 默然要显示的是照片集中的第几张
var imageView: UIImageView // 当前要显示的那个对象, 用作动画效果的
var imageList: [String] // 要显示图片的URL

func showPhotoBroswer(index: UInt, imageView: UIImageView, imageList: [String]) {

PhotoBroswerVC.show(self, type: PhotoBroswerVCTypeZoom, index: index) { () -> [AnyObject]! in
var modelsM: NSMutableArray = NSMutableArray(capacity: self.hotTopicList.count)

for var i=0; i<imageList.count; i++ {

var pbModel: PhotoModel = PhotoModel()
pbModel.mid = UInt(i + 1)

pbModel.image_HD_U = imageList[i]

pbModel.sourceImageView = imageView

modelsM.addObject(pbModel)
}

return modelsM as [AnyObject]
}
}

相册选择/浏览器

库名: LGPhotoBrowser - Objective-C

说明: 此框架包含三个模块:照片浏览器,相册选择器,照相机