2012年2月27日月曜日

アプリのテンプレートを作ってみる

オレオレテンプレートがらみの話です。
ちょっとでも開発を楽にする為に
「テンプレートでも作っとこうかなぁ」

なんて事を言い出して、作り始めたら結構はまって
逆に大変な労力を費やしてしまう。。。

そんなパターンに僕もハマりつつありますが、 
そのまま前進することにします。 

まずは必要そうな機能をリストアップ。


  • ナビゲーションで画面遷移
  • ローディングビュー
  • デバッグログ
  • ローカライズ(Localizable.strings / InfoPlist.Strings)
  • モデル実装(モデルオブジェクト,モデルリストクラス,データマネージャークラス)
  • リクエストマネージャークラス(通信の仕組み)
  • FNCクラス(各種情報の定義、ユーザデフォルト管理、C言語化した関数)
  • SNS連携
  • plistにドキュメント登録
  • URLスキーム
  • アプリ内課金View
  • アプリ紹介などのWebView
  • jsonライブラリ
  • アドモブSDK
  • サウンド再生関係
  • メール送信機能
  • 設定画面
  • OpenGLにてobjファイルを回転させるView
  • TableViewパーツとり用クラス
  • ViewControllerのお決まりテンプレート

NavigationControllerにて画面遷移するようにしておく

俺俺テンプレート第一弾ってことで、まずは画面遷移を作っていきたいと思います。

AddSubViewパターンとかmodalViewパターンはいつでも使えるので、ここではやらない。
NavigationControllerを使ったパターンを実装していきます。



まずはsingleViewのテンプレートにて新しいプロジェクトを作る

1、NavigationControllerによる画面の遷移を実装する。
AppDelegate.h
rootControllerプロパティを追加

#import <UIKit/UIKit.h>

@class ViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (nonatomic,retain) UINavigationController* rootController;
@property (strong, nonatomic) ViewController *viewController;

@end



AppDelegate.m
起動時に呼ばれるメソッドを少しいじる

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    // Override point for customization after application launch.
    self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController" bundle:nil] autorelease];
   
    //起点となるViewControllerを設定
    rootController = [[UINavigationController alloc]initWithRootViewController:_viewController];//追加
   
    self.window.rootViewController = self.rootController;//変更
    [self.window makeKeyAndVisible];
    return YES;
}




#動作を確認の為の準備
適当なViewControllerをプロジェクト上に作る。ここではSecondViewControllerとする。


ViewControllerに #importする。
ViewControllerに適当なボタンを作ってIBActionのメソッドを実行できるようにする。

メソッドの中は下記の通り

-(IBAction)buttonDidPush:(id)sender{
    SecondViewController* viewController =
    [[SecondViewController alloc]initWithNibName:@"SecondViewController" bundle:nil];
    [self.navigationController pushViewController:viewController animated:YES];
    [viewController release];
}



アプリを起動してボタンを押したら画面が遷移したら成功だ。
 ちゃんちゃん


2012年2月14日火曜日

Plistから配列にする


アプリ上で使う要素を配列にする時にこんなコードは書いてないだろうか?

  NSMutableArray* array = [NSMutableArray alloc]init];
      [array addObject:@"Source1"];
      [array addObject:@"Source2"];
      [array addObject:@"Source3"];
            -----続く---------

もちろんこれでも間違いじゃないけれど、要素が100個くらいあると
しんどいしコードが長くなる。

そんな時はPlistを使って配列に起こすようにすると色々と楽だ

よくあるサンプルだと下記のようにやっているけれど、Xcode4.xにて作ったplistはこれじゃ読込めない。 試しに実行してみるとarrayWithContentsOfFileの戻り値がnilにて返ってくるはずだ。
    NSMutableArray* array = [[NSMutableArray alloc]init];
    NSBundle* bundle = [NSBundle mainBundle];
    NSString* path = [bundle pathForResource:@"list" ofType:@"plist"];
    NSArray* list = [NSArray arrayWithContentsOfFile:path];   
   
    for(NSString* str in list){
        [array addObject:str];
    } 

  
Plistがきちんとした形式になっていないとnilが返ってくる仕様だが、xcode上で作ったplistが読込めない。

Plistを右クリックしてSourceにて開いてみると。。。

一番頭のタグが<dict>になっている。

 下はXcode3.xにて作ったPlist。

  
頭のタグが<array>になってますね。

要するにXMLの階層構造がXcode4から変わっているってことです。
なので、 dictionaryWithContentsOfFile を使ってNSDictionaryを生成するのが正解。
まず、keyをきちんととれるように下記のようにplistを作りかえます。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Root</key>
    <array>
        <string>要素1</string>
        <string>要素2</string>
    </array>
</dict>
</plist>



取得するコードは下記の通り。
一度 NSDictionaryにしてからobjectForKeyにて配列を取得するんですね。

    NSBundle* bundle = [NSBundle mainBundle];
    NSString* path = [bundle pathForResource:@"list" ofType:@"plist"];
    NSDictionary* dic = [NSDictionary dictionaryWithContentsOfFile:path];
    NSArray *items =[dic objectForKey:@"Root"];
   
    for(NSString* str in items){
        [array addObject:str];
    }

plistの作りようでは、配列の中にdictionaryを入れてそこからモデルオブジェクトを格納した配列にするなんてこともできちゃいます♪