yamashiro0110の日記

yamashiro0110の日記です。おもにIT技術のメモを綴っていきます(^o^)

GHUnitのめも


GHUnitでiOSアプリケーションのテストを書こうと思い、その時のφ(`д´)メモメモ...

f:id:yamashiro0110:20140925000040p:plain


環境


インストール

公式の通りに進めたらできました(^o^)

ただし、gemとCocoapodsが必要

  • gemでGHUnitをインストール
sudo gem install ghunit
  • プロジェクトのディレクトリに移動する
    • .xcodeprojが存在するディレクトリ
cd $PROJECT_DIR
  • Testターゲットをプロジェクトに追加
    • -nにはプロジェクト名を渡す
ghunit install -n test
  • PodfileにGHUnitを追加
platform :ios, '6.0'

target :Tests do
    pod 'GHUnit', '~> 0.5.9'
end
  • GHUnitをプロジェクトに追加
pod install
  • .xcworkspaceを開く
    • すると、ターゲットにTestsが追加されてる!

f:id:yamashiro0110:20140924231647p:plain


実行

  • 実行するターゲットをTestsに切り替える

    • 左上の停止ボタンのとなりにあるやつ
  • 実行する!

    • Product -> Run

f:id:yamashiro0110:20140924231836p:plain

今回はiOSシミュレータで実行してみた

右上のRunをタッチすると、テストが実行される


ここまで、インストールと起動は何事もなく終えることができたんですが、 自分で作成したクラスをテストしようとするとビルドエラーがでる(-_-;)

どうやらターゲット毎にコンパイルするソースを指定しないと行けないらしい。。。

方法1

  • プロジェクトの設定画面 > Testsターゲットを選択 > Build Phasesタブを選択 > Compile Sourceを選択
  • Testsターゲット内でコンパイルしたいソースを追加する

方法2

  • テスト対象のソースを選択 > File Inspector > Target Membership > Testsターゲットにチェックを入れる
    • この方法だと.mファイルしかチェックを入れることができない

.mファイルを参照できるんだったら、ヘッダファイルもimportされるから.hはチェック入れる必要なくね?ってことなんですかね(-_-;) 方法1の場合だと.hコンパイルの対象に含めることができたんですが、違いは何なんだろう。。。

ちなみに、方法1と方法2でターゲットのコンパイル対象に含める操作は、 同期されてるようでどちらかの方法で追加した場合はCompile SourceTarget Membershipに追加され、 どちらかの方法で削除した場合は、コンパイル対象から外されてた

別ターゲットの全ファイルをコンパイル対象にする、 ターゲットの設定が有りそうなものだけどわからない。。。

Xcode6にしたらFlatUIKitでエラーがでた


Xcode6にバージョンアップされてて、ビルドするとエラーがでる

FlatUIKitを使ってたので、そこでエラーが出てた

Githubリポジトリ見ると、早速修正されてる!


CocoapodsでUpdateしたら、ビルドエラー出なくなった(^o^)

pod update

QuickDialogの使い方めも


iOSアプリの開発で設定画面を作成するライブラリを使った

設定画面の作り方は、いくつか参考になるページがあったんだけど ボタンがタップされたときにメソッドを実行する方法とかが、 あまり見当たらなかったのでその辺をφ(`д´)メモメモ...


ライブラリのインストール

CocoaPods使います

  • Podfils
platform :ios, "7.1"
pod 'QuickDialog', '~> 1.0'
pod install

実装

起動時に表示されるViewController

  • TestViewController.h
#import <UIKit/UIKit.h>
#import <QuickDialog/QuickDialog.h>

/**
 * QuickDialogControllerを継承する
 */
@interface TestViewController : QuickDialogController

/**
 *  QuickDialogのRootElementを取得する
 *  @return
 */
+ (QRootElement *)getQRootElement;

@end
  • TestViewController.m
#import "TestViewController.h"

@interface TestViewController ()

@end

@implementation TestViewController

/**
 *  初期化
 *  親クラスのQuickDialogControllerの初期化メソッドをオーバーライド
 */
- (QuickDialogController *)initWithRoot:(QRootElement *)rootElement
{
    if (self = [super initWithRoot:rootElement]) {
        // rootElementのViewControllerを自分自信に設定する
        self.root.controller = self;

        // ボタンのインスタンスを取得
        QElement *button = [self.root elementWithKey:@"login_button"];

        // タップ時に実行されるメソッドを設定する
        button.controllerAction = @"clickButton";
    }

    return self;
}

/**
 *  ボタンがタップされたとき
 */
- (void)clickButton
{
    NSLog(@"ボタンがタップされました");
}

+ (QRootElement *)getQRootElement
{
    // root
    QRootElement *root = [[QRootElement alloc] init];
    root.title = @"設定";
    root.grouped = YES;

    // section
    QSection *section = [[QSection alloc] init];
    section.title = @"Section 1";

    // label
    QLabelElement *label = [[QLabelElement alloc] initWithTitle:@"hello" Value:@"World"];

    // button
    QButtonElement *button = [[QButtonElement alloc] initWithTitle:@"login"];
    [button setKey:@"login_button"];

    [section addElement:label];
    [section addElement:button];
    [root addSection:section];
    return root;
}

@end
  • TestAppDelegate.h
    • 修正なし
#import <UIKit/UIKit.h>

@interface TestAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end
  • TestAppDelegate.m
    • 必要なとこだけ抜粋
#import "TestAppDelegate.h"

// ViewControllerをimport
#import "TestViewController.h"

@interface TestAppDelegate()

@property (nonatomic) TestViewController *viewController;

@end

@implementation TestAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    // `QuickDialogController`を継承したViewControllerを初期化
    // 引数の`initWithRoot:`には、`TestViewController`のクラスメソッドである`getQRootElement`の実行結果を渡す
    self.viewController = [[TestViewController alloc] initWithRoot:[TestViewController getQRootElement]];

    // RootViewControllerに設定
    self.window.rootViewController = self.viewController;

    [self.window makeKeyAndVisible];
    return YES;
}

@end

気になったこと

初期化時にボタンのインスタンスを取得して、実行するメソッドを設定したのだけれども プロパティの型はNSStringだったので、どうやって変換するのかがわからなかった

ソースを追ってみると、↓のところぽい

  • QElement.m
- (void)performAction
{
    if (_onSelected!= nil)
        _onSelected();

    if (self.controllerAction!=NULL){
        SEL selector = NSSelectorFromString(self.controllerAction);
        if ([_controller respondsToSelector:selector]) {
            objc_msgSend(_controller,selector, self);
        }  else {
            NSLog(@"No method '%@' was found on controller %@", self.controllerAction, [_controller class]);
        }
    }
}

プロパティのcontrollerActionnilでなければSelectorに変換して、実装されていれば実行するのか。

こんなの出来るって初めて知った・・・^^;


設定画面がこんなに簡単に(^o^)

iOSアプリの開発って、もうOSSライブラリなしじゃツライっす(-_-;)

iOSオープンソースライブラリ徹底活用

iOSオープンソースライブラリ徹底活用

Googleドライブが超便利だと思った


最近、久しぶりにPC版のGoogleドライブ開いたら便利になったと感じた(^o^)


新しい Google ドライブ


  • アイコンのサイズが変わった

    • フォルダとファイルのサイズが別々になって見分けがつきやすい
  • ドラッグ&ドロップでファイルを追加できるように

  • 外部アプリと連携できるように

    • 今回のメイン!
    • これは以前から??ちょっとわからない^^;

f:id:yamashiro0110:20140911023255p:plain


Markdownをちょくちょく使うのですが、 DropBoxとか今までつかってたクラウドストレージだと オンラインで編集できないとかがあってちょっとめんどくさかった。。

だけど、Googleドライブ+StackEdit使うとオンラインで編集までできてしまうので感動してしまった。 #使ってるブラウザはGoogleChrome

使い方

  • Googleドライブを開く
  • 右クリックでメニューを開く
  • 新規ファイル > +アプリを追加
    • すでに追加されてる場合は飛ばす
  • "stackedit"で検索。追加する
  • するとStackEdit上でファイルが編集可能に!
    • 初回はGoogleドライブと接続するか確認するための画面が表示されるのでOKする

f:id:yamashiro0110:20140911023228p:plain


Written with StackEdit.

UIViewControllerでナビゲーションバーを表示する


UINavigationControllerでナビゲーションバーを表示するときφ(`д´)メモメモ...

特に難しいことないけど、(実装以外の部分で)ハマってしまったので残しておく・・・


やりたいこと

アプリ起動時に表示するビューでナビゲーションバーを表示したい

StoryBoardやInterfaceBuilderは使わずに、コードのみで

環境


実装

必要なとこのみ記述してます^^;

ViewControllerを作成

  • TestViewController.h
#import <UIKit/UIKit.h>

@interface TestViewController : UIViewController

@end
  • TestViewController.m
#import "TestViewController.h"

@implementation TestViewController

- (id)init
{
    self = [super init];

    if (self) {
        self.title = @"TestViewController";
    }

    return self;
}

- (void)viewWillAppear:(BOOL)animated
{
    // ナビゲーションバーを表示する
    [self.navigationController setNavigationBarHidden:NO animated:animated];

    // ツールバーの表示
    [self.navigationController setToolbarHidden:NO];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
}
@end

アプリケーション初期化時の処理を修正

  • AppDelegate.h
@interface AppDelegate : UIResponder <UIApplicationDelegate>

@end
  • AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    TestViewController *testViewController = [[TestViewController alloc] init];
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:testViewController];
    self.window.rootViewController = navigationController;
    [self.window makeKeyAndVisible];
    return YES;
}

実行

iOSシミュレータで確認すると、表示されてないッ!!

と思ったらシミュレータの表示サイズが100%になってて隠れているだけだった・・・orz

75%に設定するとちゃんと表示された(^o^)

iPhoneプログラミングUIKit詳解リファレンス

iPhoneプログラミングUIKit詳解リファレンス

CocoaPodsの使い方


Cocoa Podsの使い方めも

iOSライブラリ管理の神ツール(^o^)


環境

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.9.4
BuildVersion:   13E28

Rubyが必要

$ ruby -version
ruby 2.0.0p451 (2014-02-24 revision 45167) [universal.x86_64-darwin13]

インストール

$ sudo gem install cocoapods

ライブラリ情報のセットアップ

$ pod setup

使ってみる

  • iOSプロジェクトTOPのディレクトリに移動

    • .xcodeprojが存在するディレクトリ
  • Podfileを作る

    • ファイル名は"Podfile"
platform :ios, "7.1"
pod 'AFNetworking'
pod 'CocoaLumberjack'
  • ライブラリのインストール実行
pod install
  • 実行後に.xcworkspaceのファイルをXcodeで開くと、ライブラリが使える状態に!!

すげー、プロジェクトのライブラリをファイルで管理できるようになった~


参考:http://www.atmarkit.co.jp/ait/articles/1403/08/news008.html

iOS開発におけるパターンによるオートマティズムを読んだ。

Objective-Cがある程度かけるようになって、 Cocoa touch(UIKit,Foundation)もある程度知ってるけど、 自分の実装が正しいのか自信が持てない人たち向けらしい。

UIViewControlerのどのメソッドでどんな処理を実装したらいいのか、 メモリ管理の実装はどうするといいのかなどが わかりやすく簡潔に書かれていて、とても参考になった。

ARCでのメモリ管理については、書かれてないのでそれ以前の方法について解説されています

この本を先に読んでたら、あの時もっとマシなコード書けたかなと反省(-_-;)

iOS開発におけるパターンによるオートマティズム

iOS開発におけるパターンによるオートマティズム