Как я могу выбросить NSError из класса Swift и поймать его в классе Objective-C? - PullRequest
1 голос
/ 18 октября 2019

Мне нужно реализовать структуру try-catch в Objective-C для обработки брошенных Swift NSErrors.

Я написал менеджер NetService с кодом Swift и внедряю его на уже существующем Objective-CПользовательский интерфейс.

Однако всякий раз, когда я выкидываю ошибку из своего класса Swift, структура try-catch не может перехватить ошибку и переходит к блоку finally.

Определение ошибки Swift:

enum NEONetServiceErrors: Int
{
    case requestMadeWithoutIp
}

struct NEONetServiceErrorStrings
{
    let requestMadeWithoutIp = ["NEONetService Error: Request made without IP": NEONetServiceErrors.requestMadeWithoutIp]
}

Быстрое генерирование ошибок:

@objc func requestHelloPage() throws
{
    if serviceiPAddress != nil
    {
        makeHelloRequest()
    }
    else
    {
        throw NSError(domain: errorStrings.domain, code: NEONetServiceErrors.requestMadeWithoutIp.rawValue, userInfo:errorStrings.requestMadeWithoutIp)
    }
}

Свойства Objective-C:

@property NEONetServiceManager* netServiceManager;
@property NSError* _Nullable __autoreleasing * _Nullable netServiceError;

Обработка ошибок Objective-C:

- (IBAction)pressUpdateButton:(id)sender
{
    @try
    {
        [self.netServiceManager requestHelloPageAndReturnError: self.netServiceError];
    }
    @catch (NSException *exception)
    {
        NSLog(@"Throwing");
    }
    @finally
    {
        NSLog(@"Finally");
    }
}

Вывод:

2019-10-18 14:47:03.289268-0300 NEOFirmUpdate[16533:2389800] Start
2019-10-18 14:47:03.292696-0300 NEOFirmUpdate[16533:2389800] Finally

Не могли бы вы помочь мне понять, что я делаю неправильно с обработкой ошибок?

Ответы [ 3 ]

0 голосов
/ 18 октября 2019

Это потому, что вы используете там исключения для target-c и фактически не проверяете наличие ошибки. Чтобы проверить наличие ошибок в target-c, вы передаете ссылку на указатель, и ваша функция заполнит эту ошибку, если возникла проблема.

NSError *serviceError = nil;
[self.netServiceManager requestHelloPageAndReturnError:&serviceError];
if (serviceError) {
    // there was a problem
}

Если это асинхронный вызов, вам потребуетсявместо этого сделать это в закрытии:

NSError *serviceError = nil;
[self.netServiceManager requestHelloPage:^(NSError *error) {
    if (error) {
        // there was a problem
    }
}];
0 голосов
/ 18 октября 2019

В вашем коде Objective C вы Catching и NSException, а не NSError

Swift автоматически соединяет мост между типом Error и классом NSError. Методы Objective C, которые вызывают ошибки, импортируются как методы Swift, которые генерируют, и методы Swift, которые генерируют ошибки, импортируются как методы Objective C, которые генерируют ошибки, в соответствии с соглашениями об ошибках Objective C.

для болееинформация, которую вы можете нажать здесь

0 голосов
/ 18 октября 2019

Проблема в том, что ошибка NSError / Objective-C Swift Error не является исключением NSE. Вы настроены на перехват NSExceptions, но это не имеет значения.

Способ "перехватить" NSError в Objective-C, когда Swift генерирует ошибку, по косвенной ссылке с параметром NSError**, как это всегда было.

NSError* err = nil;
BOOL ok = [self.netServiceManager requestHelloPageAndReturnError:&err];
if (ok) {
    // proceed normally
} else {
    // you got an error, it is sitting in `err`
}

(Обратите внимание, как Swift обеспечивает точный результат BOOL, чтобы вы могли реализовать правильный шаблон.)

...