Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/43.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 根据NSURL请求的结果更新接口_Iphone_Ios_Objective C - Fatal编程技术网

Iphone 根据NSURL请求的结果更新接口

Iphone 根据NSURL请求的结果更新接口,iphone,ios,objective-c,Iphone,Ios,Objective C,我有一个应用程序,根据NSURL请求的结果更新界面。我将其设置为,当我的应用程序进入前台时,仅当当前视图控制器名为“ProfileViewController”时,才会触发请求 我的问题是,每次我从后台带回应用程序时,界面都会锁定几秒钟。我试图完全理解主线程/后台线程,但不确定在执行NSURL检查时如何使应用程序保持响应。任何帮助都会很好!谢谢 在我看来,加载方法: -(void)viewDidLoad { [super viewDidLoad]; [[NSNotificat

我有一个应用程序,根据NSURL请求的结果更新界面。我将其设置为,当我的应用程序进入前台时,仅当当前视图控制器名为“ProfileViewController”时,才会触发请求

我的问题是,每次我从后台带回应用程序时,界面都会锁定几秒钟。我试图完全理解主线程/后台线程,但不确定在执行NSURL检查时如何使应用程序保持响应。任何帮助都会很好!谢谢

在我看来,加载方法:

-(void)viewDidLoad {

    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self
    selector:@selector(appReturnsActive) name:UIApplicationDidBecomeActiveNotification
    object:nil];

    //additional code
}
- (void)appReturnsActive {

    [myTimer invalidate];
    myTimer = nil;

    //ONLY WANT TO PERFORM THE UPDATE IF VIEWING THE PROFILE VIEW CONTROLLER
    UIViewController *currentVC = self.navigationController.visibleViewController;
    NSString * name = NSStringFromClass([currentVC class]);
    if ([name isEqualToString:@"ProfileViewController"]) { 

        [activityIndicator startAnimating];
        [activityIndicatorTwo startAnimating];
        locationManagerProfile.delegate = self;
        locationManagerProfile.desiredAccuracy = kCLLocationAccuracyBest;
        [locationManagerProfile startUpdatingLocation];    
    }
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation 
*)newLocation fromLocation:(CLLocation *)oldLocation {

    CLLocation *currentLocation = newLocation;
    if (currentLocation != nil) {

        [self performSelectorOnMainThread:@selector(buttonUpdate:)
        withObject:NULL waitUntilDone:NO];

    }
}
-(void)buttonUpdate {

NSString *userLongitude =[NSString stringWithFormat:@"%.8f", 
        currentLocation.coordinate.longitude];
        NSString *userLatitude = [NSString stringWithFormat:@"%.8f", 
        currentLocation.coordinate.latitude];
        [locationManagerProfile stopUpdatingLocation];
        NSString *placeLatitude = [[NSUserDefaults standardUserDefaults]
                                   stringForKey:@"savedLatitude"];
        NSString *placeLongitude = [[NSUserDefaults standardUserDefaults]
                                    stringForKey:@"savedLongitude"];
        NSString *distanceURL = [NSString 
        stringWithFormat:@"http://www.website.com/page.php?
        lat1=%@&lon1=%@&lat2=%@&lon2=%@",userLatitude, userLongitude, placeLatitude, 
        placeLongitude];

        NSData *distanceURLResult = [NSData dataWithContentsOfURL:[NSURL 
        URLWithString:distanceURL]];

        NSString *distanceInFeet = [[NSString alloc] initWithData:distanceURLResult 
        encoding:NSUTF8StringEncoding];

        if ([distanceInFeet isEqualToString:@"1"])
        {
            UIBarButtonItem *btnGo = [[UIBarButtonItem alloc] initWithTitle:@"Button 1" 
            style:UIBarButtonItemStyleBordered target:self 
            action:@selector(actionTwo)];
            self.navigationItem.rightBarButtonItem = btnGo;

            UIBarButtonItem *btnGoTwo = [[UIBarButtonItem alloc] initWithTitle:@"Button 
            Two" style:UIBarButtonItemStyleBordered target:self 
            action:@selector(actionOne)];
            self.navigationItem.rightBarButtonItem = btnGoTwo;

            self.navigationItem.rightBarButtonItems = [NSArray arrayWithObjects:btnGo, 
            btnGoTwo, nil];
        }
}
然后在我的应用程序中返回活动方法:

-(void)viewDidLoad {

    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self
    selector:@selector(appReturnsActive) name:UIApplicationDidBecomeActiveNotification
    object:nil];

    //additional code
}
- (void)appReturnsActive {

    [myTimer invalidate];
    myTimer = nil;

    //ONLY WANT TO PERFORM THE UPDATE IF VIEWING THE PROFILE VIEW CONTROLLER
    UIViewController *currentVC = self.navigationController.visibleViewController;
    NSString * name = NSStringFromClass([currentVC class]);
    if ([name isEqualToString:@"ProfileViewController"]) { 

        [activityIndicator startAnimating];
        [activityIndicatorTwo startAnimating];
        locationManagerProfile.delegate = self;
        locationManagerProfile.desiredAccuracy = kCLLocationAccuracyBest;
        [locationManagerProfile startUpdatingLocation];    
    }
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation 
*)newLocation fromLocation:(CLLocation *)oldLocation {

    CLLocation *currentLocation = newLocation;
    if (currentLocation != nil) {

        [self performSelectorOnMainThread:@selector(buttonUpdate:)
        withObject:NULL waitUntilDone:NO];

    }
}
-(void)buttonUpdate {

NSString *userLongitude =[NSString stringWithFormat:@"%.8f", 
        currentLocation.coordinate.longitude];
        NSString *userLatitude = [NSString stringWithFormat:@"%.8f", 
        currentLocation.coordinate.latitude];
        [locationManagerProfile stopUpdatingLocation];
        NSString *placeLatitude = [[NSUserDefaults standardUserDefaults]
                                   stringForKey:@"savedLatitude"];
        NSString *placeLongitude = [[NSUserDefaults standardUserDefaults]
                                    stringForKey:@"savedLongitude"];
        NSString *distanceURL = [NSString 
        stringWithFormat:@"http://www.website.com/page.php?
        lat1=%@&lon1=%@&lat2=%@&lon2=%@",userLatitude, userLongitude, placeLatitude, 
        placeLongitude];

        NSData *distanceURLResult = [NSData dataWithContentsOfURL:[NSURL 
        URLWithString:distanceURL]];

        NSString *distanceInFeet = [[NSString alloc] initWithData:distanceURLResult 
        encoding:NSUTF8StringEncoding];

        if ([distanceInFeet isEqualToString:@"1"])
        {
            UIBarButtonItem *btnGo = [[UIBarButtonItem alloc] initWithTitle:@"Button 1" 
            style:UIBarButtonItemStyleBordered target:self 
            action:@selector(actionTwo)];
            self.navigationItem.rightBarButtonItem = btnGo;

            UIBarButtonItem *btnGoTwo = [[UIBarButtonItem alloc] initWithTitle:@"Button 
            Two" style:UIBarButtonItemStyleBordered target:self 
            action:@selector(actionOne)];
            self.navigationItem.rightBarButtonItem = btnGoTwo;

            self.navigationItem.rightBarButtonItems = [NSArray arrayWithObjects:btnGo, 
            btnGoTwo, nil];
        }
}
最后,在我的Did-Update-Location方法中,我得到了用户和位置之间的距离。如果结果等于1,则更新界面以显示不同的按钮。这就是界面冻结的地方:

-(void)viewDidLoad {

    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self
    selector:@selector(appReturnsActive) name:UIApplicationDidBecomeActiveNotification
    object:nil];

    //additional code
}
- (void)appReturnsActive {

    [myTimer invalidate];
    myTimer = nil;

    //ONLY WANT TO PERFORM THE UPDATE IF VIEWING THE PROFILE VIEW CONTROLLER
    UIViewController *currentVC = self.navigationController.visibleViewController;
    NSString * name = NSStringFromClass([currentVC class]);
    if ([name isEqualToString:@"ProfileViewController"]) { 

        [activityIndicator startAnimating];
        [activityIndicatorTwo startAnimating];
        locationManagerProfile.delegate = self;
        locationManagerProfile.desiredAccuracy = kCLLocationAccuracyBest;
        [locationManagerProfile startUpdatingLocation];    
    }
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation 
*)newLocation fromLocation:(CLLocation *)oldLocation {

    CLLocation *currentLocation = newLocation;
    if (currentLocation != nil) {

        [self performSelectorOnMainThread:@selector(buttonUpdate:)
        withObject:NULL waitUntilDone:NO];

    }
}
-(void)buttonUpdate {

NSString *userLongitude =[NSString stringWithFormat:@"%.8f", 
        currentLocation.coordinate.longitude];
        NSString *userLatitude = [NSString stringWithFormat:@"%.8f", 
        currentLocation.coordinate.latitude];
        [locationManagerProfile stopUpdatingLocation];
        NSString *placeLatitude = [[NSUserDefaults standardUserDefaults]
                                   stringForKey:@"savedLatitude"];
        NSString *placeLongitude = [[NSUserDefaults standardUserDefaults]
                                    stringForKey:@"savedLongitude"];
        NSString *distanceURL = [NSString 
        stringWithFormat:@"http://www.website.com/page.php?
        lat1=%@&lon1=%@&lat2=%@&lon2=%@",userLatitude, userLongitude, placeLatitude, 
        placeLongitude];

        NSData *distanceURLResult = [NSData dataWithContentsOfURL:[NSURL 
        URLWithString:distanceURL]];

        NSString *distanceInFeet = [[NSString alloc] initWithData:distanceURLResult 
        encoding:NSUTF8StringEncoding];

        if ([distanceInFeet isEqualToString:@"1"])
        {
            UIBarButtonItem *btnGo = [[UIBarButtonItem alloc] initWithTitle:@"Button 1" 
            style:UIBarButtonItemStyleBordered target:self 
            action:@selector(actionTwo)];
            self.navigationItem.rightBarButtonItem = btnGo;

            UIBarButtonItem *btnGoTwo = [[UIBarButtonItem alloc] initWithTitle:@"Button 
            Two" style:UIBarButtonItemStyleBordered target:self 
            action:@selector(actionOne)];
            self.navigationItem.rightBarButtonItem = btnGoTwo;

            self.navigationItem.rightBarButtonItems = [NSArray arrayWithObjects:btnGo, 
            btnGoTwo, nil];
        }
}
新方法:

-(void)viewDidLoad {

    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self
    selector:@selector(appReturnsActive) name:UIApplicationDidBecomeActiveNotification
    object:nil];

    //additional code
}
- (void)appReturnsActive {

    [myTimer invalidate];
    myTimer = nil;

    //ONLY WANT TO PERFORM THE UPDATE IF VIEWING THE PROFILE VIEW CONTROLLER
    UIViewController *currentVC = self.navigationController.visibleViewController;
    NSString * name = NSStringFromClass([currentVC class]);
    if ([name isEqualToString:@"ProfileViewController"]) { 

        [activityIndicator startAnimating];
        [activityIndicatorTwo startAnimating];
        locationManagerProfile.delegate = self;
        locationManagerProfile.desiredAccuracy = kCLLocationAccuracyBest;
        [locationManagerProfile startUpdatingLocation];    
    }
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation 
*)newLocation fromLocation:(CLLocation *)oldLocation {

    CLLocation *currentLocation = newLocation;
    if (currentLocation != nil) {

        [self performSelectorOnMainThread:@selector(buttonUpdate:)
        withObject:NULL waitUntilDone:NO];

    }
}
-(void)buttonUpdate {

NSString *userLongitude =[NSString stringWithFormat:@"%.8f", 
        currentLocation.coordinate.longitude];
        NSString *userLatitude = [NSString stringWithFormat:@"%.8f", 
        currentLocation.coordinate.latitude];
        [locationManagerProfile stopUpdatingLocation];
        NSString *placeLatitude = [[NSUserDefaults standardUserDefaults]
                                   stringForKey:@"savedLatitude"];
        NSString *placeLongitude = [[NSUserDefaults standardUserDefaults]
                                    stringForKey:@"savedLongitude"];
        NSString *distanceURL = [NSString 
        stringWithFormat:@"http://www.website.com/page.php?
        lat1=%@&lon1=%@&lat2=%@&lon2=%@",userLatitude, userLongitude, placeLatitude, 
        placeLongitude];

        NSData *distanceURLResult = [NSData dataWithContentsOfURL:[NSURL 
        URLWithString:distanceURL]];

        NSString *distanceInFeet = [[NSString alloc] initWithData:distanceURLResult 
        encoding:NSUTF8StringEncoding];

        if ([distanceInFeet isEqualToString:@"1"])
        {
            UIBarButtonItem *btnGo = [[UIBarButtonItem alloc] initWithTitle:@"Button 1" 
            style:UIBarButtonItemStyleBordered target:self 
            action:@selector(actionTwo)];
            self.navigationItem.rightBarButtonItem = btnGo;

            UIBarButtonItem *btnGoTwo = [[UIBarButtonItem alloc] initWithTitle:@"Button 
            Two" style:UIBarButtonItemStyleBordered target:self 
            action:@selector(actionOne)];
            self.navigationItem.rightBarButtonItem = btnGoTwo;

            self.navigationItem.rightBarButtonItems = [NSArray arrayWithObjects:btnGo, 
            btnGoTwo, nil];
        }
}

您的CoreLocation委托方法(例如“
didUpdateToLocation
”等)都发生在后台的次线程上

要解决问题,您应该在主线程上修改UI。你可以使用的一个简单的基础API是:

要解决您的问题,请将创建代码的按钮移动到一个单独的方法中,并从旧方法(通过CoreLocation委托协议在单独的线程上调用)通过“
performSelectorOnMainThread
”调用该新方法,这样您就可以开始了

NSData *distanceURLResult = [NSData dataWithContentsOfURL:[NSURL 
    URLWithString:distanceURL]];

是一个同步呼叫。这意味着您的代码将等待网络调用的结果继续。您应该使用NSURLConnection()或AFNetworking发出异步请求。

感谢您的响应!!!我是否应该将didUpdateLocation方法中的所有内容都放在即将创建的新方法中?我假设我会把几乎所有的东西都放在if(currentLocation!=nil)行下面。在我自己的代码中,如果我需要从后台线程中修改主线程上的UI,我会在单独的线程上尽可能多地做,以保持用户界面(和用户体验)尽可能精神饱满。似乎在工作!!一个相关的小问题。当我在新方法中包含包含currentLocation.coordinate.longitude的NSString时,我得到一个错误,我可以修复它吗?当然,您可以修复它。其中一个参数是“
withObject
”。为什么不把那串东西传过去?哇。太明显了。你太棒了!事实上,我需要更新我的问题并发布我到目前为止的代码,因为无论我做了什么,我的应用程序都会崩溃。好的,迈克尔,刚刚更新过。有什么想法吗?非常感谢。