develop with swift
TRANSCRIPT
Develop with Swift
森田 直樹
morizotter
2015
Githubhttp://github.com/morizotter
Github Awardhttps://github-awards.com/users/search?login=morizotter
TouchVisualizerhttps://github.com/morizotter/TouchVisualizer
SwiftyDrophttps://github.com/morizotter/SwiftyDrop
Cogglehttps://coggle.it
Cogglehttps://coggle.it
Cogglehttps://coggle.it
Cogglehttps://coggle.it
angularjs-style-guidehttps://github.com/mgechev/angularjs-style-guide/blob/
master/README-ja-jp.md
angularjs-style-guidehttps://github.com/mgechev/angularjs-style-guide/blob/
master/README-ja-jp.md
Other contributions
• SDWebImage
• SwiftBond - Japanese 2 way binding
• Evernote SDK
• Treasuredata SDK
• DateTools
• Carthage
• NVActivityIndicatorView
• TagListView
• FlatUIColors
• …
Develop with Swift
QolkCozy Qiita Reader for iOS.
QolkCozy Qiita Reader for iOS.
QolkQiitaクライアントのQolkをMacbookとCarthageで作った話
http://qiita.com/morizotter/items/90d6d6024a6e7e0e9e84
Powerful Swift OSSs.
• Dependency Manager: Carthage
• Networking: Alamofire
• JSON parser: SwiftyJSON
• Database: Realm
• Future(promise): BrightFutures
• View binding: SwiftBond
• Image loading: Kingfisher
• AutoLayout: SnapKit
Powerful Swift OSSs.
• Dependency Manager: Carthage Cocoapods
• Networking: Alamofire AFNetworking
• JSON parser: SwiftyJSON Mantle
• Database: Realm MagicalRecord/CoreData
• Future(promise): BrightFutures Bolts/PromiseKit
• View binding: SwiftBond ReactiveCocoa?
• Image loading: Kingfisher SDWebImage
• AutoLayout: SnapKit Masonry
Objective-C?
Core OSSs
• Carthage
• Alamofire
• BrightFutures
• SwiftyJSON
Carthage for all
Carthage
• Decentralized
• No .xcworkspace
• Clean & Simple
• Very Easy to distribute
• Increasing
• Centralized
• .xcworkspace
• Easy to use
• Easy to distribute
• Already many
Cocoapodshttps://github.com/Carthage/Carthage https://cocoapods.org/
Carthage
$ brew update$ brew install carthage$ cd move/to/app/root$ vi Cartfile
github "Alamofire/Alamofire" == 3.1.2
wq$ carthage update -platform ios
Carthage
Carthage
• Pros:
• Project remains clean.
• No build time.
• Cons:
• Library build time.
• Relatively fewer libraries.
If library doesn’t compatible with
Carthage?
Fork!
Tweak!
(Pull Request!)
Just 4 steps
1. Create CocoaTouch Framework
2. Add files to Framework target
3. Make scheme shared
4. git push and tag in Github
I made 5 libraries or more
Carthage Compatible for Qolk.
Many Thanks.
Alamofire
SwiftyJSON
BrightFutures
cooperate.
BrightFutures
Networking system
API Server
App
SwiftyJSON
Alamofire & BrightFutures
// AlamofireClient.swift
struct AlamofireClient { static let sharedInstance = AlamofireClient() let alamofire: Manager init() { let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() configuration.timeoutIntervalForResource = RequestTimeoutSec alamofire = Manager(configuration: configuration) } static func requestJSON(URLRequest: URLRequestConvertible) -> Future<JSONResponse, ErrorResponse> { let promise = Promise<JSONResponse, ErrorResponse>() sharedInstance.alamofire.request(URLRequest) .validate() .responseJSON(options: .AllowFragments) { (response) -> Void in log.debug("REQUEST: \(response.request)") log.debug("RESPONSE: \(response.response)”)
switch response.result { case .Success(let json): log.debug("[QIITA] JSON: \(json)") promise.success(JSONResponse(json: json, response: response.response!)) case .Failure(let error): log.debug("[QIITA] ERROR: \(error.localizedDescription)") self.errorHandling(error, response: response.response) promise.failure(ErrorResponse(nsError: error, response: response.response)) } } return promise.future } … } Return future.
Responses
// AlamofireClient.swift
struct JSONResponse { var json = JSON([]) var response: NSHTTPURLResponse? var rateLimit: Int? var rateRemaining: Int? init(json: AnyObject?, response: NSHTTPURLResponse?) { if let json = json { self.json = JSON(json) } if let response = response { self.response = response let headers = JSON(response.allHeaderFields) self.rateLimit = headers["Rate-Limit"].int self.rateRemaining = headers["Rate-Remaining"].int } } }
struct ErrorResponse: ErrorType { var error: NSError var response: NSHTTPURLResponse? init(error: NSError, response: NSHTTPURLResponse? = nil) { self.nsError = error self.response = response } }
Make original struct for easy handling.
BrightFutures & SwiftyJSON
// AppManager.swift
func getItems(pageInfo: PageInfo, query: String?) -> PageResponseFuture { let promise = Promise<PageResponse, ErrorResponse>() AlamofireClient.requestJSON(QiitaAPIRouter.Items(pageInfo: pageInfo, query: query)) .onSuccess { (result: JSONResponse) in let pageResponse = PageResponse(json: result.json, pageInfo: pageInfo, response: result.response!)
promise.success(pageResponse) } .onFailure { (errorResponse: ErrorResponse) in promise.failure(errorResponse) } return promise.future }
struct PageResponse { var json: JSON var totalCount: Int? var pageInfo: PageInfo init(json: JSON, pageInfo: PageInfo, response: NSHTTPURLResponse?) { self.json = json self.pageInfo = pageInfo if let response = response { let headers = JSON(response.allHeaderFields) self.totalCount = headers["Total-Count"].intValue } } }
typealias PageResponseFuture = Future<PageResponse, ErrorResponse>
Inject something before network returns.
SwiftyJSON
final class Item: Object, ObjectCopyable { dynamic var renderedBody = "" dynamic var body = "" dynamic var coediting = false dynamic var createdAt = "" dynamic var itemId = "" dynamic var isPrivate = false let tags = List<Tag>() dynamic var title = "" dynamic var updatedAt = "" dynamic var url = "" dynamic var user: User? override static func primaryKey() -> String? { return "itemId" } class func fromJSON(json: JSON) -> Item { let item = Item() item.renderedBody = json["rendered_body"].stringValue item.body = json["body"].stringValue item.coediting = json["coediting"].boolValue item.createdAt = json["created_at"].stringValue item.itemId = json["id"].stringValue item.isPrivate = json["private"].boolValue item.title = json["title"].stringValue item.updatedAt = json["updated_at"].stringValue item.url = json["url"].stringValue item.user = User.fromJSON(json["user"]) for (_, subJson): (String, JSON) in json["tags"] { item.tags.append(Tag.fromJSON(subJson)) } return item } … }
Sync Wantedly