iPhone/iPadネットワークプログラミング(4)Bonjourを使ってデータを送る (2) iPhone/iPadからMacヘ送信

前回の続き。サービスを探す側について。こちら側はiPhone/iPad で実装できます。


まず、発行されているサービスを検索します。サービスの検索は NSNetServiceBrowserクラスを使います。

- (void) searchService
{
    NSNetServiceBrowser* browser = [[NSNetServiceBrowser alloc] init];
    [browser setDelegate: self];
    [browser searchForServicesOfType:@"_test._tcp" inDomain:@""];
}

手順は、NSNetServiceBrowserの初期化、デリゲートの登録、searchForServicesOfType: inDomain: で検索です。
探すときの type は発行側の type と一致させないと探せません。


サービス発見時に呼ばれるメソッドを実装します。ここでサービスとIPアドレスとの関連付けを行います。

- (void) netServiceBrowser:(NSNetServiceBrowser*)browser didFindService:(NSNetService*)netService moreComing:(BOOL)moreComing
{
    NSNetService* service = [[NSNetService alloc] initWithDomain:[netService domain] type:[netService type] name:[netService name]];
    if(service){
        [service setDelegate: self];
        [service resolveWithTimeout: 5.0];
    }else{
        NSLog(@"接続失敗");
    }
}

サービスが見つかるごとに呼ばれます。
発見したサービスから NSNetService のインスタンスを新たに作成します。多分 retain でも問題ないかと思います。
作成に成功すれば、デリゲートの登録をし、IPアドレスを決定します。このとき、タイムアウトを設定します。
あ、そうそう、ここでは alloc してるので、どっかで release しないといけません。その辺はうまく組んでね。
クラス変数にしても良いが、サービスが複数あった場合に困ったことになるんで注意されたし。


さて、IPアドレスが特定できた場合、次のメソッドが呼ばれます。今回はここで文字列を送ってみます。

- (void) netServiceDidResolveAddress:(NSNetService*)netService
{
    NSLog(@"Name: %@, Domain:%@, Type:%@",   [netService name], [netService domain], [netService type]);

    NSInputStream *iStream = nil;
    NSOutputStream *oStream = nil;
    [netService getInputStream: &iStream outputStream: &oStream];

    if(oStream){
        NSString *sendMessage = @"iPhone/iPadからMacへ文字列を送信しま〜す。";
        NSData *data = [sendMessage dataUsingEncoding: NSUTF8StringEncoding];
        [oStream open];
        [oStream write:[data bytes] maxLength:[data length]];
        [oStream close];
    }
}

接続しようとしているサービスから、ストリームハンドルを取得します。これは getInputStream: outputStream: で取得できます。INとOUTの両方が取得できるので便利です。今回はOutputのみ使います。
送るデータを用意し、Output Stream をオープンして write で送ります。最後に close でストリームを閉じておきます。
注意点として、送るデータは uint8_tなので、NSString を NSData を経由して uint8_t にします。


これで、iPhone/iPad => Mac への送信ができました。
が、これ、単発しか送れないし、双方向になっていないんだよね。というわけで、次回は、Mac => iPhone/iPad についてやってみる。