问答详情
源自:2-7 ReactiveCocoa定位程序

对于失败的信号没有处理

- (void)setup {

    //定位

    _locationManager = [[DellocCLLocationManager alloc] init];

    _geoCoder = [[CLGeocoder alloc] init];

    _locationManager.delegate = self;

    _locationManager.desiredAccuracy = kCLLocationAccuracyBest;

    _locationManager.distanceFilter = 1.0;

    _currentLocation=[[CLLocation alloc]initWithLatitude:31.232032 longitude:121.476173];

    

    @weakify(self);

    

    [[[[[self authorizedSignal] filter:^BOOL(id value) {

        return [value boolValue];

    }] flattenMap:^RACStream *(id value) {

         @strongify(self);

        return [[[[[[self rac_signalForSelector:@selector(locationManager:didUpdateLocations:) fromProtocol:@protocol(CLLocationManagerDelegate)] map:^id(id value) {

            CLLocation *firstLocation= [value[1] firstObject];

            CLLocationCoordinate2D coordinate = [JZLocationConverter wgs84ToGcj02:firstLocation.coordinate];

            CLLocation *correctLocation=[[CLLocation alloc]initWithLatitude:coordinate.latitude longitude:coordinate.longitude];

            return correctLocation;

        }] merge:[[self rac_signalForSelector:@selector(locationManager:didFailWithError:) fromProtocol:@protocol(CLLocationManagerDelegate)] map:^id(id value) {

            return [RACSignal error:value[1]];

        }]] take:1] initially:^{

            @strongify(self);

            [self.locationManager startUpdatingLocation];

        }] finally:^{

            @strongify(self);

            [self.locationManager stopUpdatingLocation];

        }];

    }] flattenMap:^RACStream *(id value) {

        

        if (![value isKindOfClass:[CLLocation class]]) {

            return  [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

                [subscriber sendNext:@"定位失败"];

                [subscriber sendCompleted];

                return [RACDisposable disposableWithBlock:^{

                    

                }];

            }];

        }

        CLLocation *firstLocation= value;

        return  [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

            @strongify(self);

            [self.geoCoder reverseGeocodeLocation:firstLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {

                if (error) {

                    [subscriber sendNext:error];

                }else{

                    [subscriber sendNext:[placemarks firstObject]];

                    [subscriber sendCompleted];

                }

            }];

            return [RACDisposable disposableWithBlock:^{

                

            }];

        }];

    }] subscribeNext:^(id x) {

        NSLog(@"%@",x);

    }];

}

http://img.mukewang.com/58c351670001a59f08530468.jpg



提问者:Blank_佐毅 2017-03-11 09:23

个回答

  • zsy78191
    2017-03-30 00:10:55
    已采纳

    这里判断不是 CLLocation 类型来判断的, 可以使用 sendError 。我也忘了录课时候为什么使用sendnext了。

  • 嘿o大远
    2017-04-18 18:08:56

    我这边这么处理的..

      RACSignal *locationSignal = [[[[self authorizedSignal] filter:^BOOL(id  _Nullable value) {

            //判断是否有权限

            return [value boolValue];

        }] flattenMap:^__kindof RACSignal * _Nullable(id  _Nullable value){

            //监听地址刷新的状态

            return [[[[[[self rac_signalForSelector:@selector(locationManager:didUpdateLocations:) fromProtocol:@protocol(CLLocationManagerDelegate)] map:^id _Nullable(id  _Nullable value) {

                return value[1];

                //混合错误监听

            }] merge:[[self rac_signalForSelector:@selector(locationManager:didFailWithError:) fromProtocol:@protocol(CLLocationManagerDelegate)] map:^id _Nullable(id  _Nullable value) {

                //返回错误

                return [RACSignal error:value[1]];

            }]] take:1] initially:^{

                //initially 在所有之前开始

                [self.manager startUpdatingLocation];

            }] finally:^{

                //finally 处理完之后

                [self.manager stopUpdatingLocation];

            }];

        }] flattenMap:^__kindof RACSignal * _Nullable(id  _Nullable value) {

            

            return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {

                if ([[value class] isSubclassOfClass:[RACErrorSignal class]]) {

                    [subscriber sendError:value];

                }else{

                    CLLocation *location = [value firstObject];

                    [self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {

                        if (error) {

                            [subscriber sendError:error];

                        }else{

                            [subscriber sendNext:[placemarks firstObject]];

                            [subscriber sendCompleted];

                        }

                    }];

                }

                return [RACDisposable disposableWithBlock:^{

                }];

            }];

        }];


  • 游城十代2dai
    2017-03-29 18:30:34

    和你不太一样的地方就是我把你手动该的 RACStream 的返回值改成了 id 下面贴上我的代码吧:

    - (void)setup {
        //定位
        _locationManager = [[CLLocationManager alloc] init];
        _geoCoder = [[CLGeocoder alloc] init];
        _locationManager.delegate = self;
        _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        _locationManager.distanceFilter = 1.0;
        _currentLocation=[[CLLocation alloc]initWithLatitude:31.232032 longitude:121.476173];
        
        @weakify(self);
        
        [[[[[self authorizedSignal] filter:^BOOL(id value) {
            return [value boolValue];
        }] flattenMap:^id (id value) {
            @strongify(self);
            return [[[[[[self rac_signalForSelector:@selector(locationManager:didUpdateLocations:) fromProtocol:@protocol(CLLocationManagerDelegate)] map:^id(id value) {
                CLLocation *firstLocation= [value[1] firstObject];
                CLLocationCoordinate2D coordinate = firstLocation.coordinate;
                CLLocation *correctLocation=[[CLLocation alloc]initWithLatitude:coordinate.latitude longitude:coordinate.longitude];
                return @(22);
            }] merge:[[self rac_signalForSelector:@selector(locationManager:didFailWithError:) fromProtocol:@protocol(CLLocationManagerDelegate)] map:^id(id value) {
                return [RACSignal error:value[1]];
            }]] take:1] initially:^{
                @strongify(self);
                [_locationManager startUpdatingLocation];
            }] finally:^{
                @strongify(self);
                [_locationManager stopUpdatingLocation];
            }];
        }] flattenMap:^id (id value) {
            if (![value isKindOfClass:[CLLocation class]]) {
                return  [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
                    [subscriber sendNext:@"定位失败"];
                    [subscriber sendCompleted];
                    return [RACDisposable disposableWithBlock:^{
                        
                    }];
                }];
            }
            CLLocation *firstLocation= value;
            return  [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
                @strongify(self);
                [_geoCoder reverseGeocodeLocation:firstLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
                    if (error) {
                        [subscriber sendNext:error];
                    }else{
                        [subscriber sendNext:[placemarks firstObject]];
                        [subscriber sendCompleted];
                    }
                }];
                return [RACDisposable disposableWithBlock:^{
                    
                }];
            }];
        }] subscribeNext:^(id x) {
            NSLog(@"%@",x);
        }];
    }


  • 游城十代2dai
    2017-03-29 18:27:54

    我用你的代码实验一下...走了啊..我把

    locationManager:didUpdateLocations:

    这个方法的时候你 return 的

    correctLocation

    这个位置的值直接用 @222 这么一个 NSNumber 类型替换了, 运行的时候走了定位失败...