SlideShare ist ein Scribd-Unternehmen logo
1 von 33
Downloaden Sie, um offline zu lesen
#swift
© 2014 Shintaro Kaneko
Instagram Viewer (Swift)
Shintaro Kaneko
iOS/Android/Web Developer
自己紹介
金子 慎太郎 (Shintaro Kaneko)
iOS/Android/Webエンジニア
株式会社エウレカでマッチングアプリ「pairs」の開発
「Couples」というアプリも開発していました(pairsメイン)
趣味
コーヒー, カメラ, 数学
shintaro.kaneko
@kaneshinth
@kaneshin
@kaneshinth
@kaneshinth
Facebook:
Twitter:
GitHub:
Qiita:
Instagram:
ちょっと自慢
WWDC2014に参加したので
Swiftの発表は会場で聞いていました
GitHub Sticker
欲しい方いたら差しあげます
Agenda
InstagramのAPIを使ってSwiftで簡単なビューワーアプリの開発
これからAPIから情報を取得したい人向けです
0. 作ったアプリ(1時間)
1. 開発準備
• Instagram APIについて
• 使用するフレームワークの導入
2. 実装
• Instagramから情報を取得
3. まとめ
0. 作ったアプリ(1時間)
1. 開発準備
Instagram APIについて
使用するフレームワークの導入
Instagram APIについて
Instagram APIについて
今回使用するエンドポイント
https://api.instagram.com/v1/media/popular?client_id=CLIENT-ID
CLIENT-IDの発行 => InstagramへClient登録
http://instagram.com/developer/clients/register/
※注: 1時間につき5000リクエスト
詳細:Instagram API Endpoints
http://instagram.com/developer/endpoints/
Instagram APIについて
今回使用するエンドポイント
https://api.instagram.com/v1/media/popular?client_id=CLIENT-ID
人気のメディア(写真/動画)データが返却される
画像についての情報取得は下記のように行える
responseJSON["data"][i]["images"]["standard_resolution"]
/* { "url": "http://s.cdninstagram.com/hphotos-xap1/a.jpg",
"width": 640,
"height": 640
} */
使用するフレームワークの導入
Alamofire … ネットワーク通信
SwiftyJSON … JSONデータを扱う
使用するフレームワークの導入
今回使用するフレームワーク
Alamofire (https://github.com/Alamofire/Alamofire)
ネットワーク通信を手軽にする
SwiftyJSON (https://github.com/SwiftyJSON/SwiftyJSON)
JSONデータを構造体で扱える
この2つをダウンロードかGit-Submoduleでプロジェクトフォルダへ
※今回、ライブラリ管理ツールは使用しません
使用するフレームワークの導入
プロジェクトに追加
フレームワークのプロジェクトを
作成しているプロジェクトへ追加
使用するフレームワークの導入
ターゲットにフレームワークを追
加
→ターゲット選択
→General選択
→Embedded Binariesの「+」
→追加したいフレームワーク選択
最近のXcodeならここへ追加する
とBuild Phasesへ適切に設定される
使用するフレームワークの導入
フレームワークの準備は完了
あとは使用するコードにimportするだけです
import Alamofire
import SwiftyJSON
2. 実装
Instagramから情報を取得
Instagramから情報を取得
Instagramから情報を取得
流れ
1. Alamofire.Requestクラスを使用してInstagram APIへリクエスト
2. レスポンスのデータをSwiftJSON.JSON構造体へ
3. Media構造体に必要な情報をJSON構造体から取得
Instagramから情報を取得
JSON
Media
Media
Media
Instagram APIApp
Swifty
JSON
Swifty
JSON
Alamofire
Instagramから情報を取得
Instagram APIApp
JSON
Media
Media
Media
Swifty
JSON
Swifty
JSON
Alamofire
Instagramから情報を取得
1. Alamofire.Requestクラスを使用してInstagram APIへリクエスト
→ requestメソッドが用意されているので、それを使用する
let urlString = "https://api.instagram.com/v1/media/popular"
let param = ["client_id": "<#CLIENT-ID#>"]
let req = request(.GET, urlString, parameters: param)
Instagramから情報を取得
Instagram APIApp
JSON
Media
Media
Media
Swifty
JSON
Swifty
JSON
Alamofire
Instagramから情報を取得
2. レスポンスのデータをSwiftJSON.JSON構造体へ
→ Requestの拡張にresponseメソッドがあるのでこれを使用する
let urlString = "https://api.instagram.com/v1/media/popular"
let param = ["client_id": "<#CLIENT-ID#>"]
let req = request(.GET, urlString, parameters: param)
req.response { (request, response, responseData, error) -> Void in
if error == nil {
if let data = responseData as? NSData {
let json = JSON(data: data)
// ……
}
}
}
SwiftyJSON.JSON
Instagramから情報を取得
Media
Media
Media
Swifty
JSON
Instagram APIApp
JSON
Swifty
JSON
Alamofire
Instagramから情報を取得
3. Media構造体に必要な情報をJSON構造体から取得
→ まず、Media構造体を作成
struct Caption {
var username: String?
var text: String?
}
struct Media {
var thumbnailURL: NSURL?
var imageURL: NSURL?
var caption: Caption?
}
Instagramから情報を取得
Media
Media
Media
Instagram APIApp
Swifty
JSON
JSON
Swifty
JSON
Alamofire
Instagramから情報を取得
3. Media構造体に必要な情報をJSON構造体から取得
→ JSON構造体からMedia構造体へ
let json = JSON(data: data)
if let array = json["data"].array {
for d in array {
var caption = Caption(
username: d["caption"]["from"]["username"].string,
text: d["caption"]["text"].string)
var media = Media(
thumbnailURL: d["images"]["thumbnail"]["url"].URL,
imageURL: d["images"]["standard_resolution"]["url"].URL,
caption: caption)
self.mediaList.append(media)
}
}
SwiftyJSONを
使わない場合
Instagramから情報を取得
req.responseJSON { (request, response, jsonData, error) -> Void in
if error == nil {
if let json = jsonData as? NSDictionary {
self.mediaList = []
if let array = json["data"] as? NSArray {
for d in array {
if let dict = d as? NSDictionary {
var caption = Caption(
username: ((dict["caption"] as? NSDictionary)?["from"] as?
NSDictionary)?["username"] as? NSString,
text: (dict["caption"] as? NSDictionary)?["text"] as NSString
)
var media = Media(
thumbnailURL: NSURL(string: ((dict["images"] as? NSDictionary)?
["thumbnail"] as? NSDictionary)?["url"] as NSString)!,
imageURL: NSURL(string: ((dict["images"] as? NSDictionary)?
["standard_resolution"] as? NSDictionary)?["url"] as NSString)!,
caption: caption
)
}}}}}}
Downcastを
多用する必要がある
まとめ
ネットワーク通信関連はAlamofire
JSONの扱いはSwiftyJSON
サンプルプロジェクトのリポジトリ:
https://github.com/kaneshin/EasyInstagramViewer-Swift
来週、社内でこれをさらに内容を盛り込んで勉強会を行います
本日、聞きたいことがありましたら、何でもお聞きください
「GitHubのシールくれ!」でも構いません

Weitere ähnliche Inhalte

Was ist angesagt?

20120413 nestakabaneworkshop
20120413 nestakabaneworkshop20120413 nestakabaneworkshop
20120413 nestakabaneworkshopYoichiro Sakurai
 
ニフティクラウド mobile backendのREST APIについて
ニフティクラウド mobile backendのREST APIについてニフティクラウド mobile backendのREST APIについて
ニフティクラウド mobile backendのREST APIについてニフクラ mobile backend
 
PhoneGap勉強会 in 熊本
PhoneGap勉強会 in 熊本PhoneGap勉強会 in 熊本
PhoneGap勉強会 in 熊本Suguru Murakami
 
できるだけUI系のライブラリを用いないアニメーションを盛り込んだサンプル実装まとめ(追加版)
できるだけUI系のライブラリを用いないアニメーションを盛り込んだサンプル実装まとめ(追加版)できるだけUI系のライブラリを用いないアニメーションを盛り込んだサンプル実装まとめ(追加版)
できるだけUI系のライブラリを用いないアニメーションを盛り込んだサンプル実装まとめ(追加版)Fumiya Sakai
 
App indexingのススメ(補足版)
App indexingのススメ(補足版)App indexingのススメ(補足版)
App indexingのススメ(補足版)consomme72
 
プッシュからデータ保存まで。アプリ開発でニフティクラウド mobile backendを使う上での良くある質問、疑問にお答えします
プッシュからデータ保存まで。アプリ開発でニフティクラウド mobile backendを使う上での良くある質問、疑問にお答えしますプッシュからデータ保存まで。アプリ開発でニフティクラウド mobile backendを使う上での良くある質問、疑問にお答えします
プッシュからデータ保存まで。アプリ開発でニフティクラウド mobile backendを使う上での良くある質問、疑問にお答えしますAtsushi Nakatsugawa
 
ニフティクラウド mobile backendを使う上での良くある質問、疑問にお答えします
ニフティクラウド mobile backendを使う上での良くある質問、疑問にお答えしますニフティクラウド mobile backendを使う上での良くある質問、疑問にお答えします
ニフティクラウド mobile backendを使う上での良くある質問、疑問にお答えしますAtsushi Nakatsugawa
 
20160120 gpsロガーアプリを作ろう
20160120 gpsロガーアプリを作ろう20160120 gpsロガーアプリを作ろう
20160120 gpsロガーアプリを作ろう史識 川原
 
スキスキIonic
スキスキIonicスキスキIonic
スキスキIonicKon Yuichi
 
App indexingでアプリの成長を加速させよう!
App indexingでアプリの成長を加速させよう!App indexingでアプリの成長を加速させよう!
App indexingでアプリの成長を加速させよう!Yukari Sakurai
 
ニフティクラウド mobile backend 北海道ハンズオン
ニフティクラウド mobile backend 北海道ハンズオンニフティクラウド mobile backend 北海道ハンズオン
ニフティクラウド mobile backend 北海道ハンズオンニフクラ mobile backend
 
ReactNative + Redux + NativeBaseでつくるサンプル実装をのぞく
ReactNative + Redux + NativeBaseでつくるサンプル実装をのぞくReactNative + Redux + NativeBaseでつくるサンプル実装をのぞく
ReactNative + Redux + NativeBaseでつくるサンプル実装をのぞくFumiya Sakai
 
ニフティクラウド
 mobile backend とIoTの良い関係
ニフティクラウド
 mobile backend とIoTの良い関係ニフティクラウド
 mobile backend とIoTの良い関係
ニフティクラウド
 mobile backend とIoTの良い関係ニフクラ mobile backend
 
Foundation for Appsでザクザク作るモックアップ
Foundation for Appsでザクザク作るモックアップFoundation for Appsでザクザク作るモックアップ
Foundation for Appsでザクザク作るモックアップKeisuke Imura
 
kintoneで実践するIoTハンズオン -90分で挑戦!kintone & AWS IoT連携-
kintoneで実践するIoTハンズオン -90分で挑戦!kintone & AWS IoT連携-kintoneで実践するIoTハンズオン -90分で挑戦!kintone & AWS IoT連携-
kintoneで実践するIoTハンズオン -90分で挑戦!kintone & AWS IoT連携-JOYZO
 

Was ist angesagt? (17)

20120413 nestakabaneworkshop
20120413 nestakabaneworkshop20120413 nestakabaneworkshop
20120413 nestakabaneworkshop
 
ニフティクラウド mobile backendのREST APIについて
ニフティクラウド mobile backendのREST APIについてニフティクラウド mobile backendのREST APIについて
ニフティクラウド mobile backendのREST APIについて
 
PhoneGap勉強会 in 熊本
PhoneGap勉強会 in 熊本PhoneGap勉強会 in 熊本
PhoneGap勉強会 in 熊本
 
できるだけUI系のライブラリを用いないアニメーションを盛り込んだサンプル実装まとめ(追加版)
できるだけUI系のライブラリを用いないアニメーションを盛り込んだサンプル実装まとめ(追加版)できるだけUI系のライブラリを用いないアニメーションを盛り込んだサンプル実装まとめ(追加版)
できるだけUI系のライブラリを用いないアニメーションを盛り込んだサンプル実装まとめ(追加版)
 
App indexingのススメ(補足版)
App indexingのススメ(補足版)App indexingのススメ(補足版)
App indexingのススメ(補足版)
 
プッシュからデータ保存まで。アプリ開発でニフティクラウド mobile backendを使う上での良くある質問、疑問にお答えします
プッシュからデータ保存まで。アプリ開発でニフティクラウド mobile backendを使う上での良くある質問、疑問にお答えしますプッシュからデータ保存まで。アプリ開発でニフティクラウド mobile backendを使う上での良くある質問、疑問にお答えします
プッシュからデータ保存まで。アプリ開発でニフティクラウド mobile backendを使う上での良くある質問、疑問にお答えします
 
ニフティクラウド mobile backendを使う上での良くある質問、疑問にお答えします
ニフティクラウド mobile backendを使う上での良くある質問、疑問にお答えしますニフティクラウド mobile backendを使う上での良くある質問、疑問にお答えします
ニフティクラウド mobile backendを使う上での良くある質問、疑問にお答えします
 
Cordova × NCMB
Cordova × NCMBCordova × NCMB
Cordova × NCMB
 
20160120 gpsロガーアプリを作ろう
20160120 gpsロガーアプリを作ろう20160120 gpsロガーアプリを作ろう
20160120 gpsロガーアプリを作ろう
 
スキスキIonic
スキスキIonicスキスキIonic
スキスキIonic
 
App indexingでアプリの成長を加速させよう!
App indexingでアプリの成長を加速させよう!App indexingでアプリの成長を加速させよう!
App indexingでアプリの成長を加速させよう!
 
ニフティクラウド mobile backend 北海道ハンズオン
ニフティクラウド mobile backend 北海道ハンズオンニフティクラウド mobile backend 北海道ハンズオン
ニフティクラウド mobile backend 北海道ハンズオン
 
IRKitの作り方
IRKitの作り方IRKitの作り方
IRKitの作り方
 
ReactNative + Redux + NativeBaseでつくるサンプル実装をのぞく
ReactNative + Redux + NativeBaseでつくるサンプル実装をのぞくReactNative + Redux + NativeBaseでつくるサンプル実装をのぞく
ReactNative + Redux + NativeBaseでつくるサンプル実装をのぞく
 
ニフティクラウド
 mobile backend とIoTの良い関係
ニフティクラウド
 mobile backend とIoTの良い関係ニフティクラウド
 mobile backend とIoTの良い関係
ニフティクラウド
 mobile backend とIoTの良い関係
 
Foundation for Appsでザクザク作るモックアップ
Foundation for Appsでザクザク作るモックアップFoundation for Appsでザクザク作るモックアップ
Foundation for Appsでザクザク作るモックアップ
 
kintoneで実践するIoTハンズオン -90分で挑戦!kintone & AWS IoT連携-
kintoneで実践するIoTハンズオン -90分で挑戦!kintone & AWS IoT連携-kintoneで実践するIoTハンズオン -90分で挑戦!kintone & AWS IoT連携-
kintoneで実践するIoTハンズオン -90分で挑戦!kintone & AWS IoT連携-
 

Ähnlich wie Swift instagram viewer

内蔵化、モバイル化に向かうDepthセンサー
内蔵化、モバイル化に向かうDepthセンサー内蔵化、モバイル化に向かうDepthセンサー
内蔵化、モバイル化に向かうDepthセンサーKaoru NAKAMURA
 
iOSアプリ開発のためのSwiftビギナーズ勉強会 第6回 @Co-Edo
iOSアプリ開発のためのSwiftビギナーズ勉強会 第6回    @Co-EdoiOSアプリ開発のためのSwiftビギナーズ勉強会 第6回    @Co-Edo
iOSアプリ開発のためのSwiftビギナーズ勉強会 第6回 @Co-EdoMegumi Otani(Czenhe)
 
チーム開発にSwiftLintを導入してみた・詳細版
チーム開発にSwiftLintを導入してみた・詳細版チーム開発にSwiftLintを導入してみた・詳細版
チーム開発にSwiftLintを導入してみた・詳細版Ikada Kaori
 
デザイナー→Webエンジニア→iOSエンジニアと渡り歩いた僕なりのSwiftとの向き合い方と生かす戦略
デザイナー→Webエンジニア→iOSエンジニアと渡り歩いた僕なりのSwiftとの向き合い方と生かす戦略デザイナー→Webエンジニア→iOSエンジニアと渡り歩いた僕なりのSwiftとの向き合い方と生かす戦略
デザイナー→Webエンジニア→iOSエンジニアと渡り歩いた僕なりのSwiftとの向き合い方と生かす戦略Fumiya Sakai
 
Abc2013 spring appinventorユーザー会
Abc2013 spring appinventorユーザー会Abc2013 spring appinventorユーザー会
Abc2013 spring appinventorユーザー会Takeaki Tada
 
iOSアプリUIとの触れ合いと歩む僕なりのSwiftの楽しみ方
iOSアプリUIとの触れ合いと歩む僕なりのSwiftの楽しみ方iOSアプリUIとの触れ合いと歩む僕なりのSwiftの楽しみ方
iOSアプリUIとの触れ合いと歩む僕なりのSwiftの楽しみ方Fumiya Sakai
 
Swiftビギナーズ勉強会 第1回 @Co-Edo
Swiftビギナーズ勉強会 第1回 @Co-EdoSwiftビギナーズ勉強会 第1回 @Co-Edo
Swiftビギナーズ勉強会 第1回 @Co-EdoMegumi Otani(Czenhe)
 
SwiftによるiOS開発再入門
SwiftによるiOS開発再入門SwiftによるiOS開発再入門
SwiftによるiOS開発再入門Tomoki Hasegawa
 
【ABC2014Spring LT】AngularJSでWEBアプリ開発
【ABC2014Spring LT】AngularJSでWEBアプリ開発【ABC2014Spring LT】AngularJSでWEBアプリ開発
【ABC2014Spring LT】AngularJSでWEBアプリ開発Hiroyuki Kusu
 
App inventorで想いを形に
App inventorで想いを形にApp inventorで想いを形に
App inventorで想いを形にTakeaki Tada
 
20120316 designerworkshoppublished
20120316 designerworkshoppublished20120316 designerworkshoppublished
20120316 designerworkshoppublishedYoichiro Sakurai
 
動画プレイヤーアプリの開発を通じて学んだ機能を実現するための要点解説
動画プレイヤーアプリの開発を通じて学んだ機能を実現するための要点解説動画プレイヤーアプリの開発を通じて学んだ機能を実現するための要点解説
動画プレイヤーアプリの開発を通じて学んだ機能を実現するための要点解説Fumiya Sakai
 
Meteor勉強会発表資料「MeteorでiOSアプリを作ろう!」
Meteor勉強会発表資料「MeteorでiOSアプリを作ろう!」Meteor勉強会発表資料「MeteorでiOSアプリを作ろう!」
Meteor勉強会発表資料「MeteorでiOSアプリを作ろう!」Nobutaka OSHIRO
 
Swiftで初アプリリリースしてみて振り返り
Swiftで初アプリリリースしてみて振り返りSwiftで初アプリリリースしてみて振り返り
Swiftで初アプリリリースしてみて振り返りHikari Yanagihara
 
RxSwiftとMVVMパターンと仲良くなる次のステップ
RxSwiftとMVVMパターンと仲良くなる次のステップRxSwiftとMVVMパターンと仲良くなる次のステップ
RxSwiftとMVVMパターンと仲良くなる次のステップFumiya Sakai
 
App Inventor 2でかんたんロボカー操縦!
App Inventor 2でかんたんロボカー操縦!App Inventor 2でかんたんロボカー操縦!
App Inventor 2でかんたんロボカー操縦!Kenichi Yoshida
 
2022年の抱負とここ数年続けてきたインプット
2022年の抱負とここ数年続けてきたインプット2022年の抱負とここ数年続けてきたインプット
2022年の抱負とここ数年続けてきたインプットFumiya Sakai
 
開発中のiOSアプリ紹介 #okamoba
開発中のiOSアプリ紹介 #okamoba開発中のiOSアプリ紹介 #okamoba
開発中のiOSアプリ紹介 #okamobaishikawa akira
 

Ähnlich wie Swift instagram viewer (20)

内蔵化、モバイル化に向かうDepthセンサー
内蔵化、モバイル化に向かうDepthセンサー内蔵化、モバイル化に向かうDepthセンサー
内蔵化、モバイル化に向かうDepthセンサー
 
DevSumi 2014[14-C-5]
DevSumi 2014[14-C-5]DevSumi 2014[14-C-5]
DevSumi 2014[14-C-5]
 
iOSアプリ開発のためのSwiftビギナーズ勉強会 第6回 @Co-Edo
iOSアプリ開発のためのSwiftビギナーズ勉強会 第6回    @Co-EdoiOSアプリ開発のためのSwiftビギナーズ勉強会 第6回    @Co-Edo
iOSアプリ開発のためのSwiftビギナーズ勉強会 第6回 @Co-Edo
 
チーム開発にSwiftLintを導入してみた・詳細版
チーム開発にSwiftLintを導入してみた・詳細版チーム開発にSwiftLintを導入してみた・詳細版
チーム開発にSwiftLintを導入してみた・詳細版
 
デザイナー→Webエンジニア→iOSエンジニアと渡り歩いた僕なりのSwiftとの向き合い方と生かす戦略
デザイナー→Webエンジニア→iOSエンジニアと渡り歩いた僕なりのSwiftとの向き合い方と生かす戦略デザイナー→Webエンジニア→iOSエンジニアと渡り歩いた僕なりのSwiftとの向き合い方と生かす戦略
デザイナー→Webエンジニア→iOSエンジニアと渡り歩いた僕なりのSwiftとの向き合い方と生かす戦略
 
Abc2013 spring appinventorユーザー会
Abc2013 spring appinventorユーザー会Abc2013 spring appinventorユーザー会
Abc2013 spring appinventorユーザー会
 
iOSアプリUIとの触れ合いと歩む僕なりのSwiftの楽しみ方
iOSアプリUIとの触れ合いと歩む僕なりのSwiftの楽しみ方iOSアプリUIとの触れ合いと歩む僕なりのSwiftの楽しみ方
iOSアプリUIとの触れ合いと歩む僕なりのSwiftの楽しみ方
 
Swiftビギナーズ勉強会 第1回 @Co-Edo
Swiftビギナーズ勉強会 第1回 @Co-EdoSwiftビギナーズ勉強会 第1回 @Co-Edo
Swiftビギナーズ勉強会 第1回 @Co-Edo
 
SwiftによるiOS開発再入門
SwiftによるiOS開発再入門SwiftによるiOS開発再入門
SwiftによるiOS開発再入門
 
【ABC2014Spring LT】AngularJSでWEBアプリ開発
【ABC2014Spring LT】AngularJSでWEBアプリ開発【ABC2014Spring LT】AngularJSでWEBアプリ開発
【ABC2014Spring LT】AngularJSでWEBアプリ開発
 
App inventorで想いを形に
App inventorで想いを形にApp inventorで想いを形に
App inventorで想いを形に
 
20120316 designerworkshoppublished
20120316 designerworkshoppublished20120316 designerworkshoppublished
20120316 designerworkshoppublished
 
動画プレイヤーアプリの開発を通じて学んだ機能を実現するための要点解説
動画プレイヤーアプリの開発を通じて学んだ機能を実現するための要点解説動画プレイヤーアプリの開発を通じて学んだ機能を実現するための要点解説
動画プレイヤーアプリの開発を通じて学んだ機能を実現するための要点解説
 
Meteor勉強会発表資料「MeteorでiOSアプリを作ろう!」
Meteor勉強会発表資料「MeteorでiOSアプリを作ろう!」Meteor勉強会発表資料「MeteorでiOSアプリを作ろう!」
Meteor勉強会発表資料「MeteorでiOSアプリを作ろう!」
 
Swiftで初アプリリリースしてみて振り返り
Swiftで初アプリリリースしてみて振り返りSwiftで初アプリリリースしてみて振り返り
Swiftで初アプリリリースしてみて振り返り
 
OpenCV on mobile
OpenCV on mobileOpenCV on mobile
OpenCV on mobile
 
RxSwiftとMVVMパターンと仲良くなる次のステップ
RxSwiftとMVVMパターンと仲良くなる次のステップRxSwiftとMVVMパターンと仲良くなる次のステップ
RxSwiftとMVVMパターンと仲良くなる次のステップ
 
App Inventor 2でかんたんロボカー操縦!
App Inventor 2でかんたんロボカー操縦!App Inventor 2でかんたんロボカー操縦!
App Inventor 2でかんたんロボカー操縦!
 
2022年の抱負とここ数年続けてきたインプット
2022年の抱負とここ数年続けてきたインプット2022年の抱負とここ数年続けてきたインプット
2022年の抱負とここ数年続けてきたインプット
 
開発中のiOSアプリ紹介 #okamoba
開発中のiOSアプリ紹介 #okamoba開発中のiOSアプリ紹介 #okamoba
開発中のiOSアプリ紹介 #okamoba
 

Swift instagram viewer