通用方法的同步调用Web API服务

时间:2013-09-26 19:38:15

标签: restkit restkit-0.20

我使用RestKit版本0.20.3来制作一个在许多其他地方使用的泛型方法。问题是该方法的返回值总是为零,因为“返回位置”;语句在[objectManager getObjectsAtPath ...]方法的Success回调函数之前执行(参见下面的代码)。

我想要“返回位置”;语句必须WAIT为块变量“location”填充来自[objectManager getObjectsAtPath ...]方法内的Success回调函数的数据。我怎样才能做到这一点?

感谢您的帮助。

我的通用方法如下:

-(KNSunGoogleLatitudeLongitudeGeometryLocation*)getSynchronouslyLatitudeLongitudeWithAddress:(NSString*)address
{
    __block KNSunGoogleLatitudeLongitudeGeometryLocation* location = [[KNSunGoogleLatitudeLongitudeGeometryLocation alloc] init];


    NSURL *baseURL = [NSURL URLWithString:@"http://maps.googleapis.com/maps/api"];
    AFHTTPClient * client = [AFHTTPClient clientWithBaseURL:baseURL];
    [client setDefaultHeader:@"Accept" value:RKMIMETypeJSON];
    RKObjectManager *objectManager = [[RKObjectManager alloc] initWithHTTPClient:client];


    //1. KNSunGoogleLatitudeLongitudeGeometryLocation

    RKObjectMapping *locationMapping = [RKObjectMapping mappingForClass:[KNSunGoogleLatitudeLongitudeGeometryLocation class]];
    [locationMapping addAttributeMappingsFromArray:@[@"lat", @"lng"]];


    //2. KNSunGoogleLatitudeLongitudeGeometry

    RKObjectMapping *geometryMapping = [RKObjectMapping mappingForClass:[KNSunGoogleLatitudeLongitudeGeometry class]];

    //3. KNSunGoogleLatitudeLongitude

    RKObjectMapping *latLongMapping = [RKObjectMapping mappingForClass:[KNSunGoogleLatitudeLongitude class]];



    //4. property/relationship mapping

    [geometryMapping addPropertyMapping:[RKRelationshipMapping
                                         relationshipMappingFromKeyPath:@"location"
                                         toKeyPath:@"location"
                                         withMapping:locationMapping]];

    [latLongMapping addPropertyMapping:[RKRelationshipMapping
                                        relationshipMappingFromKeyPath:@"geometry"
                                        toKeyPath:@"geometry"
                                        withMapping:geometryMapping]];



    // 6. response
    RKResponseDescriptor * responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:latLongMapping
                                                                                             method:RKRequestMethodGET
                                                                                        pathPattern:nil
                                                                                            keyPath:@"results"
                                                                                        statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
    // 7
    [objectManager addResponseDescriptor:responseDescriptor];



    NSDictionary *queryParams;
    queryParams = [NSDictionary dictionaryWithObjectsAndKeys:address, @"address", @"false", @"sensor", nil];


    // 6

    [objectManager getObjectsAtPath:@"http://maps.googleapis.com/maps/api/geocode/json"
                         parameters:queryParams
                            success:^(RKObjectRequestOperation * operaton, RKMappingResult *mappingResult)
     {

             //-----------
             NSArray* results = [mappingResult array];
             KNSunGoogleLatitudeLongitude* result0 = [results objectAtIndex:0];
             KNSunGoogleLatitudeLongitudeGeometry* geometry = result0.geometry;

             location= geometry.location;

             NSLog(@"lat=%@, long=%@", location.lat, location.lng);


     }
                            failure:^(RKObjectRequestOperation * operaton, NSError * error)
     {
         NSLog (@"failure: operation: %@ \n\nerror: %@", operaton, error);
     }];


    return location;  // note: ALWAYS RETURNs nil 
}

1 个答案:

答案 0 :(得分:1)

你需要改变你想要的东西,因为这是一个糟糕的设计。在请求进行过程中,您不应阻止请求者。相反,您应该将块传递给从传递给RestKit的块执行的常规方法。这允许您正确地尊重请求的异步性质。

如果您确实想继续阻止,可以使用信号量来查看。但是,你需要自己管理它。并且你无法在主线程上触发请求。这些是一般使用的重大障碍,可能会在将来引发您的问题。