Archive for the ‘objective-c’ Category

    はてなブックマーク - オレオレ framework の作り方
    このエントリーをはてなブックマークに追加

    Fusic 河野です。

    GW 始まりましたね。みなさん、楽しんでますか?
    来る5月19日(土)に Future Sync vol.2 というイベントをします。
    これは、プログラマー・デザイナー・クリエイター・企画・マーケティング・学生など、
    様々な人たちが IT の未来を同期するために開催される、トークイベントです。
    詳細は、ココとかココにも書いてますので、ご興味を持たれた方が居られましたら
    ぜひご参加をお願い致します!
    (学生さんのみなさん、無料ですよ~)

    さて、本題。
    今回は iphone での framework の作り方についてです。
    iphone アプリをいくつか作成していると色々と独自のライブラリなどが
    溜まってくるかと思います。
    それらのオレオレライブラリを framework としてまとめ、今後の開発にも
    直ぐに活用できるようにしておけば、きっと楽になるのではないでしょうか。
    それでは早速いきましょー!!
    (今回は実際のコードではなく、画像が多いです。ご容赦を!)

    準備

     今回は kstenerud さんの iOS-Universal-Framework というツールを使用します。
     便利です。オススメです!
     リンク先の README を見てたら大体の事は分かると思います。

     git clone で落としてきてインストールの作業を行います。

    $ git clone git://github.com/kstenerud/iOS-Universal-Framework.git
    $ cd iOS-Universal-Framework/Real Framework
    $ ./install.sh

     因みにアンインストールする場合には、同ディレクトリにある uninstall.sh を叩きます。

    フレームワーク側の作成

     
     ”準備”を行った後、xcode を開くと新しく “Static iOS Framework”という
     テンプレートが追加されてますので、それを選んで新規にプロジェクトを作成します。

     
     今回は “HelloWorldFramework” という名前で作成しました。
     ARC などのオプションはお好みで設定してください。
     (サンプルでは ARC をオンにしてます)

     
     プロジェクト内に “HelloWorld” というクラスを作成します。

     それぞれのファイルには以下のコードを書いておきます。
     UIAlertView で “hello, world!” と表示する簡単なものです。

    HelloWorld.h

    #import <Foundation/Foundation.h>
     
    @interface HelloWorld : NSObject
     
    - (void)sayHelloWorld;
     
    @end

    HelloWorld.m

    #import "HelloWorld.h"
     
    #import <UIKit/UIKit.h>
     
    @implementation HelloWorld
     
    - (void)sayHelloWorld
    {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"alert!"
                                                            message:@"hello, world!" 
                                                           delegate:nil 
                                                  cancelButtonTitle:@"OK" 
                                                  otherButtonTitles:nil];
        [alertView show];    
    }
     
    @end

     
     ビルドが成功すると “Product” のところに “HelloWorldFramework.framework” が
     作成されてます。
     そして、その “HelloWorldFramework.framework” を選択し、右クリックして、
     Finder で表示します。

     
     
     Finder で表示したところです。
     ここにある “HelloWorldFramework.framework” というディレクトリが
     今回使うフレームワークです。
     これをどこかわかりディレクトリにコピーしておきます。

     お疲れ様でした!
     これで、一旦はオレオレフレームワークの作成が終わりました。
     ツールのおかげでほんとに楽ですよね!!

    アプリケーション側での利用

     
     アプリにて、先程の “HelloWorldFramework.framework” を
     組み込んでいきます。
     適当に新規プロジェクトでアプリを作成します。
     ”UseFramework” としています。

     
     
     
     新規作成したアプリに作成したフレームワークを追加します。
     解りやすいところにコピーした “HelloWorldFramework.framework” を
     選択して追加します。

     
     アプリにボタンを追加して、関数を追加してボタンが押下されると
     関数が呼ばれるようにします。
     今回、say というメソッドを作成し呼び出すようにしました。

    #import "HelloWorldFramework/HelloWorld.h"
     
    ...(中略)
     
    - (IBAction)say:(id)sender
    {
        HelloWorld *hello = [[HelloWorld alloc] init];
        [hello sayHelloWorld];
    }

     注意点として、フレームワーク内のヘッダを呼び出す場合は、
     #import “HelloWorldFramework/HelloWorld.h” のように
     ”フレームワーク名/呼び出したいヘッダ”
     のように記載します。

     
     プロジェクトを実行し、ボタンを押下すると無事に
     ”hello, world!” が表示されました!!

    おわりに

     ツールのおかげでほんとに楽だったと思います。
     実際に自分で1から作ろうとするとユニバーサル化含め
     メンドクサイ事がいっぱいなのですが、ほんとに楽です。
     これで気軽にフレームワークが作成できますね!

     ぜひ、みなさんの開発ライフにご活用ください!

      はてなブックマーク - Xcodeを(あまり)使わないでiPhoneアプリの開発
      このエントリーをはてなブックマークに追加

      こんにちは、そしてはじめての人ははじめまして。
      たぶん、Fusic社員の中野です。

      Fusic Advent Calendarということで、何か記事を書かなければいけなくなりました。他の人の記事はなんか難しそうな記事ばかりなので、軽くプレッシャーです。

      さて、iPhoneアプリを作っている人は、おそらく”Xcode”を使っている人がほとんどではないかなと思っています。弊社でも数人iPhoneアプリを作っている技術者がいますが、ほぼXcodeを使用しています。

      XcodeといえばMacについてくる無料の開発環境でとても便利なツールなんですが、「Emacs・Vimで開発したい!」もしくは「Xcodeを立ち上げるのもめんどくさい!」という人もいるかと思います。そこでそんな人たちのために、Xcodeを(あまり)使用せずに行うiPhoneアプリの開発のTipsをご紹介できたらとおもいます。

      検証環境

      • Mac OSX 10.5.8
      • iPhone Simulator SDK 3.0

      ※ OSのバージョンや環境によって違います

      iPhoneアプリ作成

      まず、今回の例として使用するiPhoneアプリの雛形をXcodeで作成します。Xcodeを起動して、「ファイル」->「新規プロジェクト」で「新規プロジェクト」ダイアログが表示されます。そのダイアログで「View-based Application」を選択してプロジェクトをどっかに保存してください。作成すると、以下のようにiPhone用テンプレートが作成されると思います。

      作成したら、メニューの「ビルド」->「ビルド」を選択して、一度、iPhoneアプリを作成します。

      iphonesimを作成

      次に、コマンドラインからiPhoneシミュレータを立ち上げるために、ここからソースコードをダウンロードして、”iphonesim”というツールを作成します。(ダウンロードして解凍すると、Xcodeのプロジェクトが入ってますので、お使いの環境にあわせてビルドをしてください。)

      コマンドラインからiPhoneシミュレータの起動

      ビルドしてできたiphonesimを利用し、はじめに作成したテスト用のiPhoneアプリをiPhoneシミュレータ内で起動させます。

      # iphoneアプリのプロジェクトのパスが"~/Desktop/Fac/Test"だった場合
      $ pwd
      /Users/nakano/Downloads/iphonesim/build/Debug
      $ ./iphonesim launch ~/Desktop/Fac/Test/build/Debug-iphonesimulator/Test.app
      [DEBUG] App Spec: 〜
      [DEBUG] SDK Root: 〜
      [DEBUG] Session started

      何もエラーがなければ、iPhoneシミュレータが立ち上がりiPhoneアプリが表示されると思います。

      いろいろ

      Q: Xcodeしか使ってないじゃん!ソースコードを編集してビルドするときはどうすんのよ?
      A:xcodebuildというコマンドでビルドできます。

      $ xcodebuild -configuration Debug -sdk iphonesimulator3.0
      Q:デバッグは?
      A:iPhoneアプリのPIDが取れますので、gdb –pid=PIDでデバッグできます。iphonesim+gdbを使ってのデバッグはちょっとしたコツが必要です。今回はデバッグ方法については割愛しますが、要望があれば次の回にでも補足できたらなと思います。
      Q:Interface Builderを使いたい!
      A:お察し下さい。

      Emacsをお使いの方は”emacs-xcode.el”やAutoCompleteの”ac-source-company-xcode”など利用すれば、開発自体も便利になると思います。 そして、これらをうまく利用すれば、Xcodeに負けないぐらいのiPhoneアプリの開発ができるelispができそうだなーなんて考えてます。

      それでは、次の担当の人にバトンタッチ〜。

      { 2010.12.5 }

      iPhone で暗号化

        はてなブックマーク - iPhone で暗号化
        このエントリーをはてなブックマークに追加

        初めまして、Fusic 河野です。
        わたくし、IT 系のバスケの社会人チームやiPhone アプリ系のコミュニティとかを
        やってたりするので、ご興味のある方はぜひご参加ください。

        弊社にはもう一人河野というものがおり、そっちとは違う方と
        覚えて頂けると溜飲が下がります。。。

        最近、プライベートではこんなことやってたりして遊んでます。
        Fusic では、主に ruby on rails をやっており、ZENPRE の iPhone アプリを
        担当させていただいてたりします。

        さて、昨日行われました安元の結婚式も無事に終わり、本日はとっても天気の良い日曜日です。
        それにしても、とても良い結婚式でした。

        「おめでとうございます。お二人とも末永くお幸せに!」

        で、そんな幸せに包まれつつな日曜日も Advent Calendar です。
        こんな日にバトンがまわってくるとは、、な気分ではございますがさっそく。

        ご結婚されたばかりのお二人には、なんとも、、な話かもしれませんが、
        いくら仲睦まじい関係だとしても、時には隠蔽する必要が出てくる事が
        あるやも知れません。
        そんな時に必要になってくること。

        “暗号化”についてです。

        前に山本が「as3cryptoで暗号化」 という記事を書いてますが、
        その記事の iPhone 版だと思っていただければ幸いです。

        暗号化

         objective-c で暗号化をする場合、CCCrypt() という関数を使います。

         [CCCrypt(3cc) Mac OS X Manual Page]
         developer.apple.com/library/mac/#DOCUMENTATION/Darwin/Reference/ManPages/man3/CCCrypt.3cc.html
         
         iPhone 用のサンプルコードはこちらになるのですが、見ていただくと分かるのですが、
         まー、as のように楽じゃないなというのが分かって頂けるかなと。

         CCCrypt() を使用して、NSData クラスに AES256EncryptWithKey, AES256DecryptWithKey のメソッドを追加します。
         (※ こちらを参考にしました)

         NSDataAdditions.m というファイルを作成し、以下を追加します。

        #import &lt;CommonCrypto/CommonCryptor.h&gt;
         
        @implementation NSData (Additions)
         
        @class NSString; 
         
        - (NSData *)AES256EncryptWithKey:(NSString *)key {
                char keyPtr[kCCKeySizeAES256+1];
                bzero(keyPtr, sizeof(keyPtr));
         
                [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
         
                NSUInteger dataLength = [self length];
         
                size_t bufferSize = dataLength + kCCBlockSizeAES128;
                void *buffer = malloc(bufferSize);
         
                size_t numBytesEncrypted = 0;
                CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,       
                                                                                 kCCOptionPKCS7Padding | kCCOptionECBMode,
                                                                                 keyPtr, kCCKeySizeAES256,
                                                                                 NULL,
                                                                                 [self bytes], dataLength,
                                                                                 buffer, bufferSize,
                                                                                 &numBytesEncrypted);
                if (cryptStatus == kCCSuccess) {
                        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
                }
                free(buffer);
                return nil;
        }
         
        - (NSData *)AES256DecryptWithKey:(NSString *)key {
                char keyPtr[kCCKeySizeAES256+1];
                bzero(keyPtr, sizeof(keyPtr));
         
                [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
         
                NSUInteger dataLength = [self length];
         
                size_t bufferSize = dataLength + kCCBlockSizeAES128;
                void *buffer = malloc(bufferSize);
         
                size_t numBytesDecrypted = 0;
                CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, 
                                                                                 kCCOptionPKCS7Padding | kCCOptionECBMode,
                                                                                 keyPtr, kCCKeySizeAES256,
                                                                                 NULL,
                                                                                 [self bytes], dataLength,
                                                                                 buffer, bufferSize,
                                                                                 &numBytesDecrypted);
         
                if (cryptStatus == kCCSuccess) {
                        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
                }
                free(buffer);
                return nil;
        }
        @end

         使う側でファイルをインポートすれば、NSData クラスのメソッドとして使えます。

        base64encoding

         暗号化したデータを ZENPRE とかのように、サーバにデータを送る必要があるなら、
         base64 エンコードも実装する必要があります。
         同じく NSData クラスに newStringInBase64FromData というメソッドを追加します。
         (※ こちらを参考にしました)

         先程のファイルに下記を追加します。

        - (NSString *)newStringInBase64FromData {
                NSMutableString *dest = [[NSMutableString alloc] initWithString:@""];
                unsigned char * working = (unsigned char *)[self bytes];
                int srcLen = [self length];
         
                for (int i=0; i<srcLen; i += 3) {
                        for (int nib=0; nib<4; nib++) {
                            int byt = (nib == 0)?0:nib-1;
                                int ix = (nib+1)*2;
         
                                if (i+byt >= srcLen) break;
         
                                unsigned char curr = ((working[i+byt] << (8-ix)) & 0x3F);
         
                                if (i+nib < srcLen) curr |= ((working[i+nib] >> ix) & 0x3F);
         
                                [dest appendFormat:@"%c", base64[curr]];
                        }
                }
                return dest;
        }

         同じく使う側でファイルをインポートすれば、NSData クラスのメソッドとして使えます。

        実行

         上記の追加したコードを含めたサンプルコードを実行します。

         

         入力した値が、base64 に変換されている事(真ん中のグレー領域)と
         暗号化されたものが復元されている事(下の白領域)を確認します。

        おわりに

         やはり、どうしても as と比べるとなんだかメンドクサイですね。
         暗号化の話は、コードも含め長文にどうしてもなってしまうので
         駆け足で進めていってしまいました。
         今回、objective-c の醍醐味の一つでもあるかなと個人的に思ってる、
         既存クラスへのメソッドの追加ができるってだけでも実感頂ければと思います。

         今回使用したサンプルのソースコードはココにあげております。
         お役に立てれば幸いです。

         それと、近々 ZENPRE の iPhone アプリの新版がリリースされる予定です。
         ご期待下さい。