mapbox / DEPRECATED-mapbox-ios-sdk

REPLACED – use https://www.mapbox.com/ios-sdk instead
https://github.com/mapbox/mapbox-gl-native
Other
322 stars 8 forks source link

NSInternalInconsistencyException on iOS8 #487

Open anayini opened 10 years ago

anayini commented 10 years ago

MapBox Release: 1.1.0 iOS Version: 1.8

When running our application on iOS8, after the tile sources load, but before they display, we are running into an application crash caused by an NSInternalInconsistencyException. No issues when running on iOS7

A stack trace excerpt:

The view hierarchy is not prepared for the constraint: <NSLayoutConstraint:0x78e67320 V:[UIImageView:0x7a479cb0]-(-476)-[_UILayoutGuide:0x7a03f4a0]> When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView _viewHierarchyUnpreparedForConstraint:] to debug.

*\ Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Impossible to set up layout with view hierarchy unprepared for constraint.'

I'm digging into this issue further but thought that I would file this here ASAP. Not sure if this is affecting other users.

Will attempt to upgrade to the latest release to see if this issue gets resolved, but we actually have a fork of 1.1.0, so I'll take a bit to get back on the right track.

If this is a known issue, I apologize and will close this.

incanus commented 10 years ago

I think you'll likely see this fixed in later versions, but I want to be sure. Let me know what you find.

anayini commented 10 years ago

Yup. Currently having issues with a missing FMDB.h file and a whole host of other unrelated issues due to the XCode6 beta. I'll ack back as soon as I know whats up

anayini commented 10 years ago

I am continuing to see this issue after bumping to 1.3.0. Any suggestions as to why this might be happening?

Exception seems to be stemming from RMMapView.m (line 559):

[viewController.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:formatString options:0 metrics:@{ @"bottomSpacing" : @(bottomSpacing) } views:views]];

incanus commented 10 years ago

When running our application on iOS8, after the tile sources load, but before they display, we are running into an application crash caused by an NSInternalInconsistencyException

Can you provide this code, like your -viewDidLoad or wherever you're setting it up so I can try the same? The map ID shouldn't matter; I can use a generic one.

anayini commented 10 years ago
    - (void)viewDidLoad {
        [super viewDidLoad];
        [self initalizeMap];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(applicationEnteredForeground:)
                                                     name:UIApplicationWillEnterForegroundNotification
                                                   object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(applicationEnteredBackground:)
                                                     name:UIApplicationDidEnterBackgroundNotification
                                                   object:nil];
        [[self teamFilter] addDelegate:self];
    }

The meat happens in initializeMap:

- (void)initalizeMap {
    if ([self mapView] != nil) {
        return;
    }
   /* A BUNCH OF BACKGROUND CODE TO GET TILESOURCES / API KEYS from a 
   PROPERTY SERVICE */
        if (tileSource != nil && [self mapView] == nil) {
            [self setMapView:[[RMMapView alloc] initWithFrame:[[self view] bounds] andTilesource:tileSource]];
            [[self mapContainer] addSubview:[self mapView]];
            [[[self mapContainer] window] layoutSubviews];
            [[self mapView] setDelegate:self];
            [[self mapView] setShowLogoBug:NO];
            [[self mapView] setHideAttribution:YES];
            [[self mapView] setShowsUserLocation:YES];
            [[self mapView] setFrame:[[self view] bounds]];
            [[self mapView] setZoom:16.0f animated:NO];
            [[self mapView] setUserTrackingMode:RMUserTrackingModeFollow];
            [[self centerOnMeButton] setEnabled:YES];
            [self updateFilterTeamsButton];
            [[self tilesourceLoadingView] setHidden:YES];
            [self updateUsersLocations];
            [[self centerOnMeButton] setMapView:[self mapView]];
        } else if (tileSource == nil && [self mapView] == nil) {
            [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(initalizeMap) userInfo:nil repeats:NO];
        }
    }];
}

Sorry if this isn't sufficient / isn't what you were asking for exactly. I actually just inherited this code, so I'm fairly unfamiliar with it.

incanus commented 10 years ago

That gives me an idea of what you're doing, at least. Two things:

  1. You shouldn't be calling [[[self mapContainer] window] layoutSubviews] as that method specifically says not to call it directly. Might be related.
  2. Check out the latest develop since you are setting up your map in viewDidLoad as this fixes some issues there (as of https://github.com/mapbox/mapbox-ios-sdk/commit/7e4797f7b681f8b23aa6dd1c87f01946b5c87197).

Otherwise, things look ok but I have a hunch that manually triggering your layout is the problem, despite working in iOS 7.