Convert Objective-C Lock to Close Fast

I successfully converted the following method from Obj-C to Swift:

After learning how blocks are replaced by closures in Swift.

Obj-C:

- (RACSignal *)fetchCurrentConditionsForLocation:(CLLocationCoordinate2D)coordinate {
    NSString *urlString = [NSString stringWithFormat:@"http://api.openweathermap.org/data/2.5/weather?lat=%f&lon=%f&units=imperial", coordinate.latitude, coordinate.longitude];
    NSURL *url = [NSURL URLWithString:urlString];

    return [[self fetchJSONFromURL:url] map:^(NSDictionary *json) {
        return [MTLJSONAdapter modelOfClass:[WXCondition class] fromJSONDictionary:json error:nil];
    }];
}

Swift:

func fetchCurrentConditionsForLocation(coordinate: CLLocationCoordinate2D) -> RACSignal {
    let urlString = NSString(format: "http://api.openweathermap.org/data/2.5/weather?lat=%f&lon=%f&units=metric", coordinate.latitude, coordinate.longitude)
    let url = NSURL.URLWithString(urlString)

    return fetchJSONFromURL(url).map { json in
        return MTLJSONAdapter.modelOfClass(WXCondition.self, fromJSONDictionary: json as NSDictionary, error: nil)
    }
}

However, it is difficult for me to convert the following return mapping block to Swift:

enter image description here

func fetchHourlyForecastForLocation(coordinate: CLLocationCoordinate2D) -> RACSignal {
    var urlString = NSString(format: "http://api.openweathermap.org/data/2.5/forecast?lat=%f&lon=%f&units=metric&cnt=12", coordinate.latitude, coordinate.longitude)
    let url = NSURL.URLWithString(urlString)

    /* Original Obj-C:

    return [[self fetchJSONFromURL:url] map:^(NSDictionary *json) {
        RACSequence *list = [json[@"list"] rac_sequence];
            return [[list map:^(NSDictionary *item) {
                return [MTLJSONAdapter modelOfClass:[WXCondition class] fromJSONDictionary:item error:nil];
            }] array];
        }];
    }
     */

    // My attempt at conversion to Swift
    // (I can't resolve `rac_sequence` properly). Kind of confused
    // as to how to cast it properly and return
    // it as an "rac_sequence" array.

    return fetchJSONFromURL(url).map { json in
        let list = RACSequence()
        list = [json["list"] rac_sequence]
        return (list).map { item in {
            return MTLJSONAdapter.modelOfClass(WXCondition.self, fromJSONDictionary: item as NSDictionary, error: nil)
        } as NSArray
    }
}

If this helps, this is what rac_sequence:

- (RACSequence *)rac_sequence {
    return [RACArraySequence sequenceWithArray:self offset:0];
}

RACArraySequence():

+ (instancetype)sequenceWithArray:(NSArray *)array offset:(NSUInteger)offset;

EDIT: The fetch method returns RACSignal not NSArray:

func fetchJSONFromURL(url: NSURL) -> RACSignal {

}
+4
source share
2 answers

It looks like you just forgot the return type in the function declaration. The declaration should look something like this:

func fetchHourlyForecastForLocation(coordinate: CLLocationCoordinate2D) -> RACSignal { //...rest of function

, as NSArray return . , !

0

:

func fetchHourlyForecastForLocation(coordinate: CLLocationCoordinate2D,completion:(AnyObject) -> Void)  {

   //after getting the NSArray (maping)
   completion(_array)
}
0

Source: https://habr.com/ru/post/1544584/


All Articles