3

我正在寻找将一个简单的objectiveC类(甚至不是现在它只是函数中的一些vars)转换为JSON,以便可以在服务器端将其发送并插入到java对象中。

该类可能具有以下字段;

LatLng locationA // a simple POJO with either float or long to represent lat and long. 
LatLng locationA
float someFloat

在我试图将所有内容打包到 NSDictonary 的那一刻。传递浮点数不起作用,所以我必须将它们转换为 NSStrings。所以在服务器端,它们会以字符串的形式出现......这并不理想。

CLLocationCoordinate2D location = ... ;
float lat = location.latitude;
float lng = location.longitude;

float aFloat = 0.12434f;
NSString *aFloatstr = [NSString stringWithFormat:@"%f", aFloat];

NSString *latStr = [NSString stringWithFormat:@"%f", lat];
NSString *lngStr = [NSString stringWithFormat:@"%f", lng];

NSDictionary *locationDictionary =
    [NSDictionary dictionaryWithObjectsAndKeys:
        latStr , @"latitude",
        lngStr, @"longitude",
        nil];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                locationDictionary, @"locationA",
                                locationDictionary, @"locationB",
                                aFloatstr,@"aFloat",
                                nil];
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:&error];

NSString *str = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(@"%@",str);

将 CLLocationCoordinate2Ds 放入 NSDictionary 的最佳方法是什么?

如何将原始类型、长浮点数等添加到 NSDictionary?

4

3 回答 3

4

与其把纬度和经度放进去NSString,你会有更好的运气NSNumber。遇到NSJSONSerialization时,NSNumber它不会像引用字符串那样引用值(这是您在传输数字时想要的,对吧?)。

您还需要使用double, notfloat来表示纬度和经度,因为这就是它们在内部的表示方式。无需放弃精度。

[NSNumber numberWithDouble:lat]
[NSNumber numberWithDouble:lng]
[NSNumber numberWithFloat:aFloat]

由于实例NSNumber是对象,因此您可以NSDictionary毫无问题地存储它们。

于 2013-03-30T03:44:52.347 回答
1

使用NSNumber而不是字符串来包装float值,例如:

NSDictionary *locationDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                          [NSNumber numberWithFloat:lat] , @"latitude",
                          [NSNumber numberWithFloat:lng], @"longitude", nil];

这样,NSJSONSerialization将正确地将它们编码为数值。

于 2013-03-30T03:44:58.947 回答
0

结构

Neat way of doing this is to create category for NSValue that understands your struct. In your case it's CLLocationCoordinate2D, but could be any really. Here is snippet from Apple's own documentation explaning usage of NSValue:

// NSValue+Polyhedron.h
typedef struct {
    int numFaces;
    float radius;
} Polyhedron;

@interface NSValue (Polyhedron)
+ (instancetype)valueWithPolyhedron:(Polyhedron)value;
@property (readonly) Polyhedron polyhedronValue;
@end


// NSValue+Polyhedron.m
@implementation NSValue (Polyhedron)
+ (instancetype)valueWithPolyhedron:(Polyhedron)value
{
    return [self valueWithBytes:&value objCType:@encode(Polyhedron)];
}
- (Polyhedron) polyhedronValue
{
    Polyhedron value;
    [self getValue:&value];
    return value;
}
@end

From here usage is quite trivial. To create boxed NSValue:

NSValue *boxedPolyhedron = [NSValue valueWithPolyhedron:yourStruct];

Now you can put boxedPolyhedron whenever NSValue can go, NSArray, NSDictionary, NSSet, and many more, plus al the mutable versions.

To get struct back:

Polyhedron polyStruct = [boxedPolyhedron polyhedronValue];

That's it.

As a bonus, this works for any C type, not only for structs.

floats, longs, etc.

As mentioned above, could do same as above. But, for numbers, you could use NSNumber which is actually a subclass if NSValue with all popular methods already implemented. Here is a list of types you can box by instantiating NSNumber:

+ (NSNumber *)numberWithChar:(char)value;
+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
+ (NSNumber *)numberWithShort:(short)value;
+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
+ (NSNumber *)numberWithInt:(int)value;
+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
+ (NSNumber *)numberWithLong:(long)value;
+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
+ (NSNumber *)numberWithLongLong:(long long)value;
+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
+ (NSNumber *)numberWithFloat:(float)value;
+ (NSNumber *)numberWithDouble:(double)value;
+ (NSNumber *)numberWithBool:(BOOL)value;
+ (NSNumber *)numberWithInteger:(NSInteger)value;
+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value;

In similiar fashion you un-box values using [yourNumber longValue], [yourNumber floatValue], etc.

Hope that helps.

于 2015-07-29T11:53:45.023 回答