Peter
Peter

Reputation: 49

Is there any way to return a value from a block in Objective-C?

As I said in title, is there any way to return a value from a block?

This is PDDokdo class

@implementation PDDokdo
-(NSString *)getCurrentTemperature {
    WeatherPreferences * weatherPrefs = [NSClassFromString(@"WeatherPreferences") sharedPreferences];
    WATodayAutoupdatingLocationModel *todayModel = [[NSClassFromString(@"WATodayAutoupdatingLocationModel") alloc] init];
    [todayModel setPreferences:weatherPrefs];
    City *city = todayModel.forecastModel.city;

    __block double temp = 0;
    __block long long conditionCode = 0;
    [[NSClassFromString(@"TWCLocationUpdater") sharedLocationUpdater] updateWeatherForLocation:city.location city:city isFromFrameworkClient:true withCompletionHandler:^{
        temp = [[city temperature] celsius];
        conditionCode = [city conditionCode];

        return [NSString stringWithFormat:@"%.f°C", round(temp)];
    }];

    return @":(";
}
@end

I want it to return a value in a block, not the end of the method.

Since PDDokdo is a sub-class of NSObject, I get the result like below in another class.

NSString *temperature = [[PDDokdo alloc] getCurrentTemperature];

To sum up, I want -(NSString *)getCurrentTemperature to return [NSString stringWithFormat:@"%.f°C", round(temp)] in a block instead of :(, so that I can get the value from another class.

Upvotes: 1

Views: 70

Answers (1)

Roman Podymov
Roman Podymov

Reputation: 4521

getCurrentTemperature should return void and accept a block as a parameter:

typedef void(^CurrentTemperatureCompletion)(NSString *);

@implementation PDDokdo
-(void)getCurrentTemperature:(CurrentTemperatureCompletion)completion {
    WeatherPreferences * weatherPrefs = [NSClassFromString(@"WeatherPreferences") sharedPreferences];
    WATodayAutoupdatingLocationModel *todayModel = [[NSClassFromString(@"WATodayAutoupdatingLocationModel") alloc] init];
    [todayModel setPreferences:weatherPrefs];
    City *city = todayModel.forecastModel.city;

    __block double temp = 0;
    __block long long conditionCode = 0;
    [[NSClassFromString(@"TWCLocationUpdater") sharedLocationUpdater] updateWeatherForLocation:city.location city:city isFromFrameworkClient:true withCompletionHandler:^{
        temp = [[city temperature] celsius];
        conditionCode = [city conditionCode];

        NSString* result = [NSString stringWithFormat:@"%.f°C", round(temp)];
        completion(result);
        return result;
    }];
}
@end

In such case you don't need to wait for updateWeatherForLocation to complete.

This is how you can call it:

[[[PDDokdo alloc] init] getCurrentTemperature:^(NSString * temperature) {
    NSLog(@"%@", temperature);
}];

Upvotes: 3

Related Questions