あるプロジェクトで導入しているライブラリを簡単に説明を添えてくれと頼まれたので その内容をQiitaにも投稿します。
iOSプロジェクトで導入しているライブラリの説明
実際にプロジェクトで使っているコードを一部抜粋して載せます。
※ 長くなってしまうので必要最低限の記述とし、Import等は省きます。
※ App.XX
というのは自前で定義しているstructなのでスルーしてください。
APIKit
APIリクエストをする際に使用するネットワークライブラリです。
JSON デコーダのHimotokiと合わせて使っています。
例:お知らせ情報を取得
import APIKit
import Himotoki
struct InformationEntity {
let id: Int
let publishedAt: String
let title: String
let content: String
let images: [ImageEntity]
init(id: Int, publishedAt: String, title: String, content: String, images: [ImageEntity]) {
self.id = id
self.publishedAt = publishedAt
self.title = title
self.content = content
self.images = images
}
}
extension InformationEntity: Decodable {
static let URLTransformer = Transformer<String, NSURL> { URLString throws -> NSURL in
if let URL = NSURL(string: URLString) {
return URL
}
throw customError("Invalid URL string: \(URLString)")
}
static func decode(_ e: Extractor) throws -> InformationEntity {
return try InformationEntity(
id: e <| "id",
publishedAt: e <| "published_at",
title: e <| "title",
content: e <| "content",
images: e <|| "images"
)
}
}
struct InformationItemsRequest: Request {
typealias Response = [InformationEntity]
let number: Int
var baseURL: URL {
return URL(string: "http://xxxxxxx.com")!
}
var method: HTTPMethod {
return .get
}
var parameters: Any? {
return [
"page": number
]
}
var path: String {
return "/informations"
}
func response(from object: Any, urlResponse: HTTPURLResponse) throws -> Response {
return try decodeArray(object, rootKeyPath: ["informations"])
}
}
実際にリクエストを送る。
let informationsReqest = InformationItemsRequest(number: number)
Session.send(informationsReqest) { result in
switch result {
case .success(let response):
closure(response)
case .failure(let error):
print(error)
}
}
Himotoki
ikesyo/Himotoki: A type-safe JSON decoding library purely written in Swift
JSONをデコードするライブラリです。
主にAPIKitで受け取ったJSONをデコードしてオブジェクトとして扱えるようにします。
以下の e <| "id”
部分。
static func decode(_ e: Extractor) throws -> InformationEntity {
return try InformationEntity(
id: e <| "id",
publishedAt: e <| "published_at",
title: e <| "title",
content: e <| "content",
images: e <|| "images"
)
}
}
Result
antitypical/Result: Swift type modelling the success/failure of arbitrary operations.
成功・エラーをResult型として返すライブラリです。
以下の様にSwitch文で判断し処理を振り分けます。
let informationsReqest = InformationItemsRequest(number: number)
Session.send(informationsReqest) { result in
switch result {
case .success(let response):
closure(response)
case .failure(let error):
print(error)
}
}
Kingfisher
画像のダウンロード・キャッシュを行うライブラリです。
例えば、以下のようにURLを渡すと画像を取得してImageViewに表示します。
@IBOutlet weak var targetImageView: UIImageView!
...
guard let imageUrl = model.imageUrl else { return }
targetImageView.kf.setImage(with: URL(string: imageUrl))
SwiftyJSON
SwiftyJSON/SwiftyJSON: The better way to deal with JSON data in Swift
JSONを簡単に扱うためのライブラリです。
PUSH通知のPayloadをデコードするのに使っています。
参考:[iOSのPUSH通知(APNS)の特徴・ノウハウまとめ(iOS 9まで対応) - Qiita] (http://qiita.com/mono0926/items/df03c61adc56934e2e7a#%E9%80%9A%E7%9F%A5%E3%83%9A%E3%82%A4%E3%83%AD%E3%83%BC%E3%83%89%E3%82%92struct%E3%81%A7%E3%83%A9%E3%83%83%E3%83%97%E3%81%97%E3%81%A6%E6%89%B1%E3%81%86%E3%81%A8%E4%BE%BF%E5%88%A9) :pray:
(Himotokiと被っているのでコードを書き換えて1つにするべきかも)
import SwiftyJSON
struct NotificationPayload {
let json: JSON
fileprivate var aps: JSON { return json["aps"] }
var alert: String? { return aps["alert"].string }
var badge: Int? { return aps["badge"].int }
var sound: String? { return aps["sound"].string }
var contentAvailable: Int? { return aps["content-available"].int }
var notificationId: Int? { return aps["notification_id"].int }
fileprivate var body: JSON { return json["body"] }
var category: String? { return body["category"].string }
init(userInfo: [AnyHashable: Any]) {
json = JSON(userInfo)
}
}
SwiftyUserDefaults
radex/SwiftyUserDefaults: Modern Swift API for NSUserDefaults
UserDefaultsを扱いやすくするライブラリです。
Keyを予め設定することで文字列ではなく、Value Typeで扱うことができます。
Keyを定義
import SwiftyUserDefaults
extension DefaultsKeys {
static let deviceToken = DefaultsKey<String?>("deviceToken")
static let accessToken = DefaultsKey<String?>("accessToken")
static let firstLaunchAt = DefaultsKey<Date?>("firstLaunchAt")
}
更新・取得
let deviceToken = deviceToken.map { String(format: "%.2hhx", $0) }.joined()
Defaults[.deviceToken] = deviceToken
...
let deviceToken = Defaults[.deviceToken]
Fabric、Crashlytics
Fabric上でデータを取得したり、配布を行うためのSDKです。
コード自体はAppDelegateに以下を記述するだけです。
...
Fabric.with([Crashlytics.self])
Crashlytics.sharedInstance().setUserIdentifier(Defaults[.accessToken])
GoogleMaps
GoogleMapsのSDKです。
ちなみにGoogleMapsのマーカーからGoogleMapsアプリに飛ばす処理を書いたら、
審査の際に純正のMapを使えとリジェクトされました。
@IBOutlet weak var mapView: UIView!
...
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
setupMap() /// AutoLayoutが設定されてからセットしたいのでviewDidLayoutSubviewsで呼んでます
}
fileprivate func setupMap() {
let googleMap = GMSMapView(frame: CGRect(x: 0, y: 0, width: mapView.bounds.width, height: mapView.bounds.height))
let camera = GMSCameraPosition.camera(withLatitude: latitude, longitude: longitude, zoom: zoom)
googleMap.camera = camera
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
marker.map = googleMap
marker.icon = UIImage(named: "MarkerIcon")
mapView.addSubview(googleMap)
}
DZNEmptyDataSet
UITableVIewやUICollectionViewでコンテンツが空だった場合に、簡単に画像やボタン等を配置するためのライブラリです。(Objective-C)
func viewDidLoad() {
tableView.emptyDataSetSource = self
tableView.emptyDataSetDelegate = self
}
...
// MARK: - DZNEmptyDataSetSource, DZNEmptyDataSetDelegate
extension CouponViewController: DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {
func title(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
let text = "XXXXXXXが見つかりませんでした"
return NSAttributedString(string: text, attributes: [NSFontAttributeName: App.Font.main(14), NSForegroundColorAttributeName: UIColor.gray])
}
func description(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
let text = "配信の際はPUSH通知でお知らせ致します"
return NSAttributedString(string: text, attributes: [NSFontAttributeName: App.Font.main(12), NSForegroundColorAttributeName: UIColor.gray])
}
}
Eureka
xmartlabs/Eureka: Elegant iOS form builder in Swift
多彩なフォームを作成できるライブラリです。
コードでStatic Table View を構成すると少々面倒ですが、このライブラリを使うと簡単に設計できます。
(とはいえ書き方のクセが強い)
import UIKit
import Eureka
class SettingViewController: FormViewController {
override func viewDidLoad() {
super.viewDidLoad()
form
+++ Section("PUSH通知設定")
<<< LabelRow("通知設定を開く") {
$0.title = $0.tag
}.onCellSelection(){row in
let url = URL(string: UIApplicationOpenSettingsURLString)!
let app = UIApplication.shared
app.openURL(url)
}
+++ Section("このアプリについて")
<<< ButtonRow("利用規約") {
$0.title = $0.tag
$0.presentationMode = .segueName(segueName: R.segue.settingViewController.toTermsOfUseVC.identifier, onDismiss: nil)
}
<<< LabelRow(){
$0.title = "このアプリを評価する"
}.onCellSelection(){row in
let url = URL(string: App.URL.itunes)!
let app = UIApplication.shared
app.openURL(url)
}
<<< LabelRow() {
$0.title = "バージョン"
$0.value = App.version
}
}
}
NVActivityIndicatorView
ninjaprox/NVActivityIndicatorView: A collection of awesome loading animations
色々なローディングインジケータを扱えるライブラリです。
オリジナルのgontovnik/DGActivityIndicatorView はObjective-Cですが、こちらはSwiftで書き直されています。
PMAlertController
UIAlertControllerがカスタマイズされたライブラリです。
普通のUIAlertControllerのように使います。(普通のUIAlertControllerでいい件)
let popAlertController = PMAlertController(title: "ダウンロード頂き\nありがとうございます!", description: terms.description, image: nil, style: .alert)
popAlertController.addAction(PMAlertAction(title: "OK", style: .default, action: { () in
self.viewController?.enableTabBar() /// タブバーを有効にする
}))
self.present(popAlertController, animated: true, completion: nil)
SwiftDate
malcommac/SwiftDate: The best way to manage Dates and Timezones in Swift
日付に関する値を扱いやすくするライブラリです。
Realm
realm/realm-cocoa: Realm is a mobile database: a replacement for Core Data & SQLite
Databeseフレームワークライブラリです。ローカルにデータを保持する際に使います。
R.swift
Resourceを管理するライブラリです。
R.~~
という書き方で以下のものがコード補完されるようになります。
- Images
- Fonts
- Resource files
- Colors
- Localized strings
- Storyboards
- Segues
- Nibs
- Reusable cells
let icon = R.image.settingsIcon()
let font = R.font.sanFrancisco(size: 42)
let viewController = CustomViewController(nib: R.nib.customView)
let string = R.string.localizable.welcomeWithName("Arthur Dent")
文字列で管理しなくなるのでtypo等の心配もなくなりいいのですが、
全部 R
から始まり、コードが増えてきた際の可読性が落ちる気がするので、SwiftGenの方がいいかも。
Instructions
吹き出しを表示できるライブラリです。チュートリアルなどで使います。
...
extension AreaShopViewController: CoachMarksControllerDataSource, CoachMarksControllerDelegate {
func numberOfCoachMarks(for coachMarksController: CoachMarksController) -> Int {
return 1
}
func coachMarksController(_ coachMarksController: CoachMarksController, coachMarkAt index: Int) -> CoachMark {
var coachMark: CoachMark = coachMarksController.helper.makeCoachMark(for: tableView, pointOfInterest: nil, cutoutPathMaker: nil)
coachMark.arrowOrientation = .bottom
return coachMark
}
func coachMarksController(_ coachMarksController: CoachMarksController, coachMarkViewsAt index: Int, coachMark: CoachMark) -> (bodyView: CoachMarkBodyView, arrowView: CoachMarkArrowView?) {
let coachViews = coachMarksController.helper.makeDefaultCoachViews(withArrow: true, withNextText: true, arrowOrientation: coachMark.arrowOrientation)
coachViews.bodyView.hintLabel.text = "💡お気に入りに登録して店舗のオトクな情報をゲットしよう!"
coachViews.bodyView.nextLabel.text = "OK"
coachViews.bodyView.nextLabel.font = UIFont.boldSystemFont(ofSize: UIFont.labelFontSize)
return (bodyView: coachViews.bodyView, arrowView: coachViews.arrowView)
}
}
TextAttributes
delba/TextAttributes: An easier way to compose attributed strings
テキストの装飾を扱いやすくするライブラリです。
var titleLabel = UILabel()
let attrs = TextAttributes()
.lineHeightMultiple(1.4)
.underlineStyle(.styleSingle)
titleLabel.attributedText = NSAttributedString(string: "タイトル", attributes: attrs)
AttributedLabel
KyoheiG3/AttributedLabel: Easy to use, fast, and higher performance than UILabel.
UILabelよりもパフォーマンスを上げ、扱いやすくするライブラリです。 ※ UILabelの継承じゃないことに注意
var bodyLabel = AttributedLabel()
bodyLabel.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: 30)
bodyLabel.font = UIFont.systemFont(ofSize: 15)
bodyLabel.contentAlignment = .topLeft
bodyLabel.padding = 15
view.addSubview(bodyLabel)
以上となります。 実は現状使ってないライブラリもあります。