‘iPhone/iPad’ カテゴリーのアーカイブ

長崎国体・大会アプリがリリースされました!

長崎がんばらんば国体・長崎がんばらんば大会実行委員会様提供、弊社設計・開発による長崎国体アプリがリリースされました!
競技の日程や組合せ、会場付近の施設など、観戦をトータルにサポートするアプリになっております。
5月24・25日はリハーサル大会も開催されますので、是非ダウンロードしてください!

Facebooktwittergoogle_pluslinkedintumblrmail

AutoLayoutをiOS5にbackportするRRAutoLayout

iOS6で導入されたAutoLayout。正しく使えば3.5inchでも4inchでも怖くない!しかし当然iOS5以前では使えません。。。2013年7月現在でも、iOS5を使用されてるユーザは全体の1割程はいるようで、切るにも切れないこともあるかと思います。

そこでRRAutoLayout、素晴らしすぎます。

RolandasRazma/RRAutoLayout 

セットアップにはハマりませんでしたが、思ったような表示にならなかったので色々触っていると、次のようなことに注意すれば良いことが分かりました。

Storyboard上で、例えばViewの最上部に置きたい画像がある場合、通常ImageViewをドラッグして、Viewの最上部に置くと思いますが、この際自動でConstraintsが設定されるかと思います(SuperviewとのVertical Spaceが0など)。この自動でできるConstraintsだとRRAutoLayout は認識してくれないので、あくまでも手動でのConstraintsに変換してやります。(ImageViewのHeightなども含め)

まだ多くのViewを定義してみたわけではありませんが、これで効率よく開発できそうです。

Facebooktwittergoogle_pluslinkedintumblrmail

Objectve-Cでクラスのインスタンスメソッドを書き換える

つい最近までiOS用のコードを書いていたのですが、その中でとあるオープンソースのライブラリを使用しています。でその中のとあるインスタンスメソッドの処理を書き換える必要がありました。
カテゴリ使って書き換えようと思ったのですが、その処理自身がカテゴリで定義されていたため無理でした。

まあライセンスに問題なければソースを直接修正すれば良いのですが、ライブラリのアップデートとかに備えておきたいとこです。
そこでclass_replaceMethodを使って書き換える方法に落ち着きました。

//ExampleClassのexampleMethodを書き換える例

#import 

...

id class = [ExampleClass class];//クラス定義取得
SEL sel = @selector(exampleMethod);//セレクタ取得

void (^block)() = ^{
  //処理を書き換える
};

IMP imp = imp_implementationWithBlock(block);//BlocksからIMPを生成

Method method = class_getInstanceMethod(class, sel);//元のインスタンスメソッドを取得
char* types = method_getDescription(method)->types;//インスタンスメソッドの引数の型を取得
class_replaceMethod(class, sel, imp, types); //書き換え!

これをAppDelegateなんかで実行しておけばOKです。

Facebooktwittergoogle_pluslinkedintumblrmail

NSDictionaryのdictionaryWithObjectsAndKeysが辛い

iOS開発をやっていて、NSDictionaryでよく使うdictionaryWithObjectsAndKeys、NSArrayのarrayWithObjectsですが、下記のように入れ子になってくると何のこっちゃ分からなくなります。

NSDictionary *dictionary1 = [NSDictionary dictionaryWithObjectsAndKeys:
                             @"Taichiro", @"firstname",
                             @"Yoshida", @"lastname",
                             [NSArray arrayWithObjects:
                              [NSDictionary dictionaryWithObjectsAndKeys:
                               @"twitter", @"type",
                               @"dataich", @"id",
                               nil
                               ],
                              [NSDictionary dictionaryWithObjectsAndKeys:
                               @"facebook", @"type",
                               @"dataich", @"id",
                               nil
                               ],
                              nil],
                             @"accounts",
                             nil
                             ];

NSLogで出力した結果を見ると、下記のようなシンプルな内容なのですが。

{
    accounts =     (
                {
            id = dataich;
            type = twitter;
        },
                {
            id = dataich;
            type = facebook;
        }
    );
    firstname = Taichiro;
    lastname = Yoshida;
}

これをもう少し簡単にかける方法があります。
dictionaryWithObjectsAndKeysには @{}
arrayWithObjectsには @[]
というリテラル?が用意されてます。
これを使って書き直すと下記のようになります。

NSDictionary *dictionary2 = @{
                              @"firstname" : @"Taichiro",
                              @"lastname"  : @"Yoshida",
                              @"accounts"  : @[
                                                @{
                                                    @"type" : @"twitter",
                                                    @"id"   : @"dataich"
                                                },
                                                @{
                                                    @"type" : @"facebook",
                                                    @"id"   : @"dataich"
                                                }
                                             ]
                              };

ちょっとは見やすくなりますね!

Facebooktwittergoogle_pluslinkedintumblrmail

Wowza Media Server 2 でiPhoneへのオンデマンドストリーミング、ライブストリーミング

Wowza Media Serverのバージョン2が先日リリースされたのですが、Apple HTTP Live StreamingによるiPhoneへの配信が可能になりました。ということで試してみましたのでついでにCentOS5でのセットアップの手順を書きました。

Javaのインストール

[root@localhost ~]# yum install java

Wowza ServerのRPMインストール

WowzaサイトからLinux RPM版のURLを取得します。
また、実行に必要なシリアルNoも取得しておきます。(今回はWowza Server Developer Editionを取得しました。)

$ mkdir work
$ cd work
$ wget http://www.wowzamedia.com/downloads/WowzaMediaServer-2-0-0/WowzaMediaServer-2.0.0.rpm.bin
$ chmod +x WowzaMediaServer-2.0.0.rpm.bin
$ ./WowzaMediaServer-2.0.0.rpm.bin

Wowza Serverのライセンスキー設定及び実行

$ cd /usr/local/WowzaMediaServer/bin
$ ./startup.sh
Configure logging: file:///usr/local/WowzaMediaServer/conf/log4j.properties
Please enter serial number:
XXXXX-XXXXX-XXXXX-XXXXX-XXXXX #ここでシリアルNoを入力

サーバが起動しますので、一旦Ctrl+Cで停止します。

自動起動の設定

$ chkconfig WowzaMediaServer on
$ chkconfig WowzaMediaServer --list
WowzaMediaServer0:off1:off2:on3:on4:on5:on6:off
$ /etc/rc.d/init.d/WowzaMediaServer start #再度、Wowzaを起動

サンプルのインストール

$ cd /usr/local/WowzaMediaServer/examples/
$ ./installall.sh

オンデマンドをiPhoneで試す

オンデマンドアプリケーションの作成、設定

$ cd /usr/local/WowzaMediaServer/conf/
$ mkdir vod
$ cp Application.xml vod/

http://hostname:1935/vod/mp4:Extremists.m4v/playlist.m3u8 にアクセスすると動画のストリーミングが開始されます。

ライブストリーミングをiPhoneで試す

ライブストリーミングアプリケーションの作成、設定

$ cd /usr/local/WowzaMediaServer/conf/
$ mkdir live
$ cp Application.xml live/
$ vi live/Application.xml
#Streams/StreamTypeをliveに変更
#Streams/LiveStreamPacketizersをcupertinostreamingpacketizerに変更(WowzaのドキュメントではStreamタグ内と書いてありませんでしたが、こちらに設定しないとうまくいきませんでした)
#RTP/Authentication/PlayMethodをnoneに変更
#RTP/Authentication/PublishMethodをnoneに変更

ウェブキャストアプリケーションのインストール、放送

ここではWireCastを使用します。
こちらからWireCastをダウンロード、インストールし起動

ウィンドウ下部で使用するカメラを選択
メニュー > 放送 > 放送セッティングを選択し下記セッティングを用意する

  • エンコーダープレ
    エンコーダプレコンボボックスから編集を選択。ここでは下記のようにしました。
  • デスティネーション
    QuickTime ストリーミングサーバに知らせる。
  • ホスト名
    hostname:1935
  • ロケーション
    live/myStream.sdp(myStream部分は別名可)
  • ユーザ名、パスワード
    なし(認証は試していません)
  • TCP経由ブロードキャスト
    なし

上記で保存。

ウィンドウ左上の放送アイコンをクリック。これで放送が開始されます。
http://hostname:1935/live/myStream.sdp/playlist.m3u8 にアクセスするとライブストリーミングが開始されます。

Facebooktwittergoogle_pluslinkedintumblrmail

モバイルアプリケーション向けユーザサポートサイトをホスティングする SuppApp( http://supp-app.com/ )をオープンしました。

この度、有限会社ランカードコムは、モバイルアプリケーション向けユーザサポートサイトをホスティングする SuppApp(http://supp-app.com/)をオープンしました。

iPhoneから始まったモバイルアプリケーションブーム。多くの方々が続々と開発に参入しています。ユーザからの評価が高いアプリケーションの共通事項として、「ユーザの声をよく聞いている」という事が挙げられます。SuppAppは「ユーザの声を聞く」ことを強力に支援します。

「認証にTwitterを使用」

開発者(アプリの登録)、アプリユーザ(サポートサイトへの投稿)共にTwitterのOAuthによって認証を行います。面倒なメールアドレス等の登録が要りません。またアプリユーザに関しては認証無しでも投稿が可能です。

「トピックの状態」

トピックは質問・要望・賞賛・バグの4つのカテゴリに分けられ、例えばユーザからの要望が投稿された場合、開発者はそれを(対応します・対応中です・リリースしました)とマークすることができます。これによりユーザは新機能が実装されるのかどうかを把握することができます。

「トピックへの投票」

ユーザはトピックに対して投票することができます。開発者は投票数を見て要望を実装するかを決める事ができます。

「iPhone、iPadへの対応」

アプリを登録する際にiPhoneアプリか、iPadアプリかを登録してください。するとトップページには登録したスクリーンショットをiPhone、iPadの端末画像にはめ込んで表示します。今後Android等にも対応する予定です。

「ヘルプページ」

アプリの使い方を登録するページも用意しました。

「モバイルブラウザに対応」

サポートサイトはモバイル向けにも見やすく表示できるよう最適化しています。アプリ内にサポートサイトへのリンクを用意しておけば、ユーザはそのまま質問したり、要望を出したりすることができます。

「開発者向けページ」

開発者がアプリにどんな投稿があるのか、回答がなされているのかを一目で把握できるようなページを用意しています。またアプリ毎のフィードも用意しています。

SuppAppはモバイルアプリケーションの開発者様を強力にサポートします。数分で登録できますので、是非ご登録をお願いします!

Facebooktwittergoogle_pluslinkedintumblrmail

画面いっぱいのUITextViewがキーボードに隠れないようにする

iPadで画面いっぱいにUITextViewを配置すると、入力状態になった際にキーボードが出てきて入力カーソルが隠れてしまいます。これには「キーボードが表示・非表示になるタイミングで、UITextViewの高さを変えてあげる」ことで 対処可能です。UICatalogのサンプルが少し古く、3.2ではDeprecatedになっているUIKeyboardBoundsUserInfoKeyを使っていたため、UIKeyboardFrameEndUserInfoKeyを使うようにしてみました。恐らくiPhoneでも同じようにできるはずです。

@interface CustomViewController : UIViewController  {
    UITextView *_textView; //対象となるテキストビュー。UIViewControllerのサブビューとして追加する。
}
@property (nonatomic, retain) IBOutlet UITextView *_textView;
@end


@implementation CustomeViewController

- (void)viewDidLoad {
    [super viewDidLoad];    
    //親ビューの高さが変更された時に追従するようにする
    _textView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
    //キーボード表示・非表示の通知の開始
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];

    //キーボード表示・非表示の通知を終了
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

//キーボードが表示された場合
- (void)keyboardWillShow:(NSNotification *)aNotification {
    //キーボードのCGRectを取得
    CGRect keyboardRect = [[[aNotification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    keyboardRect = [[self.view superview] convertRect:keyboardRect fromView:nil];
    
    //キーボードのanimationDurationを取得
    NSTimeInterval animationDuration = [[[aNotification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];

    //メインビューの高さをキーボードの高さ分マイナスしたframe
    CGRect frame = self.view.frame;
    frame.size.height -= keyboardRect.size.height;

    //キーボードアニメーションと同じ間隔でメインビューの高さをアニメーションしつつ変更する。
    //これでUITextViewも追従して高さが変わる。
    [UIView beginAnimations:@"ResizeForKeyboard" context:nil];
    [UIView setAnimationDuration:animationDuration];
    self.view.frame = frame;
    [UIView commitAnimations];
}

//キーボードが非表示にされた場合(keyboardWillShowと同じことを高さを+してやっているだけ)
- (void)keyboardWillHide:(NSNotification *)aNotification {
    CGRect keyboardRect = [[[aNotification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    keyboardRect = [[self.view superview] convertRect:keyboardRect fromView:nil];

    NSTimeInterval animationDuration = [[[aNotification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];

    CGRect frame = self.view.frame;
    frame.size.height += keyboardRect.size.height;

    [UIView beginAnimations:@"ResizeForKeyboard" context:nil];
    [UIView setAnimationDuration:animationDuration];
    self.view.frame = frame;
    [UIView commitAnimations];
}

@end
Facebooktwittergoogle_pluslinkedintumblrmail