Просмотр для сетевых служб

Важная часть Добрый день является возможностью просмотреть для служб на сеть. В этой главе описываются, как использовать NSNetServiceBrowser класс для обнаружения Добрый день сетевых служб.

Процесс просмотра

NSNetServiceBrowser класс обеспечивает методы для просмотра для доступного Добрый день сетевые службы.

Из-за возможных задержек, связанных с сетевым трафиком, NSNetServiceBrowser объекты выполняют просмотр асинхронно путем регистрации в выполненном цикле по умолчанию. Просматривающие результаты возвращаются к Вашему приложению через методы делегата. Обработать результаты NSNetServiceBrowser объект, необходимо присвоить его делегат.

Для Просмотра для Добрый день сетевых служб приложение должно выполнить три шага:

  1. Инициализируйте NSNetServiceBrowser экземпляр и присваивает делегата в объекте.

  2. Начните поиск служб определенного типа в данном домене.

  3. Результаты поиска дескриптора и другие сообщения отправили к объекту делегата.

Инициализация браузера и запуск поиска

Инициализировать NSNetServiceBrowser объект, используйте init метод. Это устанавливает браузер и добавляет его к текущему циклу выполнения. Если Вы хотите использовать цикл выполнения кроме текущего, используйте removeFromRunLoop:forMode: и scheduleInRunLoop:forMode: методы.

Для начала процесса просмотра используйте searchForServicesOfType:inDomain: метод. Экспрессы типа службы оба протокол прикладного уровня (FTP, HTTP, и т.д.) и транспортный протокол (TCP или UDP). Формат как описан в Доменных Соглашениях о присвоении имен — например, _printer._tcp для принтера LPR по TCP.

Доменный параметр указывает домен DNS, в котором браузер выполняет свой поиск. Существует четыре распространенных способа использовать этот параметр:

Для остановки поиска используйте 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: метод уведомляет делегата, что начинается поиск. Можно использовать этот метод для обновления пользовательского интерфейса, чтобы отразить, что поиск происходит. При просмотре остановок делегат получает 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