- Product Manager
- Web Engineer
- Customer Support
- Other occupations (60)
- Development
-
Business
- Product Manager
- プロダクトマネージャー
- 広報
- カルチャー推進・浸透
- 知財戦略立案・推進・発明発掘
- リスクマネジメント統括本部
- 内部監査
- AML/CFTコンプライアンス
- AML・金融犯罪対策Ops
- 金融コンプライアンス
- システム監査
- ビジネス採用担当
- 経営企画(予実・IR)
- HRBP
- Legal
- 債権管理/MFK
- ToB Sales
- インサイドセールス
- フィールドセールス
- インサイドセールス SDR
- インサイドセールス企画
- オンラインセールス
- SaaS営業、MFBC
- インサイドセールス MFBC
- セールス MFBC
- マーケティングリサーチャー
- マーケター
- データマーケター
- BtoBマーケティングリーダー
- CRMスペシャリスト
- イベントマーケター
- Other
こんにちは。エンジニアの浅井です。
普段はマネーフォワードのiOSアプリ開発を担当しています。
弊社では、全社で使用する共通ライブラリの開発を積極的に行っています。
今回は、先日正式リリースされたSwift2.0で作成中のAPI通信基盤をご紹介します。
APIKitを参考に、下記のライブラリを用いて実装しています。
* Alamofire(HTTP通信)
* ObjectMapper(JSONのパース)
本エントリーの肝
本エントリーではSwift2.0で追加された、ProtocolExtensionを利用しています。
プロトコルに実装を定義できるだけでなく、細かく条件指定ができるので、そのプロトコルに準拠したクラスの実装を少なく抑えることができます。
また、typealiasによるジェネリクスを利用することで、タイプセーフな設計になっています。
利用側のコード
兎にも角にもまずは利用側のコードです。
API.call(Endpoint.GetUsers()) { result in
switch result {
case .Success(let users):
// 成功時の処理
println("success")
case .Failure(let data, let error):
// 失敗時の処理
println("failure")
}
}
API.callをリクエストオブジェクトを引数にして呼び出す(後述RequestProtocol)返却されるresultはAlamofire.Result型Success時のusersはジェネリクスにより型が明らかになっている(後述ResponseType)
APIの例
例えばこんなAPIがあったとします。
URL
https://api.test.com/users
Response
{
"users": [
{
id: 1,
name: "yuki"
},
{
id: 2,
name: "asai"
}
]
}
こんなときObjectMapperを用いたモデルクラスは以下のように定義するでしょう。
class Users: Mappalbe {
var users: [User]?
required init?(_ map: Map) {
mapping(map)
}
func mapping(map: Map) {
users <- map["users"]
}
}
class User: Mappable {
var id: Int?
var name: String?
required init?(_ map: Map) {
mapping(map)
}
func mapping(map: Map) {
id <- map["id"]
name <- map["name"]
}
}
そしてリクエストオブジェクトは以下のように定義します。
class Endpoint {
class GetUsers: RequestProtocol {
typealias ResponseType = Users
var baseUrl: String {
return "https://api.test.com/"
}
var path: String {
return "users"
}
}
}
このResponseTypeが成功時のresultの値の型になります。
ライブラリ側のコード
APIの定義
Alamofireを用いることで、HTTP通信の処理もすっきりしています。
class API {
class func call<T: RequestProtocol, V where T.ResponseType == V>(request: T, completion: (Result<V>) -> Void) {
Alamofire.request(request)
.responseJSON { req, res, result in
switch result {
case .Success(let json):
completion(request.fromJson(json))
case .Failure(let data, let error):
completion(.Failure(data, error))
}
}
}
}
RequestProtocolの定義
protocol RequestProtocol: URLRequestConvertible {
typealias ResponseType
var method: Method { get }
var baseUrl: String { get }
var path: String { get }
var parameters: [String: AnyObject]? { get }
var encoding: ParameterEncoding { get }
var headers: [String: String]? { get }
func fromJson(json: AnyObject) -> Result<ResponseType>
}
extension RequestProtocol {
var method: Method {
return .GET
}
var parameters: [String: AnyObject]? {
return nil
}
var encoding: ParameterEncoding {
return .URL
}
var headers: [String: String]? {
return nil
}
func fromJson(json: AnyObject) -> Result<ResponseType> {
guard let value = json as? ResponseType else {
return .Failure(nil, error(0, localizedDescription: "Convert object failed"))
}
return .Success(value)
}
}
ObjectMapper対応
ResponseTypeがObjectMapper.Mappalbeに準拠したクラスでであれば、ObjectMapperのマッピング処理を行うよう、ProtocolExtensionで定義します。
extension RequestProtocol where ResponseType: Mappable {
func fromJson(json: AnyObject) -> Result<ResponseType> {
guard let value = Mapper<ResponseType>().map(json) else {
return .Failure(nil, error(0, localizedDescription: "Mapping object failed"))
}
return .Success(value)
}
}
JSONをそのまま利用したい場合はRequestProtocolを準拠したクラスでfromJsonを都度実装してやればよいですし、ProtocolExtensionで拡張していくことで、様々なマッパーに対応させることができるでしょう。
最後に
マネーフォワードでは、新しい技術も積極的に取り入れていくエンジニアを募集しています。
ご応募お待ちしております!
【採用サイト】
■『マネーフォワード採用サイト』 https://recruit.moneyforward.com/
■『Wantedly』 https://www.wantedly.com/companies/moneyforward
【公開カレンダー】
■マネーフォワード公開カレンダー
【プロダクト一覧】
■家計簿アプリ・クラウド家計簿ソフト『マネーフォワード』 https://moneyforward.com/
■家計簿アプリ・クラウド家計簿ソフト『マネーフォワード』 iPhone,iPad
■家計簿アプリ・クラウド家計簿ソフト『マネーフォワード』 Android
■クラウド型会計ソフト『MFクラウド会計』 https://biz.moneyforward.com/
■クラウド型請求書管理ソフト『MFクラウド請求書』 https://invoice.moneyforward.com/
■クラウド型給与計算ソフト『MFクラウド給与』 https://payroll.moneyforward.com/
■消込ソフト・システム『MFクラウド消込』 https://biz.moneyforward.com/reconciliation/
■マイナンバー対応『MFクラウドマイナンバー』 https://biz.moneyforward.com/mynumber