Просмотр для сетевых служб
Важная часть Добрый день является возможностью просмотреть для служб на сеть. В этой главе описываются, как использовать NSNetServiceBrowser
класс для обнаружения Добрый день сетевых служб.
Процесс просмотра
NSNetServiceBrowser
класс обеспечивает методы для просмотра для доступного Добрый день сетевые службы.
Из-за возможных задержек, связанных с сетевым трафиком, NSNetServiceBrowser
объекты выполняют просмотр асинхронно путем регистрации в выполненном цикле по умолчанию. Просматривающие результаты возвращаются к Вашему приложению через методы делегата. Обработать результаты NSNetServiceBrowser
объект, необходимо присвоить его делегат.
Для Просмотра для Добрый день сетевых служб приложение должно выполнить три шага:
Инициализируйте
NSNetServiceBrowser
экземпляр и присваивает делегата в объекте.Начните поиск служб определенного типа в данном домене.
Результаты поиска дескриптора и другие сообщения отправили к объекту делегата.
Инициализация браузера и запуск поиска
Инициализировать NSNetServiceBrowser
объект, используйте init
метод. Это устанавливает браузер и добавляет его к текущему циклу выполнения. Если Вы хотите использовать цикл выполнения кроме текущего, используйте removeFromRunLoop:forMode:
и scheduleInRunLoop:forMode:
методы.
Для начала процесса просмотра используйте searchForServicesOfType:inDomain:
метод. Экспрессы типа службы оба протокол прикладного уровня (FTP, HTTP, и т.д.) и транспортный протокол (TCP или UDP). Формат как описан в Доменных Соглашениях о присвоении имен — например, _printer._tcp
для принтера LPR по TCP.
Доменный параметр указывает домен DNS, в котором браузер выполняет свой поиск. Существует четыре распространенных способа использовать этот параметр:
Ограничить поиски локальной сетью (для программы чата, например), передача
@"local"
искать только локальный LAN.Для ограниченной глобальной поддержки, передачи
@""
искать области поиска системы по умолчанию. Избегать беспорядка, убеждаться вывести на экран домен каждой службы в Вашем пользовательском интерфейсе.Для полной глобальной поддержки используйте
searchForBrowsableDomains
метод для получения списка доступных для просмотра доменов, как описано в Просмотре для Доменов. Тогда представьте пользовательский интерфейс, позволяющий пользователю выбирать домен для просмотра. Когда пользователь выбирает домен, обзор только в том домене.Для обеспечения максимальной гибкости для продвинутых пользователей обеспечьте текстовое поле, в котором пользователь может указать произвольное доменное имя для просмотра.
Для остановки поиска используйте stop
метод. Тогда выполните любую необходимую очистку в netServiceBrowserDidStopSearch:
обратный вызов делегата.
Перечисление 3-1 демонстрирует, как просмотреть для Добрый день сетевых служб с NSNetServiceBrowser
. Код инициализирует объект, присваивает делегата и начинает поиск гипотетического музыкального типа службы, _music._tcp
, в локальной сети. Для хорошего примера просмотра службы см. проект примера кода PictureSharingBrowser в Библиотеке Разработчика Mac.
Просмотр перечисления 3-1 для Добрый день сетевых служб
id delegateObject; // Assume this exists. |
NSNetServiceBrowser *serviceBrowser; |
serviceBrowser = [[NSNetServiceBrowser alloc] init]; |
[serviceBrowser setDelegate:delegateObject]; |
[serviceBrowser searchForServicesOfType:@"_music._tcp" inDomain:@""]; |
Реализация методов делегата для просмотра
NSNetServiceBrowser
возвраты весь просмотр заканчиваются его делегату. При использовании класса для просмотра для служб, объект делегата должен реализовать следующие методы:
netServiceBrowserWillSearch:
netServiceBrowserDidStopSearch:
netServiceBrowser:didNotSearch:
netServiceBrowser:didFindService:moreComing:
netServiceBrowser:didRemoveService:moreComing:
netServiceBrowserWillSearch:
метод уведомляет делегата, что начинается поиск. Можно использовать этот метод для обновления пользовательского интерфейса, чтобы отразить, что поиск происходит. При просмотре остановок делегат получает a netServiceBrowserDidStopSearch:
сообщение. В том методе делегата можно выполнить любую необходимую очистку.
Если делегат получает a netServiceBrowser:didNotSearch:
сообщение, поиск перестал работать по некоторым причинам. Метод делегата должен извлечь информацию об ошибке из словаря с NSNetServicesErrorCode
ключ и обрабатывает ошибку соответственно. Для списка возможных ошибок посмотрите NSNetService.
Вы отслеживаете службы с netServiceBrowser:didFindService:moreComing:
и netServiceBrowser:didRemoveService:moreComing:
методы, указывающие, что служба стала доступной или закрылась. moreComing
параметр указывает, является ли больше результатов на пути. Если этот параметр YES
, задержку, обновляющую любые элементы пользовательского интерфейса до метода, вызывают с a moreComing
параметр NO
.
Обязательно сохраните didFindService
параметр прежде, чем попытаться разрешить его. Иначе, Вы рискуете объектом, становящимся освобожденными. Если Вы хотите список доступных служб, необходимо поддержать собственный массив на основе информации, предоставленной методами делегата.
Перечисление 3-2 показывает интерфейс для класса, отвечающего на NSNetServiceBrowser
методы делегата, требуемые для просмотра службы и Перечисления 3-3, показывают его реализацию. Можно хотеть использовать этот код в качестве начальной точки для кода просмотра службы.
Интерфейс перечисления 3-2 для NSNetServiceBrowser делегирует объект, используемый при просмотре для служб
#import <Foundation/Foundation.h> |
@interface NetServiceBrowserDelegate : NSObject <NSNetServiceBrowserDelegate> |
{ |
} |
@property BOOL searching; |
@property (strong,atomic) NSMutableArray *services; |
// Other methods |
- (void)handleError:(NSNumber *)error; |
- (void)updateUI; |
@end |
Реализация перечисления 3-3 для NSNetServiceBrowser делегирует объект, используемый при просмотре для служб
#import "NetServiceBrowserDelegate.h" |
@implementation NetServiceBrowserDelegate |
- (id)init |
{ |
self = [super init]; |
if (self) { |
self.services = [NSMutableArray arrayWithCapacity: 0]; |
self.searching = NO; |
} |
return self; |
} |
// Sent when browsing begins |
- (void)netServiceBrowserWillSearch:(NSNetServiceBrowser *)browser |
{ |
self.searching = YES; |
[self updateUI]; |
} |
// Sent when browsing stops |
- (void)netServiceBrowserDidStopSearch:(NSNetServiceBrowser *)browser |
{ |
self.searching = NO; |
[self updateUI]; |
} |
// Sent if browsing fails |
- (void)netServiceBrowser:(NSNetServiceBrowser *)browser |
didNotSearch:(NSDictionary *)errorDict |
{ |
self.searching = NO; |
[self handleError:[errorDict objectForKey:NSNetServicesErrorCode]]; |
} |
// Sent when a service appears |
- (void)netServiceBrowser:(NSNetServiceBrowser *)browser |
didFindService:(NSNetService *)aNetService |
moreComing:(BOOL)moreComing |
{ |
[self.services addObject:aNetService]; |
NSLog(@"Got service %p with hostname %@\n", aNetService, |
[aNetService hostName]); |
if(!moreComing) |
{ |
[self updateUI]; |
} |
} |
// Sent when a service disappears |
- (void)netServiceBrowser:(NSNetServiceBrowser *)browser |
didRemoveService:(NSNetService *)aNetService |
moreComing:(BOOL)moreComing |
{ |
[self.services removeObject:aNetService]; |
if(!moreComing) |
{ |
[self updateUI]; |
} |
} |
// Error handling code |
- (void)handleError:(NSNumber *)error |
{ |
NSLog(@"An error occurred. Error code = %d", [error intValue]); |
// Handle error here |
} |
// UI update code |
- (void)updateUI |
{ |
if(self.searching) |
{ |
// Update the user interface to indicate searching |
// Also update any UI that lists available services |
} |
else |
{ |
// Update the user interface to indicate not searching |
} |
} |
@end |