QwikJson 1.1.8

QwikJson 1.1.8

测试已测试
语言语言 Obj-CObjective C
许可证 MIT
发布最后发布2024年6月

Logan Sease 维护。



QwikJson 1.1.8

  • 作者
  • Logan Sease

QwikJson

[![CI 状态](http://img.shields.io/travis/Logan Sease/QwikJson.svg?style=flat)](https://travis-ci.org/Logan Sease/QwikJson) 版本 许可证 平台

摘要

在我们 ReSTful API 世界中,我们始终向我们的 api 传递 JSON 对象并从中接收它们。不断将这些对象序列化为 JSON 字符串和字典,再从字典序列化到对象,可能会非常麻烦,并且可能导致您的模型类和数据处理服务开始填充样板代码解析。

为了解决这个问题,我引入了 QwikJson。这是一个强大而简单的库,用于序列化和反序列化 JSON 对象。

只需让您的模型类继承自 QwikJson,这个世界将向您敞开。

QwikJson 使对象转换为字典和字典数组(反之亦然)变得非常简单。它支持嵌套模型对象、嵌套数组模型对象、多种日期和时间格式,以及将数据和从 JSON 字符串转换的功能。

安装

QwikJson可以通过CocoaPods获取。要安装它,只需将以下行添加到您的Podfile中

pod "QwikJson"

并导入以下头文件

#import "QwikJson.h"

此pod用Objective-C编写,但与Swift项目也运作良好。

用法

As of Swift 3, all swift properties must contain the @objc tag to be visible to swift

创建一个模型类并扩展QwikJson,并添加您的字段

//menu.h
@interface Menu : QwikJson
@property(nonatomic,strong)NSString * name;
@property(nonatomic,strong)NSArray * menuItems;
@end
class Menu : QwikJson
{
    @objc var name : String?
}

现在您可以从字典和相反方向转换,更轻松了

//deserialize
menu = [Menu objectFromDictionary:dictionary];

//serialize again
dictionary = [menu toDictionary];

使用嵌套对象(即使是嵌套数组)和自定义日期序列化器

//restaurant.h
@interface Restaurant : QwikJson
@property(nonatomic,strong)NSString * image_url;
@property(nonatomic,strong)NSString * name;
@property(nonatomic,strong)NSArray * menus;
@property(nonatomic,strong)DBTimeStamp * createdAt;
@end

+(Class)classForKey:(NSString*)key
{
    if([key isEqualToString:@"menus"])
    {
        return [Menu class];
    }
    if([key isEqualToString:@"createdAt"])
    {
        return [DBTimeStamp class];
    }

    return [super classForKey:key];
}

或者用Swift

class Restaurant: QwikJson {
   @objc var imageUrl: String?
   @objc var name: String?
   @objc var menus: [Menu] = []
   @objc var createdAt: DBTimeStamp?
   
   override public class func type(forKey: String!) -> AnyClass!
   {
    if forKey == "createdAt"
    {
        return DBTimeStamp
    }
   
    if forKey == "menu"
    {
        return Menu.self
    }

    return super.type(forKey: forKey)
   }
}

在序列化或反序列化时执行特定逻辑。

//override in subclass to perform some custom deserizliation or change property keys
-(void)writeObjectFrom:(NSDictionary*)inputDictionary forKey:(NSString*)key toProperty:(NSString*)property
{
    //adjust the property name since the database is formatted with _'s instead of camel case
    if([property isEqualToString:@"menu_items"])
    {
        property = @"menuItems";
    }

    [super writeObjectFrom:inputDictionary forKey:key toProperty:property];
}

//override in subclass to specify a new key or perform some custom action on serialize
-(void)serializeObject:(NSObject*)object withApiKey:(NSString*)apiKey fromKey:(NSString*)objectKey toDictionary:(NSMutableDictionary*)dictionary
{
    //adjust the property name since the database is formatted with _'s instead of camel case
    if([objectKey isEqualToString:@"menuItems"])
    {
        apiKey = @"menu_items";
    }
    [super serializeObject:object withApiKey:apiKey fromKey:objectKey toDictionary:dictionary];
}

定义一个属性映射来指定模型对象和API中对象字段的名称不同。这在您使用保留关键字如“description”或API返回下划线名称字段时可能是必要的。

+(NSDictionary<NSString*,NSString*>*)apiToObjectMapping
{
    //specify custom field mappings for qwikJsonObjects
    return @{@"description": @"descriptionText"};
}

定义一个临时属性数组来指定在序列化时不应写入的属性。请注意,某些字段默认标记为临时。这些如下:#define kDefaultTransientProperties @[@"superclass", @"hash", @"debugDescription", @"description"] 如果您想传递这些变量中的任何一个,只需使用apiToObjectMapping方法重命名字段即可。

+(NSArray<NSString*>*)transientProperties
{
    return @{@"someCalculatedFieldName"};
}

直接写入首选项设置

[self.restaurant writeToPreferencesWithKey:@"data"];
self.restaurant = [Restaurant readFromPrefencesWithKey:@"data"];

转换成字符串和相反操作

@interface NSDictionary (QwikJson)
-(NSString*)toJsonString;
+(NSDictionary*)fromJsonString:(NSString*)json;
@end

@interface NSArray (QwikJson)
-(NSString*)toJsonString;
+(NSArray*)fromJsonString:(NSString*)json;
@end

支持的字段类型

  • 布尔值 / Bool
  • NSString / String
  • NSArray / []
  • NSNumber
  • NSDecimalNumber(但您必须在classForKey:中指定类型)
  • 注意,如果您在使用Swift并且正在使用布尔值,请使用Bool。不要使用Bool?,因为在Objective-C中不能表达可选布尔值。

  • 另一个注意:当使用Swift 4时,所有Swift属性都必须以前缀@objc开头,以便它们可读。

自定义日期序列化器,处理解析 Various 日期/时间格式

DBDate

2015-12-30

DBDateTime

2015-01-01T10:15:30

DBTimeStamp

0312345512

DBTime

12:00:00

请注意,您可以通过在日期类上调用 setDateFormat 来自定义日期格式。或者,如果主要格式解析失败,可以调用 setAlternateDateFormats 提供一个交替格式的数组

[DBDate setDateFormat:@"MM/DD/YYYY"];

对于 DBTimeStamp,如果您 API 返回的是毫秒而不是秒,可以设置一个乘数以支持毫秒格式

[DBTimeStamp setTimeStampMultiplier: 1000.0f];

数字/字符串兼容性

如果您的 API 有时在数字字段中返回字符串,或者您正在支持 NSDecimalNumber 以支持高精度数字(在这种情况下,您的 API 可能将它们序列化为字符串),则可以使用 classForKey 方法指定类型,解析器将检查以确保正确反序列化

@property NSNumber* amount;
@property NSDecimalNumber* cost;

//restaurant.m
+(Class)classForKey:(NSString*)key
{
    if([key isEqualToString:@"amount"])
    {
        return [NSNumber class];
    }
    if([key isEqualToString:@"cost"])
    {
        return [NSDecimalNumber class];
    }

    return [super classForKey:key];
}

序列化Null

默认情况下不会序列化Null,但存在全局设置以及每个对象的设置来决定是否应该序列化 Null。

    [QwikJson setSerializeNullsByDefault:YES];
    object.serializeNulls = kNullSerializationSettingDoNotSerialize;

支持NSManagedObject

如果您正在使用CoreData并希望使用QwikJson,也可以简单地导入并扩展QwikJsonManagedObject而不是直接使用QwikJson。

Android

在这个仓库和android目录中,您还将找到一个非常相似的类,QwikJson.java,它为Android和其他Java平台提供了类似的功能。

更多提示

除了解析和序列化JSON之外,与其他RESTful API通信的另一个关键部分是良好的网络库。请考虑使用QwikHttp与此库结合使用,以完善您的工具集。[A链接](https://github.com/logansease/QwikHttp)

同时,请检查SeaseAssist pod,它提供了一大堆辅助工具来使您的iOS代码编写更加简单![A链接](https://github.com/logansease/SeaseAssist)

作者

Logan Sease, [B电子邮件](/cdn-cgi/l/email-protection#d8b4abbdb9abbd98bfb5b9b1b4f6bbb7b5)

许可证

QwikJson 在 MIT 许可下可用。有关更多信息,请参阅 LICENSE 文件。