サーバーからiOSアプリを変更する
-
Upload
toyship -
Category
Engineering
-
view
4.446 -
download
0
description
Transcript of サーバーからiOSアプリを変更する
サーバーからiOSアプリを変更する
2014/4/26@TachibanaKaoru
自己紹介
• @TachibanaKaoru
• 渋谷のgenesixで働くiOSエンジニアです
• Blog : http://www.toyship.org/
サーバーからiOSアプリを変更する
• 一回リリースしたiOSアプリをサーバーサイドで変更したい
• できるだけ頻繁にアプリの仕様やUIを変更したい
• ユーザーによって表示するUIを変えて、A/Bテストを行いたい
MVC in server/local
Model Controller
View
Native Code (Objc..)
Server API
Storyboard or Xib or Code
UIWebViewを使う
• よく使われるのがUIWebViewで画面を作成し、表示内容をすべてサーバーサイドで作成する
• Model/View/Controlの処理の大部分がサーバー側となるため迅速な変更ができるが、いろいろと弊害がある
UIWebViewによる弊害
• 全体的なパフォーマンス
• 特にTableViewではUIKitのCellのresuseの仕組みが使えないため、操作が遅くなる
• 多量のデータハンドリングに問題あり
• デバイス固有の機能を使うには制限がある
UIWebViewを使わずに動的に変更するには
• 簡単な例としては、UIに表示する画像の一部をサーバーサイドからもってくる方法もありますが…
• 実施例:アプリ起動時の「ようこそ画面」をサーバーサイドから取得し、ABテストを実施
• ただ、この仕組みをコードに記述する必要があるため、コードに仕組みをいれこまないような形にしたい
• もっと大幅な変更を動的に行いたい
Storyboardをネットワークからダウンロード
• @tokoromさんの案
• http://www.slideshare.net/yutatokoro7/potatotips1
• StoryboardをNSBundleに含めてzipにして、サーバーに置いておく
• アプリがダウンロードしてunzipしてStoryboardを作成する
MVC in server/local
Controller
View
Server API Model
Storyboardをダウンロード することで、この部分が サーバーで更新できるよう になる
Storyboard or Xib
Native Code (Objc..)
Storyboardをネットワークからダウンロード
• Storyboardが変更可能な場合、画面レイアウトなどの要素は動的に変更変更することが可能になる
• しかし、ModelとViewの両方をサーバーサイドにしても、Modelを変更してViewに反映させるためには、Controllerの変更が必要になる
例えば……
今まで表示していなかったTweetのFavorite数を タイムライン上に表示するようにしよう!
ここのTweetボタンのアイコンの画像を変更しよう
OK!
NG!
Modelの変更に対して、Controlを変更せずに、サーバーサイドだけでで対応させたい!
対応例
• 今まで別のものを表示していた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" } },
独自UITableViewControllerの設定
• この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”;
独自UITableViewControllerの設定
StoryboardのUser Defined Runtime Attributesを使い、ソースコード 上でなく、StoryboardでstrEndPoint、strField の値を入力します。
独自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の値
独自UILabelの設定
StoryboardでUIEntityLabelのstrEntityプロパティに、そのラベルに表示したい要素名を指定する
@interface UIEntityLabel : UILabel @property(nonatomic,strong)NSString* strEntity; !@end
独自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; }
実行結果
Storyboardで指定したEndpointのAPIをよび、 Storyboardで指定した要素を表示することが できる
MVC in server/local
Controller
View
storyboard from server
ModelServer API
Native Code (Objc..)
UIViewControllerの場合
• 基底クラスがUIViewControllerの場合にも、UITableViewControllerと同様に独自ラベル(UIEntityLabel)とUser Defined Runtime Attributeの仕組みを使えばなことが可能です。
まとめ
• StoryboardとUser Defined Runtime Attributeをうまく使うと、サーバーサイドだけでModel/Viewの大幅な変更ができるようになります。