質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

4710閲覧

SwiftでBonjourのデバイスにアクセスしたい

apple2

総合スコア37

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2017/03/30 05:13

SwiftでLAN内のBonjourやAvahiに対応したデバイスを検索し、そのIPアドレスを求めたいと思います
NetServiceBrowserを利用すれば実現しそうな気がするのですが、いかんせん、能力が低いもので、よくわかりません
わかりやすい説明やサンプルコードが書かれたサイトがあれば教えてください

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

NetServiceBrowserにdelegateをセットして、searchForServicesを実行することでサービスを検索することが出来ます。
NetServiceBrowserで検索が成功するとデリゲートのnetServiceBrowser(_ browser: NetServiceBrowser, didFind service: NetService, moreComing: Bool)が呼ばれ、そこでサービスにdelegateをセットしてresolveを実行します。
resolveが成功すると今度はデリゲートの'netServiceDidResolveAddress(_ sender: NetService)'が呼ばれます。そのメソッドでaddressesを利用することが出来ます。

下のコードをPlaygroundで実行すると、サービスのタイプに_afpovertcp._tcpを指定しているのでAFPに対応した機器のIPアドレスが表示されます。

Swift

1import Foundation 2import PlaygroundSupport 3 4class Delegatee: NSObject, NetServiceBrowserDelegate, NetServiceDelegate { 5 var services = [NetService]() 6 7 func netServiceBrowser(_ browser: NetServiceBrowser, didFind service: NetService, moreComing: Bool) { 8 services.append(service) 9 service.delegate = self 10 service.resolve(withTimeout: 5.0) 11 } 12 13 func netServiceDidResolveAddress(_ sender: NetService) { 14 var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST)) 15 guard let data = sender.addresses?.first else { return } 16 do { 17 try data.withUnsafeBytes { (pointer: UnsafePointer<sockaddr>) in 18 guard getnameinfo(pointer, socklen_t(data.count), &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 19 else { throw NSError(domain: "error_domain", code: 0, userInfo: .none) } 20 21 let address = String(cString: hostname) 22 print(address) 23 } 24 } catch { 25 print(error) 26 } 27 } 28} 29 30let delegatee = Delegatee() 31let browser = NetServiceBrowser() 32browser.delegate = delegatee 33browser.searchForServices(ofType: "_afpovertcp._tcp", inDomain: "") 34 35PlaygroundPage.current.needsIndefiniteExecution = true

投稿2017/03/30 09:30

rizumita

総合スコア84

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

apple2

2017/03/30 23:31

ありがとうございます、試してみます
apple2

2017/03/30 23:53

PlayGroundで実行するとDelegateeの中のaddressの値が、IPアドレスになっていて、ちゃんと動いていることが確認できました、ありがとうございます ただ、私はプログラミングがまだわかっていないので実際にはどうやってaddressの値をclassから取り出すのかわかりません
apple2

2017/03/31 02:33

こんな風に書いたんですが、値はとれません また、ホストネームはどの変数で取れるのでしょう import UIKit import Foundation class ViewController: UIViewController, NetServiceBrowserDelegate { let ud = UserDefaults.standard override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let delegatee = Delegatee() let browser = NetServiceBrowser() browser.delegate = delegatee browser.searchForServices(ofType: "_afpovertcp._tcp", inDomain: "") print(delegatee.ipAddress) print(delegatee.hostNames) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } class Delegatee: NSObject, NetServiceBrowserDelegate, NetServiceDelegate { var services = [NetService]() var ipAddress = [String]() var hostNames = [String]() func netServiceBrowser(_ browser: NetServiceBrowser, didFind service: NetService, moreComing: Bool) { services.append(service) service.delegate = self service.resolve(withTimeout: 5.0) } func netServiceDidResolveAddress(_ sender: NetService) { var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST)) guard let data = sender.addresses?.first else { return } do { try data.withUnsafeBytes { (pointer: UnsafePointer<sockaddr>) in guard getnameinfo(pointer, socklen_t(data.count), &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 else { throw NSError(domain: "error_domain", code: 0, userInfo: .none) } let address = String(cString: hostname) ipAddress.append(address) hostNames.append(String(describing: hostname)) } } catch { print(error) } } }
rizumita

2017/03/31 04:52

そのコードですとおそらくviewDidLoadの抜けたらdelegateeが無くなってしまうので取得できません。delegateeをViewControllerのプロパティとして持たせてみてください。
apple2

2017/03/31 06:25

VIewControllerにプロパティを持たせると言うのは class ViewController:の行のすぐ下に宣言を書くということでしょうか? import UIKit import Foundation var ipAddress = [String]() var hostNames = [String]() class ViewController: UIViewController, NetServiceBrowserDelegate { var delegatee = Delegatee() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let browser = NetServiceBrowser() browser.delegate = delegatee browser.searchForServices(ofType: "_afpovertcp._tcp", inDomain: "") print(ipAddress) print(hostNames) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } class Delegatee: NSObject, NetServiceBrowserDelegate, NetServiceDelegate { var services = [NetService]() // var ipAddress = [String]() // var hostNames = [String]() func netServiceBrowser(_ browser: NetServiceBrowser, didFind service: NetService, moreComing: Bool) { services.append(service) service.delegate = self service.resolve(withTimeout: 5.0) } func netServiceDidResolveAddress(_ sender: NetService) { var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST)) guard let data = sender.addresses?.first else { return } do { try data.withUnsafeBytes { (pointer: UnsafePointer<sockaddr>) in guard getnameinfo(pointer, socklen_t(data.count), &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 else { throw NSError(domain: "error_domain", code: 0, userInfo: .none) } let address = String(cString: hostname) ipAddress.append(address) hostNames.append(String(describing: hostname)) print(address) } } catch { print(error) } } }
apple2

2017/03/31 06:26

あまりにもレベルが低い質問で申し訳ありません
apple2

2017/03/31 12:34

ホストネームは service.nameに入ってました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問