Попытка перейти от Objective-C к Swift VC

Я пытаюсь перейти от цели-к к быстрому.

Однако, когда я пытаюсь сделать это, используя объект ниже, я получаю следующую ошибку

Я не знаю, что я делаю неправильно, я настроил переход на раскадровке и присвоил ему тот же идентификатор, создал функцию подготовки и выполнение.

- (void)renderer:(id<SCNSceneRenderer>)renderer willRenderScene:(SCNScene *)scene atTime:(NSTimeInterval)time {
    // Look for trackables, and draw on each found one.
    size_t trackableCount = trackableIds.size();
    for (size_t i = 0; i < trackableCount; i++) {
//      NSLog(@"this is the variable value: %d", trackableIds[i]);
      // Find the trackable for the given trackable ID.
      ARTrackable *trackable = arController->findTrackable(trackableIds[i]);
//      SCNCamera *camera = self.cameraNode.camera;
      SCNNode *trackableNode = self.trackableNodes[i];
      if (trackable->visible) {
        if (trackableIds[i] == 0) {
          NSLog(@"Starbucks");
          [self performSegueWithIdentifier:@"brandSegue" sender:self];
        } else if (trackableIds[i] == 1) {
          NSLog(@"Dortios");
        }
      } else {
        trackableNode.opacity = 0;
      }

  }
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  if ([segue.identifier isEqualToString:@"brandSegue"]) {
    JSONViewController *destViewController = segue.destinationViewController;
  }
}

РЕДАКТИРОВАТЬ - СООБЩЕНИЕ ОБ ОШИБКЕ

2017-11-09 16:57:05.232992+0000 MyARApp[2573:1099927] *** Assertion failure in -[UIApplication _cachedSystemAnimationFenceCreatingIfNecessary:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3698.21.8/UIApplication.m:1707
2017-11-09 16:57:05.233169+0000 MyARApp[2573:1099927] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'accessing _cachedSystemAnimationFence requires the main thread'
*** First throw call stack:
(0x186f51d04 0x1861a0528 0x186f51bd8 0x1878e1c24 0x1905e9c4c 0x19064646c 0x190432338 0x19038fe5c 0x1903fb6a8 0x190470bf0 0x1906ffb00 0x190701434 0x190703cd8 0x19070420c 0x190703c28 0x190467ab4 0x190707ae4 0x190b38854 0x190ca6b30 0x190ca69d4 0x1906f7e18 0x1020a27cc 0x19a66c610 0x19a725a84 0x19a723e00 0x19a724d1c 0x19a5a0cc4 0x19a6717ac 0x19a671b14 0x19a671f8c 0x19a71a67c 0x19a5d24a0 0x19a6e1c90 0x1035b949c 0x1035b945c 0x1035c8110 0x1035bc9a4 0x1035c9104 0x1035d0100 0x186b7afd0 0x186b7ac20)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

2 ответа

Решение

После обсуждения в чате и решения различных проблем я расскажу о них один за другим:

> *** Assertion failure in -[UIApplication _cachedSystemAnimationFenceCreatingIfNecessary:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3698.21.8/UIApplication.m:1707
> *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'accessing _cachedSystemAnimationFence requires the main thread'

Это первая проблема, вызывающая сбой. Это говорит о внутреннем методе CocoaTouch, который необходимо вызывать в основном потоке.

Вопрос лежит на вашем performSegueWithIdentifier:sender:, Все связанные с пользовательским интерфейсом вызовы должны выполняться в основном потоке. Починить это:

dispatch_async(dispatch_get_main_queue(), ^(){
    [self performSegueWithIdentifier:@"brandSegue" sender:self];
});

Исправление выявило вторую проблему:

он срабатывает, но срабатывает дважды, знаете, почему это может произойти?

Вы делаете это:

for (size_t i = 0; i < trackableCount; i++) 
{
    if (somethingTest)
    {
        [self performSegueWithIdentifier:@"brandSegue" sender:self];
    }
}

Кто сказал, что в цикле for вы не действительны несколько раз? somethingTest?

Чтобы это исправить (я говорю о логике, я не делал dispatch_async(dispatch_get_main_queue(){()} часть, чтобы избежать добавления шума в алгоритм).

//Declare a var before the for loop
BOOL seguedNeedsToBeDone = FALSE;
for (size_t i = 0; i < trackableCount; i++) 
{
    if (somethingTest)
    {
        seguedNeedsToBeDone = TRUE;
    }
}
//Perform the segue after the for loop if needed
if (seguedNeedsToBeDone)
{
    [self performSegueWithIdentifier:@"brandSegue" sender:self];
}

Следующая проблема, передача данных в Destination ViewController:

JSONViewController *destViewController = segue.destinationViewController;
destViewController.brand = @"something";

Вы смешиваете Swift & Objective-C, так как XCode жаловался на незнание brand быть собственностью JSONViewController объект, вам нужно было добавить @objc до объявления вар. Более подробный ответ можно найти здесь.

Наконец, совет для передачи ваших данных для цикла использует отправителя (это быстрее с точки зрения кодирования, чем создание другого var и т. Д.):

//Calling the performSegue with custom value to pass
[self performSegueWithIdentifier:@"brandSegue" sender:someVarToSend];

//Passing the custom value
destViewController.brand = someVarToSend;

Я думаю, что более безопасный способ - это использовать navigationController?.PushViewController(_:animated:) вместо использования segues.

Другие вопросы по тегам