Основной поток блокирует NSStream при проверке доступности ввода в NSStream - PullRequest
0 голосов
/ 14 января 2019

Я работаю с пакетом DSBridge для подключения мобильного приложения (в данном случае кода iOS) к коду javascript, содержащему основную логику моего приложения. Это включает в себя запуск JavaScript на невидимом WKWebView.

Мой код JavaScript должен вызывать метод в собственном приложении iOS, которое должно выполняться и возвращать значение в JavaScript.

Функция My Objective C гласит:

- (NSString* )read:(NSDictionary *) args{
    NSLog(@"In Read");
    while(self->connection != NULL) {
        if([self->connection isMessageAvailable]) {
            [self->connection messageRetrieved];
            NSLog(@"Message Received in ViewController");
            return [self->connection getMessage];
        }
    }
    return NULL;
}

Это вызывается из моего JavaScript, мне нужно, чтобы он возвращался в основной поток, чтобы возвращаемое значение отправлялось в мой WebView.

Проблема в том, что мое сообщение от IO, которого я жду, никогда не появится, так как мой NSStream заблокирован циклом while.

Мои методы подключения и NSStream выглядят так:

-(void)readData:(NSData*)receivedData{
    NSData *decoded = [self btXOR:receivedData withMask:0x26];
    message = [[NSString alloc] initWithData:decoded encoding:NSUTF8StringEncoding];
    NSLog(@"message: %@", message);
    messageAvailable = true;
}

- (BOOL) isMessageAvailable {
    return messageAvailable;
}

- (void) messageRetrieved {
    messageAvailable = false;
}

- (NSString*) getMessage {
    NSLog(@"Message: %@", message);
    return message;
}

#pragma mark StreamDelegate
-(void) stream:(NSStream *)theStream handleEvent:(NSStreamEvent)eventCode
{
    switch (eventCode)
    {

            //Reading in from host done here
            case NSStreamEventHasBytesAvailable:
            DDLogInfo(@"NSStreamEventHasBytesAvailable");
            DDLogInfo(@"stream is input: %i " , (theStream == inputStream));
            NSLog(@"NSStreamEventHasBytesAvailable");
            NSLog(@"stream is input: %i " , (theStream == inputStream));


            if (theStream == inputStream)
        {
            uint8_t buffer[1024];
            long len;

            while ([inputStream hasBytesAvailable])
            {
                len = [inputStream read:buffer maxLength:sizeof(buffer)];
                DDLogDebug(@"InputStream still has bytes");
                NSLog(@"InputStream still has bytes");
                if (len > 0)
                {
                    NSMutableData* data=[[NSMutableData alloc] initWithLength:0];

                    [data appendBytes: (const void *)buffer length:(int)len];
                    [self readData:data];
                }
            }
        }
            break;

Случай 'NSStreamEventHasBytesAvailable' должен возникать после того, как сообщение будет готово, и должно быть получено моей функцией чтения, чтобы оно могло быть возвращено моему JavaScript WebViews.

Как я могу отключить цикл while из основного потока и все еще вернуться после получения сообщения? Можно ли удалить NSStream из основного цикла выполнения таким образом, чтобы он не был заблокирован моей функцией чтения?

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

...