サーバーからiOSアプリを変更する

23
サーバーからiOSアプリを変更する 2014/4/26 @TachibanaKaoru

description

2014/4/26のyidev@恵比寿で発表したスライドです。

Transcript of サーバーからiOSアプリを変更する

Page 1: サーバーからiOSアプリを変更する

サーバーからiOSアプリを変更する

2014/4/26@TachibanaKaoru

Page 2: サーバーからiOSアプリを変更する

自己紹介

• @TachibanaKaoru

• 渋谷のgenesixで働くiOSエンジニアです

• Blog : http://www.toyship.org/

Page 3: サーバーからiOSアプリを変更する

サーバーからiOSアプリを変更する

• 一回リリースしたiOSアプリをサーバーサイドで変更したい

• できるだけ頻繁にアプリの仕様やUIを変更したい

• ユーザーによって表示するUIを変えて、A/Bテストを行いたい

Page 4: サーバーからiOSアプリを変更する

MVC in server/local

Model Controller

View

Native Code (Objc..)

Server API

Storyboard or Xib or Code

Page 5: サーバーからiOSアプリを変更する

UIWebViewを使う

• よく使われるのがUIWebViewで画面を作成し、表示内容をすべてサーバーサイドで作成する

• Model/View/Controlの処理の大部分がサーバー側となるため迅速な変更ができるが、いろいろと弊害がある

Page 6: サーバーからiOSアプリを変更する

UIWebViewによる弊害

• 全体的なパフォーマンス

• 特にTableViewではUIKitのCellのresuseの仕組みが使えないため、操作が遅くなる

• 多量のデータハンドリングに問題あり

• デバイス固有の機能を使うには制限がある

Page 7: サーバーからiOSアプリを変更する

UIWebViewを使わずに動的に変更するには

• 簡単な例としては、UIに表示する画像の一部をサーバーサイドからもってくる方法もありますが…

• 実施例:アプリ起動時の「ようこそ画面」をサーバーサイドから取得し、ABテストを実施

• ただ、この仕組みをコードに記述する必要があるため、コードに仕組みをいれこまないような形にしたい

• もっと大幅な変更を動的に行いたい

Page 8: サーバーからiOSアプリを変更する

Storyboardをネットワークからダウンロード

• @tokoromさんの案

• http://www.slideshare.net/yutatokoro7/potatotips1

• StoryboardをNSBundleに含めてzipにして、サーバーに置いておく

• アプリがダウンロードしてunzipしてStoryboardを作成する

Page 9: サーバーからiOSアプリを変更する

MVC in server/local

Controller

View

Server API Model

Storyboardをダウンロード することで、この部分が サーバーで更新できるよう になる

Storyboard or Xib

Native Code (Objc..)

Page 10: サーバーからiOSアプリを変更する

Storyboardをネットワークからダウンロード

• Storyboardが変更可能な場合、画面レイアウトなどの要素は動的に変更変更することが可能になる

• しかし、ModelとViewの両方をサーバーサイドにしても、Modelを変更してViewに反映させるためには、Controllerの変更が必要になる

Page 11: サーバーからiOSアプリを変更する

例えば……

今まで表示していなかったTweetのFavorite数を タイムライン上に表示するようにしよう!

ここのTweetボタンのアイコンの画像を変更しよう

OK!

NG!

Page 12: サーバーからiOSアプリを変更する

Modelの変更に対して、Controlを変更せずに、サーバーサイドだけでで対応させたい!

Page 13: サーバーからiOSアプリを変更する

対応例

• 今まで別のものを表示していたTableViewに、このjsonのなかの特定の要素を表示するという変更に、Storyboardだけで対応してみたいと思います。

• http://itunes.apple.com/jp/rss/topfreeapplications/limit=20/json

{ "feed": { "author": { "name": { "label": "iTunes Store" }, "uri": { "label": "http://www.apple.com/jp/itunes/" } }, "entry": [ { "category": { "attributes": { "im:id": "6016", "label": "エンターテインメント", "scheme": "https://itunes.apple.com/jp/genre/ios-entateinmento/id6016?mt=8&uo=2", "term": "Entertainment" } },

Page 14: サーバーからiOSアプリを変更する

独自UITableViewControllerの設定

Page 15: サーバーからiOSアプリを変更する

• このUITableViewControllerクラスは、CallすべきAPIのEndPointのURL、表示すべきJsonの要素名をpropertyとして持っています。

!

• 通常、このpropertyの代入は、ソースコード上で行っていますが……。

独自UITableViewControllerの設定

@interface CommonListViewController : UITableViewController @property (nonatomic,strong)NSString* strField; @property (nonatomic,strong)NSString* strEndPoint; @property (nonatomic,strong)NSArray* items; @end

self.EndPoint = @“http://itunes.apple.com/jp/rss/topfreeapplications/limit=20/json”; self.strField = @“feed.entry”;

Page 16: サーバーからiOSアプリを変更する

独自UITableViewControllerの設定

StoryboardのUser Defined Runtime Attributesを使い、ソースコード 上でなく、StoryboardでstrEndPoint、strField の値を入力します。

Page 17: サーバーからiOSアプリを変更する

独自UITableViewControllerの設定

- (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; ! NSURL *url = [NSURL URLWithString:self.strEndPoint]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; self.items = [jsonDictionary valueForKeyPath:self.strField]; [self.tableView reloadData]; }]; }

Storyboardで設定されたstrEndPointの値

Storyboardで設定されたstrFieldの値

Page 18: サーバーからiOSアプリを変更する

独自UILabelの設定

StoryboardでUIEntityLabelのstrEntityプロパティに、そのラベルに表示したい要素名を指定する

@interface UIEntityLabel : UILabel @property(nonatomic,strong)NSString* strEntity; !@end

Page 19: サーバーからiOSアプリを変更する

独自UILabelの設定- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //(いつもの処理) NSDictionary* dict = [self.items objectAtIndex:indexPath.row]; NSArray* cellSubviews = cell.contentView.subviews; for( UIView* control in cellSubviews){ if( [[[control class] description] isEqualToString:@"UIEntityLabel"]){ UIEntityLabel* label = (UIEntityLabel*)control; NSString* strData = [dict valueForKeyPath:label.strEntity]; label.text = strData; ! } } return cell; }

Page 20: サーバーからiOSアプリを変更する

実行結果

Storyboardで指定したEndpointのAPIをよび、 Storyboardで指定した要素を表示することが できる

Page 21: サーバーからiOSアプリを変更する

MVC in server/local

Controller

View

storyboard from server

ModelServer API

Native Code (Objc..)

Page 22: サーバーからiOSアプリを変更する

UIViewControllerの場合

• 基底クラスがUIViewControllerの場合にも、UITableViewControllerと同様に独自ラベル(UIEntityLabel)とUser Defined Runtime Attributeの仕組みを使えばなことが可能です。

Page 23: サーバーからiOSアプリを変更する

まとめ

• StoryboardとUser Defined Runtime Attributeをうまく使うと、サーバーサイドだけでModel/Viewの大幅な変更ができるようになります。