Matt Hammond
Matt Hammond

Reputation: 785

Attempting to segue from Objective-C to Swift VC

i'm trying to segue from objective-c to swift.

However when I try this using the object below I receive the following error

enter image description here

I don't know what i'm doing wrong, i've setup the segue on the storyboard and assigned it to the same ID, created the prepare function and the perform.

- (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;
  }
}

EDIT - ERROR MESSAGE

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) 

Upvotes: 1

Views: 462

Answers (2)

Alexey Savchenko
Alexey Savchenko

Reputation: 889

I guess the more safe way is to use navigationController?.pushViewController(_:animated:), instead of using segues.

Upvotes: 0

Larme
Larme

Reputation: 26066

After discussion in Chat and fixing various issues, I'll take them one by one:

> *** 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'

That's the first issue causing a crash. This is talking about an internal method of CocoaTouch needed to be called in main thread.

The issue lies on your performSegueWithIdentifier:sender:. All UI related calls have to be done in main thread. To fix it:

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

Fixing this revealed a second issue:

it segues but it trigger twice, do you know why this may happen?

You are doing this:

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

Who said that in your for loop you don't valid multiple times somethingTest?

To fix it (I'm talking about the logic, I didn't do the dispatch_async(dispatch_get_main_queue(){()} part to avoid adding noise to the algorithm).

//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];
}

Next issue, passing data to the Destination ViewController:

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

You are mixing Swift & Objective-C, since XCode was complaining about not knowing brand being a property of JSONViewController object, you needed to add @objc before the declaration of the var. More detailed answer can be found here.

Finally, a tip to pass the data of you for loop is using the sender (it's faster in term of coding than creating another var, etc.):

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

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

Upvotes: 1

Related Questions