【问题标题】:Store CLLocationCoordinate2D to NSUserDefaults将 CLLocationCoordinate2D 存储到 NSUserDefaults
【发布时间】:2013-09-25 11:28:49
【问题描述】:

我是 iphone 开发新手,我想将 CLLocationCoordinate2D 对象存储到 NSUserDefaults。 我在努力

    [defaults setObject:location forKey:@"userLocation"];

但它给出了错误'Sending CLLocationCoordinate2D to parameter of in compatible type id'

那么如何将CLLocationCoordinate2D 存储到NSUserDefaults 中? 谢谢。

【问题讨论】:

    标签: iphone ios objective-c nsuserdefaults cllocationmanager


    【解决方案1】:

    NSUserDefaults 类提供了方便的方法来访问常用类型,例如浮点数、双精度数、整数、布尔值和 URL。默认对象必须是一个属性列表,即以下实例(或集合实例的组合):NSData、NSString、NSNumber、NSDate、NSArray 或 NSDictionary。 如果要存储任何其他类型的对象,通常应该将其归档以创建 NSData 实例

    见:NSUserDefaults

    【讨论】:

    • 感谢您的回复,但现在如何归档它以创建 NSData 的实例以存储在 NSUSERDEFAULTS 中。
    【解决方案2】:

    你可以这样设置..

    CLLocationCoordinate2D coordinate; // need to set your coordinate here
    
    [[defaults setObject:[NSString stringWithFormat:@"%g",coordinate.latitude] forKey:@"latitude"] ];
    [[defaults setObject:[NSString stringWithFormat:@"%g",coordinate.longitude] forKey:@"longitude"] ];
    

    希望对你有帮助。

    【讨论】:

      【解决方案3】:

      这就是我会做的:

      NSData *data = [NSData dataWithBytes:&coordinate length:sizeof(coordinate)];
      [[NSUserDefaults standardUserDefaults] setObject:data forKey:@"key"];
      [[NSUserDefaults standardUserDefaults] synchronize];
      

      然后你可以像这样检索它:

      NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:@"key"];
      CLLocationCoordinate2D coordinate;
      [data getBytes:&coordinate length:sizeof(coordinate)];
      

      【讨论】:

      • 感谢您的回答!小心使用它来存储 CLLocation 对象,您可能会收到与将 Core Foundation 指针转换为 Objective-C 指针相关联的“EXC_BAD_ACESS code = 1”错误,稍后您将无法使用它,因为在某些情况下它指向的对象将已经被释放。看到这个帖子...stackoverflow.com/a/27848617/4018041
      • FormigaNinja,你是在讽刺吧?如果结构的大小会改变,之后数据可能无法正常恢复。
      【解决方案4】:

      正如pdrcabrod所说,

      “默认对象必须是属性列表,即NSDataNSStringNSNumberNSDateNSArrayNSDictionary的实例。”

      我用这个来存储,

          NSNumber *lat = [NSNumber numberWithDouble:location.latitude];
          NSNumber *lon = [NSNumber numberWithDouble:location.longitude];
          NSDictionary *userLocation=@{@"lat":lat,@"long":lon};
      
          [[NSUserDefaults standardUserDefaults] setObject:userLocation forKey:@"userLocation"];
          [[NSUserDefaults standardUserDefaults] synchronize];
      

      并使用访问,

          NSDictionary *userLoc=[[NSUserDefaults standardUserDefaults] objectForKey:@"userLocation"];
          NSLog(@"lat %@",[userLoc objectForKey:@"lat"]);
          NSLog(@"long %@",[userLoc objectForKey:@"long"]);
      

      【讨论】:

      • 应该是NSNumber *lat = [NSNumber numberWithDouble:location.coordinate.latitude]; NSNumber *lon = [NSNumber numberWithDouble:location.coordinate.longitude];
      【解决方案5】:

      正如其他人所说,首先将其转换为DictionaryData 对象,然后照常保存。在 Swift 中,我强烈推荐使用扩展。这是我所做的:

      extension CLLocationCoordinate2D {
      
          private static let Lat = "lat"
          private static let Lon = "lon"
      
          typealias CLLocationDictionary = [String: CLLocationDegrees]
      
          var asDictionary: CLLocationDictionary {
              return [CLLocationCoordinate2D.Lat: self.latitude,
                      CLLocationCoordinate2D.Lon: self.longitude]
          }
      
          init(dict: CLLocationDictionary) {
              self.init(latitude: dict[CLLocationCoordinate2D.Lat]!,
                        longitude: dict[CLLocationCoordinate2D.Lon]!)
          }
      
      }
      

      【讨论】:

        【解决方案6】:
        import CoreLocation
        
        // Store an array of CLLocationCoordinate2D
        func storeCoordinates(_ coordinates: [CLLocationCoordinate2D]) {
        let locations = coordinates.map { coordinate -> CLLocation in
            return CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
        }
        let archived = NSKeyedArchiver.archivedData(withRootObject: locations)
        UserDefaults.standard.set(archived, forKey: "coordinates")
        UserDefaults.standard.synchronize()
        }
        
        // Return an array of CLLocationCoordinate2D
        func loadCoordinates() -> [CLLocationCoordinate2D]? {
        guard let archived = UserDefaults.standard.object(forKey: "coordinates") as? Data,
            let locations = NSKeyedUnarchiver.unarchiveObject(with: archived) as? [CLLocation] else {
                return nil
        }
        
        let coordinates = locations.map { location -> CLLocationCoordinate2D in
            return location.coordinate
        }
                return coordinates
        }
        

        现在让我们测试一下实现:

        let testCoordinates = [
        CLLocationCoordinate2D(latitude: 0.123456789, longitude: 0.123456789),
        CLLocationCoordinate2D(latitude: 1.123456789, longitude: 1.123456789),
        CLLocationCoordinate2D(latitude: 2.123456789, longitude: 2.123456789)
        ]
        
        self.storeCoordinates(testCoordinates)
        
        let coordinates = loadCoordinates()
        print(coordinates)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-28
          相关资源
          最近更新 更多