DDModel 1.2.2

DDModel 1.2.2

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

DeJohn Dong 维护。



DDModel 1.2.2

  • 作者:
  • DeJohn Dong

备注:我的英语并非100%流利,但我正在努力提高。

这是一个 HTTP-JSON-ORM-Persisent 对象套件。

DDModel 继承自 SQLitePersisentObject,因此您可以立即将对象保存到 SQLite 中。
DDModel 包裹了 HTTP 请求,减少了 UIViewController 与 HTTP 代码的耦合,在您使用 DDModelKit 时,无需再为项目中的 HTTP 请求打包而烦恼。
您的开发将会变得简单。

如果您需要支持 iOS 6.0,请使用版本 0.x,现在我将更多地专注于 1.x 版本,1.x 版本需要 iOS 7.0 及以上。
1.0 使用 NSURLSession 替代 NSURLConnection

安装

作为替代,您还可以将 DDModel / Classes 中的文件直接拖入您的项目中。然后您应该克隆以下仓库:AFNetworkingXMLDictionaryJTObjectMappingSQLitePersistentObjectMBProgressHUD

用法

为了运行示例项目;首先将仓库克隆,然后从项目目录运行 pod install

1. 在您的项目中导入 DDModelKit.h

2. 在您的全局对象中初始化一个 DDModelHttpClient,例如AppDelegate;例如

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    [DDModelHttpClient startWithURL:@"https://api.app.net/" delegate:self]; // initialzie a DDModelHttpClient

    return YES;
}

您可以通过以下方式设置响应类型:[DDModelHttpClient sharedInstance].type = DDResponseXML。这样 httpClient 将处理响应数据类型为 XML。

若要处理 HTTP 请求参数或响应字符串,请实现 Protocol 方法 - (NSDictionary *)encodeParameters:(NSDictionary *)params;- (NSString *)decodeResponseString:(NSString *)responseString;

如果您在 API 中有自定义业务逻辑,应实现 Protocol 方法 - (BOOL)checkResponseValueAvailable:(NSDictionary *)values failure:(DDResponsesFailureBlock)failure

例如

#pragma mark - DDHttpClient Delegate Method

- (NSDictionary *)encodeParameters:(NSDictionary *)params{

    // encode the the paramters
    NSMutableDictionary *finalParams = [NSMutableDictionary dictionaryWithDictionary:params];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.dateFormat = @"yyyyMMddHHmmss";
    NSString *times = [formatter stringFromDate:[NSDate date]];
    [finalParams setObject:times forKey:@"time"];
    NSString *parameterString = [self ddEncode:finalParams];
    NSString *beforeSign = [NSString stringWithFormat:@"%@&%@&%@",PLATFORM,APP_KEY,parameterString];
    [finalParams setObject:[beforeSign md5] forKey:@"sign"];
    return finalParams;
}

- (NSString *)decodeResponseString:(NSString *)responseString{
    NSLog(@"responseString = %@",responseString);
    return responseString;
}

- (BOOL)checkResponseValueAvailable:(NSDictionary *)values
                            failure:(DDResponseFailureBlock)failure{
    // handler your owner business logic
    if([[values objectForKey:@"returnCode"] isEqualToString:@"0000"])
        return YES;
    else{
        if(failure){
            failure([NSError errorWithDomain:@"ddmodel.validate.error" code:1001 userInfo:nil],[values objectForKey:@"returnMessage"]);
        }
        return NO;
    }
}

3. 创建任何继承 DDModel 类的实体。根据 JSON 值定义属性。例如
JSON

{"created_at":"2015-03-09T06:45:45Z","num_stars":0,"num_replies":0,"source":{"link":"http://themodernink.com/portfolio/dash-for-app-net/","name":"Dash","client_id":"nxz5USfARxELsYVpfPJc3mYaX42USb2E"},"text":"K\u00f6nnen wir bitte nochmal Sonntag haben? So einen wie gestern - nur mit anderem Spielergebnis der Eintracht? ","num_reposts":0,"id":"54842887","canonical_url":"https://alpha.app.net/berenike/post/54842887","entities":{"mentions":[],"hashtags":[],"links":[]},"html":"<span itemscope=\"https://app.net/schemas/Post\">K&#246;nnen wir bitte nochmal Sonntag haben? So einen wie gestern - nur mit anderem Spielergebnis der Eintracht? </span>","machine_only":false,"user":{"username":"berenike","avatar_image":{"url":"https://d1f0fplrc06slp.cloudfront.net/assets/user/68/b6/70/68b6700000000000.gif","width":500,"is_default":false,"height":500},"description":{"text":"irgendwie is hier anders.\r\nhttp://keinnaturtalent.wordpress.com\r\nhttp://franziskanaja.tumblr.com/","html":"<span itemscope=\"https://app.net/schemas/Post\">irgendwie is hier anders.&#13;<br><a href=\"http://keinnaturtalent.wordpress.com\">http://keinnaturtalent.wordpress.com</a>&#13;<br><a href=\"http://franziskanaja.tumblr.com/\">http://franziskanaja.tumblr.com/</a></span>","entities":{"mentions":[],"hashtags":[],"links":[{"url":"http://keinnaturtalent.wordpress.com","text":"http://keinnaturtalent.wordpress.com","pos":27,"len":36},{"url":"http://franziskanaja.tumblr.com/","text":"http://franziskanaja.tumblr.com/","pos":65,"len":32}]}},"locale":"de_DE","created_at":"2013-05-26T12:20:30Z","canonical_url":"https://alpha.app.net/berenike","cover_image":{"url":"https://d2rfichhc2fb9n.cloudfront.net/image/5/77Bi7kWHejTDAceY-gaw4B0h2SF7InMiOiJzMyIsImIiOiJhZG4tdXNlci1hc3NldHMiLCJrIjoiYXNzZXRzL3VzZXIvZTEvNDcvNDAvZTE0NzQwMDAwMDAwMDAwMC5qcGciLCJvIjoiIn0","width":960,"is_default":false,"height":300},"timezone":"Europe/Berlin","counts":{"following":40,"posts":682,"followers":43,"stars":340},"type":"human","id":"108262","name":"Franziska Naja"},"thread_id":"54842887","pagination_id":"54842887"}

模型定义

@interface User : DDModel

@property (nonatomic, strong) NSNumber *id;
@property (nonatomic, copy) NSString *username;
@property (nonatomic, copy) NSString *avatarImageURLString;

@end

@interface Post : DDModel

@property (nonatomic, copy) NSString *text;
@property (nonatomic, strong) NSNumber *id;
@property (nonatomic, strong) User *user;


+ (void)getPostList:(id)params
           parentVC:(id)viewController
            showHUD:(BOOL)show
            success:(DDResponseSuccessBlock)success
            failure:(DDResponsesFailureBlock)failure;

@end

#import "Post.h"

@implementation Post

+ (NSString *)parseNode{
    return @"data";
}

// ovrride this method if your define propery is not the same key in json string. or the object contain Nested objects
+ (NSDictionary *)parseMappings{
    id userHandler = [User mappingWithKey:@"user" mapping:[User parseMappings]];
    NSDictionary *jsonMappings = @{@"user":userHandler};
    return jsonMappings;
}

// a demo method of get data
+ (void)getPostList:(id)params
           parentVC:(id)viewController
            showHUD:(BOOL)show
            success:(DDResponseSuccessBlock)success
            failure:(DDResponseFailureBlock)failure
{
    [[self class] get:@"stream/0/posts/stream/global" params:params showHUD:show parentViewController:viewController successBlock:success failureBlock:failure];
}

@end

@implementation User

+ (NSDictionary *)parseMappings{
    // support for KeyPath
    return @{@"avatar_image.url":@"avatarImageURLString"};
}

@end

4. 更多信息请查看示例项目,谢谢。

方法

DDModelHttpClient.h
/**
 *  Start a singleton HTTP client with url.
 *
 *  @param url HTTP target url
 */
+ (void)startWithURL:(NSString *)url;

/**
 *  Start a singleton HTTP client with url & delegate
 *
 *  @param url      HTTP target url
 *  @param delegate DDHttpClientDelegate
 */
+ (void)startWithURL:(NSString *)url delegate:(id<DDHttpClientDelegate>)delegate;

/**
 *  Set the HTTP header field value
 *
 *  @param keyValue keyValue
 */
+ (void)addHTTPHeaderFieldValue:(NSDictionary *)keyValue;

/**
 *  Remove the HTTP header field value
 *
 *  @param keyValue keyValue
 */
+ (void)removeHTTPHeaderFieldValue:(NSDictionary *)keyValue;

@protocol DDHttpClientDelegate <NSObject>

@optional
/**
 *  Parameter encode method if you should encode the parameter in your HTTP client
 *
 *  @param params original parameters
 *
 *  @return endcoded parameters
 */
- (NSDictionary *)encodeParameters:(NSDictionary *)params;

/**
 *  Response String decode methods in you HTTP client
 *
 *  @param responseString origin responseString
 *
 *  @return new responseString
 */
- (NSString *)decodeResponseString:(NSString *)responseString;

/**
 *  Check the response values is an avaliable value.
    e.g. You will sign in an account but you press a wrong username/password, server will response a error for you, you can catch them use this protocol methods and handle this error exception.
 *
 *  @param values  should check value
 *  @param failure failure block
 *
 *  @return true or false
 */
- (BOOL)checkResponseValueAvailable:(NSDictionary *)values failure:(DDResponseFailureBlock)failure;

@end
DDModel.h
@protocol DDMappings <NSObject>

/**
 *  Set the parse node, every subclass override the method if you want parse any node
 *
 *  @return node
 */
+ (NSString *)parseNode;

/**
 *  Handle the mappings about the json key-value transform to a model object.
 The method support for KeyPathValue. e.g. you have a  @property name, you want get value from "{user:{name:'mike',id:10011},picture:'https://xxxx/headerimage/header01.jpg'}", you just set mapping dictionary is @{@"user.name":@"name"}.
 *
 *  @return mappings
 */
+ (NSDictionary *)parseMappings;

@end

/**
 *  Get json data first from db cache then from http server by HTTP GET Mehod.
 *
 *  @param path           HTTP Path
 *  @param params         GET Paramtters
 *  @param dbResult       db cache result block
 *  @param success        success block
 *  @param failure        failre block
 *
 *  @return NSURLSessionDataTask
 */
+ (NSURLSessionDataTask *)get:(NSString *)path
                       params:(id)params
                    dbSuccess:(DDSQLiteBlock)dbResult
                      success:(DDResponseSuccessBlock)success
                      failure:(DDResponsesFailureBlock)failure;

/**
 *  Get json data first from db cache then from http server by HTTP POST Mehod.
 *
 *  @param path           HTTP Path
 *  @param params         GET Paramtters
 *  @param dbResult       db cache result block
 *  @param success        success block
 *  @param failure        failre block
 *
 *  @return NSURLSessionDataTask
 */
+ (NSURLSessionDataTask *)post:(NSString *)path
                        params:(id)params
                     dbSuccess:(DDSQLiteBlock)dbResult
                       success:(DDResponseSuccessBlock)success
                       failure:(DDResponsesFailureBlock)failure;

/**
 *  Get json data from http server by HTTP GET Mehod.
 *
 *  @param path           HTTP Path
 *  @param params         GET Paramtters
 *  @param success        success block
 *  @param failure        failre block
 *
 *  @return NSURLSessionDataTask
 */
+ (NSURLSessionDataTask *)get:(NSString *)path
                       params:(id)params
                      success:(DDResponseSuccessBlock)success
                      failure:(DDResponsesFailureBlock)failure;

/**
 *  Get json data from http server by HTTP POST Mehod.
 *
 *  @param path           HTTP Path
 *  @param params         POST Paramtters
 *  @param success        success block
 *  @param failure        failre block
 *
 *  @return NSURLSessionDataTask
 */
+ (NSURLSessionDataTask *)post:(NSString *)path
                        params:(id)params
                       success:(DDResponseSuccessBlock)success
                       failure:(DDResponsesFailureBlock)failure;

/**
 *  Upload a data stream to http server by HTTP POST Method.
 *
 *  @param path           HTTP Path
 *  @param stream         stream data
 *  @param params         POST Parameters
 *  @param userInfo       userInfo dictionary
 *  @param success        success block
 *  @param failure        failure block
 *
 *  @return NSURLSessionDataTask
 */
+ (NSURLSessionDataTask *)post:(NSString *)path
                    fileStream:(NSData *)stream
                        params:(id)params
                      userInfo:(id)userInfo
                       success:(DDUploadReponseSuccessBlock)success
                       failure:(DDResponsesFailureBlock)failure;

/**
 *  Parse self entity into a dictionary
 *
 *  @return a dictionary of self entity
 */
- (NSDictionary *)propertiesOfObject;

您可以在项目中查看更多方法,项目中也有一些类别。

更新

  • 1.1 代码重构和增加 http 客户端运行时改变 url 的特性
  • 1.0 使用 NSURLSession 替代 NSURLConnection

  • 0.4 添加数据库缓存功能

  • 0.3 添加XML解析功能
  • 0.2 添加检查API业务逻辑功能

要求

  • Xcode 6
  • iOS 5.1.1 或 Mac OSX 10.8 (0.x) 或 iOS 7.0 及以后或 OSX 10.9 (1.x)

作者

DeJohn Dong, [email protected]

许可

DDModel 可在 MIT 许可证下使用。更多信息请参见 LICENSE 文件。