【iOS】FMDB封装,查询自动mapping

sqlite几乎所有的App都会用到,但是系统自带的sqlite API是用C语言写的,非常不友好,用起来非常不便,通常我们使用第三方封装好的工具,例如:FMDB(https://github.com/ccgus/fmdb

FMDB的提供了一种更简单,方便的API,并且还提供了线程安全的队列FMDatabaseQueue用于数据库的读写,关于FMDB的使用,参见github上的描述

在使用FMDB查询表的时候的时候我们一般用下面方式

  1、定义一个数据模型PersonModel

@interface PersonModel : NSObject

@property (nonatomic, assign) NSInteger peopleId;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *gender;
@property (nonatomic, assign) float weight;
@property (nonatomic, assign) double height;
@property (nonatomic, assign) short age;
@property (nonatomic, assign) long score;
@property (nonatomic, strong) NSDate *createTime;
@property (nonatomic, assign) BOOL married;
@property (nonatomic, strong) NSData *desc;

@end

  2、插入数据

    NSString *sql = @"insert into People(name, gender, weight, height, age, score, createTime, married, desc) values(?,?,?,?,?,?,?,?,?)";

    NSString *text = @"dataValue";
    NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];

    NSArray *param = @[@"bomo", @"male", @70, @175l, @22, @123, [NSDate date], @NO, data];

    [_queue inDatabase:^(FMDatabase *db) {
        [db executeUpdate:sql withArgumentsInArray:param];
    }];

  3、查询

    NSString *sql = @"select * from People";

    __block NSMutableArray *people = [NSMutableArray array];

    [_queue inDatabase:^(FMDatabase *db) {
        FMResultSet *rs = [db executeQuery:sql];
        while ([rs next]) {
            person.name = [rs stringForColumn:@"name"];
            person.gender = [rs stringForColumn:@"gender"];
            person.height = [rs doubleForColumn:@"height"];
            person.score = [rs longForColumn:@"score"];
            person.createTime = [rs dateForColumn:@"createTime"];
            person.married = [rs boolForColumn:@"married"];
            person.desc = [rs dataForColumn:@"desc"];

            //下面几种方式读取数据会导致数据类型不一致的问题
            //person.peopleId = [rs intForColumn:@"peopleId"];
            //person.age = [rs intForColumn:@"age"];
            //person.weight = [rs doubleForColumn:@"weight"];
            [people addObject:person];
        }

        [rs close];
    }];        

这里的查询方法需要对每一个属性进行读取和赋值,并且可能有数据类型不一致的问题,比如 读取出来的int 赋值给NSInteger 类型,double类型赋值给float类型,下面我们对查询方法进行改造,让其变得更通用,可以自动映射查询结果到Model,并提供数据库列名到属性名之间的映射

  1、定义映射协议

#import <Foundation/Foundation.h>

//实现数据库列名到model属性名的映射
@protocol ColumnPropertyMappingDelegate <NSObject>

@required
- (NSDictionary *)columnPropertyMapping;

@end

  2、修改PersonModel模型

#import <Foundation/Foundation.h>
#import "ColumnPropertyMappingDelegate.h"

@interface PersonModel : NSObject <ColumnPropertyMappingDelegate>

@property (nonatomic, assign) NSInteger peopleId;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *gender;
@property (nonatomic, assign) float weight;
@property (nonatomic, assign) double height;
@property (nonatomic, assign) short age;
@property (nonatomic, assign) long score;
@property (nonatomic, strong) NSDate *createTime;
@property (nonatomic, assign) BOOL married;
@property (nonatomic, strong) NSData *desc;

@end

@implementation PersonModel

- (NSDictionary *)columnPropertyMapping
{
    return @{@"id": @"peopleId",
             @"str1": @"name",
             @"str2": @"gender",
             @"float1": @"weight",
             @"double1": @"height",
             @"short1": @"age",
             @"long1": @"score",
             @"date1": @"createTime",
             @"bool1": @"married",
             @"data1": @"desc"};
}

@end

  数据库的列名如果与Model的属性名不一致,可以通过改映射函数进行配置

  3、查询函数,关键方法

/**
 *  执行查询操作,自定构造models集合
 *
 *  @param sql        sql语句
 *  @param args       sql参数
 *  @param modelClass 结果集model类型
 *  @param block      对model执行自定义操作
 *
 *  @return 查询结果集
 */
- (NSArray *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)args modelClass:(Class)modelClass performBlock:(void (^)(id model, FMResultSet *rs))block
{
    __block NSMutableArray *models = [NSMutableArray array];

    [_queue inDatabase:^(FMDatabase *db) {
        NSDictionary *mapping = nil;

        FMResultSet *rs = [db executeQuery:sql withArgumentsInArray:args];
        while ([rs next]) {
            id model = [[modelClass alloc] init];
            if(!mapping && [model conformsToProtocol:@protocol(ColumnPropertyMappingDelegate)]) {
                //实现了列-属性转换协议
                mapping = [model columnPropertyMapping];
            }

            for (int i = 0; i < [rs columnCount]; i++) {
                //列名
                NSString *columnName = [rs columnNameForIndex:i];
                //进行数据库列名到model之间的映射转换,拿到属性名
                NSString *propertyName;

                if(mapping) {
                    propertyName = mapping[columnName];
                    if (propertyName == nil) {
                        //如果映射未定义,则视为相同
                        propertyName = columnName;
                    }
                } else {
                    propertyName = columnName;
                }

                objc_property_t objProperty = class_getProperty(modelClass, propertyName.UTF8String);
                //如果属性不存在,则不操作
                if (objProperty) {
                    if(![rs columnIndexIsNull:i]) {
                        [self setProperty:model value:rs columnName:columnName propertyName:propertyName property:objProperty];
                    }
                }

                NSAssert(![propertyName isEqualToString:@"description"], @"description为自带方法,不能对description进行赋值,请使用其他属性名或请ColumnPropertyMappingDelegate进行映射");
            }

            //执行自定义操作
            if (block) {
                block(model, rs);
            }
            [models addObject:model];
        }

        [rs close];
    }];
    return models;
}

/**
 *  进行属性赋值
 */
- (void)setProperty:(id)model value:(FMResultSet *)rs columnName:(NSString *)columnName propertyName:(NSString *)propertyName property:(objc_property_t)property
{
    //    @"f":@"float",
    //    @"i":@"int",
    //    @"d":@"double",
    //    @"l":@"long",
    //    @"c":@"BOOL",
    //    @"s":@"short",
    //    @"q":@"long",
    //    @"I":@"NSInteger",
    //    @"Q":@"NSUInteger",
    //    @"B":@"BOOL",

    NSString *firstType = [[[[NSString stringWithUTF8String:property_getAttributes(property)] componentsSeparatedByString:@","] firstObject] substringFromIndex:1];

    if ([firstType isEqualToString:@"f"]) {
        NSNumber *number = [rs objectForColumnName:columnName];
        [model setValue:@(number.floatValue) forKey:propertyName];

    } else if([firstType isEqualToString:@"i"]){
        NSNumber *number = [rs objectForColumnName:columnName];
        [model setValue:@(number.intValue) forKey:propertyName];

    } else if([firstType isEqualToString:@"d"]){
        [model setValue:[rs objectForColumnName:columnName] forKey:propertyName];

    } else if([firstType isEqualToString:@"l"] || [firstType isEqualToString:@"q"]){
        [model setValue:[rs objectForColumnName:columnName] forKey:propertyName];

    } else if([firstType isEqualToString:@"c"] || [firstType isEqualToString:@"B"]){
        NSNumber *number = [rs objectForColumnName:columnName];
        [model setValue:@(number.boolValue) forKey:propertyName];

    } else if([firstType isEqualToString:@"s"]){
        NSNumber *number = [rs objectForColumnName:columnName];
        [model setValue:@(number.shortValue) forKey:propertyName];

    } else if([firstType isEqualToString:@"I"]){
        NSNumber *number = [rs objectForColumnName:columnName];
        [model setValue:@(number.integerValue) forKey:propertyName];

    } else if([firstType isEqualToString:@"Q"]){
        NSNumber *number = [rs objectForColumnName:columnName];
        [model setValue:@(number.unsignedIntegerValue) forKey:propertyName];

    } else if([firstType isEqualToString:@"@\"NSData\""]){
        NSData *value = [rs dataForColumn:columnName];
        [model setValue:value forKey:propertyName];

    } else if([firstType isEqualToString:@"@\"NSDate\""]){
        NSDate *value = [rs dateForColumn:columnName];
        [model setValue:value forKey:propertyName];

    } else if([firstType isEqualToString:@"@\"NSString\""]){
        NSString *value = [rs stringForColumn:columnName];
        [model setValue:value forKey:propertyName];

    } else {
        [model setValue:[rs objectForColumnName:columnName] forKey:propertyName];
    }
}

  我们把数据库的查询和更新方法封装成DbService

#import <Foundation/Foundation.h>
@class FMResultSet;

@interface DbService : NSObject

- (instancetype)initWithPath:(NSString *)path;

/**
 *  查询第一行第一列的数据
 */
- (id)executeScalar:(NSString *)sql param:(NSArray *)param;

/**
 *  查询行数
 */
- (NSInteger)rowCount:(NSString *)tableName;

/**
 *  更新数据
 */
- (BOOL)executeUpdate:(NSString *)sql param:(NSArray *)param;

#pragma mark - 查询操作自动构建Model

/**
 *  执行查询操作,自定构造models集合
 *
 *  @param sql        sql语句
 *  @param args       sql参数
 *  @param modelClass 结果集model类型
 *
 *  @return 查询结果集
 */
- (NSArray *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)args modelClass:(Class)modelClass;

/**
 *  执行查询操作,自定构造models集合
 *
 *  @param sql        sql语句
 *  @param args       sql参数
 *  @param modelClass 结果集model类型
 *  @param block      对model执行自定义操作
 *
 *  @return 查询结果集
 */

- (NSArray *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)args modelClass:(Class)modelClass performBlock:(void (^)(id model, FMResultSet *rs))block;

/**
 *  查询结果集取得model集合
 *
 *  @param rs         数据库查询结果集
 *  @param modelClass 结果集model类型
 *
 *  @return 查询结果集
 */
- (NSArray *)resultForModels:(FMResultSet *)rs modelClass:(Class)modelClass;

/**
 *  查询结果集取得model集合
 *
 *  @param rs         数据库查询结果集
 *  @param modelClass 结果集model类型
 *  @param block      对model执行自定义操作
 *
 *  @return 查询结果集
 */
- (NSArray *)resultForModels:(FMResultSet *)rs modelClass:(Class)modelClass performBlock:(void (^)(id model, FMResultSet *rs))block;

@end

#import "DbService.h"
#import <objc/runtime.h>
#import "FMDB.h"
#import "ColumnPropertyMappingDelegate.h"

#import "PersonModel.h"

@interface DbService ()
{
    FMDatabaseQueue *_queue;
}

@end

@implementation DbService

- (instancetype)initWithPath:(NSString *)path
{
    if (self = [super init]) {
        _queue = [FMDatabaseQueue databaseQueueWithPath:path];
    }

    return self;
}

- (BOOL)executeUpdate:(NSString *)sql param:(NSArray *)param
{
    __block BOOL result = NO;
    [_queue inDatabase:^(FMDatabase *db) {
        if (param && param.count > 0) {
            result = [db executeUpdate:sql withArgumentsInArray:param];
        } else {
            result = [db executeUpdate:sql];
        }
    }];

    return result;

}

- (id)executeScalar:(NSString *)sql param:(NSArray *)param
{
    __block id result;

    [_queue inDatabase:^(FMDatabase *db) {
        FMResultSet *rs = [db executeQuery:sql withArgumentsInArray:param];
        if ([rs next]) {
            result = rs[0];
        } else {
            result = 0;
        }
    }];
    return result;
}

- (NSInteger)rowCount:(NSString *)tableName
{
    NSNumber *number = (NSNumber *)[self executeScalar:[NSString stringWithFormat:@"SELECT COUNT(*) FROM %@", tableName] param:nil];
    return [number longValue];
}

#pragma mark -
#pragma mark -- 自动创建model查询方法
- (NSArray *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)args modelClass:(Class)modelClass
{
    return [self executeQuery:sql withArgumentsInArray:args modelClass:modelClass performBlock:nil];
}

- (NSArray *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)args modelClass:(Class)modelClass performBlock:(void (^)(id model, FMResultSet *rs))block
{
    __block NSMutableArray *models = [NSMutableArray array];

    [_queue inDatabase:^(FMDatabase *db) {
        NSDictionary *mapping = nil;

        FMResultSet *rs = [db executeQuery:sql withArgumentsInArray:args];
        while ([rs next]) {
            id model = [[modelClass alloc] init];
            if(!mapping && [model conformsToProtocol:@protocol(ColumnPropertyMappingDelegate)]) {
                //实现了列-属性转换协议
                mapping = [model columnPropertyMapping];
            }

            for (int i = 0; i < [rs columnCount]; i++) {
                //列名
                NSString *columnName = [rs columnNameForIndex:i];
                //进行数据库列名到model之间的映射转换,拿到属性名
                NSString *propertyName;

                if(mapping) {
                    propertyName = mapping[columnName];
                    if (propertyName == nil) {
                        //如果映射未定义,则视为相同
                        propertyName = columnName;
                    }
                } else {
                    propertyName = columnName;
                }

                objc_property_t objProperty = class_getProperty(modelClass, propertyName.UTF8String);
                //如果属性不存在,则不操作
                if (objProperty) {
                    if(![rs columnIndexIsNull:i]) {
                        [self setProperty:model value:rs columnName:columnName propertyName:propertyName property:objProperty];
                    }
                }

                NSAssert(![propertyName isEqualToString:@"description"], @"description为自带方法,不能对description进行赋值,请使用其他属性名或请ColumnPropertyMappingDelegate进行映射");
            }

            //执行自定义操作
            if (block) {
                block(model, rs);
            }
            [models addObject:model];
        }

        [rs close];
    }];
    return models;
}

/**
 *  解析结果集(models)
 */
- (NSArray *)resultForModels:(FMResultSet *)rs modelClass:(Class)modelClass
{
    return [self resultForModels:rs modelClass:modelClass performBlock:nil];
}

- (NSArray *)resultForModels:(FMResultSet *)rs modelClass:(Class)modelClass performBlock:(void (^)(id model, FMResultSet *rs))block;
{
    NSDictionary *mapping = nil;

    NSMutableArray *models = [NSMutableArray array];
    while ([rs next]) {
        id model = [[modelClass alloc] init];
        if(!mapping && [model conformsToProtocol:@protocol(ColumnPropertyMappingDelegate)]) {
            //实现了列-属性转换协议
            mapping = [model columnPropertyMapping];
        }

        for (int i = 0; i < [rs columnCount]; i++) {
            //列名
            NSString *columnName = [rs columnNameForIndex:i];
            //进行数据库列名到model之间的映射转换,拿到属性名
            NSString *propertyName;

            if(mapping) {
                propertyName = mapping[columnName];
                if (propertyName == nil) {
                    propertyName = columnName;
                }
            } else {
                propertyName = columnName;
            }

            objc_property_t objProperty = class_getProperty(modelClass, propertyName.UTF8String);
            //如果属性不存在,则不操作
            if (objProperty) {
                if(![rs columnIndexIsNull:i]) {
                    [self setProperty:model value:rs columnName:columnName propertyName:propertyName property:objProperty];
                }
            }

            NSAssert(![propertyName isEqualToString:@"description"], @"description为自带方法,不能对description进行赋值,请使用其他属性名或请ColumnPropertyMappingDelegate进行映射");
        }

        //执行自定义操作
        if (block) {
            block(model, rs);
        }

        [models addObject:model];
    }
    [rs close];

    return models;
}

/**
 *  进行属性赋值
 */
- (void)setProperty:(id)model value:(FMResultSet *)rs columnName:(NSString *)columnName propertyName:(NSString *)propertyName property:(objc_property_t)property
{
    //    @"f":@"float",
    //    @"i":@"int",
    //    @"d":@"double",
    //    @"l":@"long",
    //    @"c":@"BOOL",
    //    @"s":@"short",
    //    @"q":@"long",
    //    @"I":@"NSInteger",
    //    @"Q":@"NSUInteger",
    //    @"B":@"BOOL",

    NSString *firstType = [[[[NSString stringWithUTF8String:property_getAttributes(property)] componentsSeparatedByString:@","] firstObject] substringFromIndex:1];

    if ([firstType isEqualToString:@"f"]) {
        NSNumber *number = [rs objectForColumnName:columnName];
        [model setValue:@(number.floatValue) forKey:propertyName];

    } else if([firstType isEqualToString:@"i"]){
        NSNumber *number = [rs objectForColumnName:columnName];
        [model setValue:@(number.intValue) forKey:propertyName];

    } else if([firstType isEqualToString:@"d"]){
        [model setValue:[rs objectForColumnName:columnName] forKey:propertyName];

    } else if([firstType isEqualToString:@"l"] || [firstType isEqualToString:@"q"]){
        [model setValue:[rs objectForColumnName:columnName] forKey:propertyName];

    } else if([firstType isEqualToString:@"c"] || [firstType isEqualToString:@"B"]){
        NSNumber *number = [rs objectForColumnName:columnName];
        [model setValue:@(number.boolValue) forKey:propertyName];

    } else if([firstType isEqualToString:@"s"]){
        NSNumber *number = [rs objectForColumnName:columnName];
        [model setValue:@(number.shortValue) forKey:propertyName];

    } else if([firstType isEqualToString:@"I"]){
        NSNumber *number = [rs objectForColumnName:columnName];
        [model setValue:@(number.integerValue) forKey:propertyName];

    } else if([firstType isEqualToString:@"Q"]){
        NSNumber *number = [rs objectForColumnName:columnName];
        [model setValue:@(number.unsignedIntegerValue) forKey:propertyName];

    } else if([firstType isEqualToString:@"@\"NSData\""]){
        NSData *value = [rs dataForColumn:columnName];
        [model setValue:value forKey:propertyName];

    } else if([firstType isEqualToString:@"@\"NSDate\""]){
        NSDate *value = [rs dateForColumn:columnName];
        [model setValue:value forKey:propertyName];

    } else if([firstType isEqualToString:@"@\"NSString\""]){
        NSString *value = [rs stringForColumn:columnName];
        [model setValue:value forKey:propertyName];

    } else {
        [model setValue:[rs objectForColumnName:columnName] forKey:propertyName];
    }
}

@end

PersonModel.m

  创建一个PeopleService演示一下

#import <Foundation/Foundation.h>

@interface PeopleService : NSObject

+ (instancetype)shareInstance;

- (void)createTable;

- (void)insertOnePerson;

- (NSArray *)query;

@end

PeopleService.h

#import "PersonModel.h"
#import "PeopleService.h"
#import "DbService.h"

@interface PeopleService ()
{
    DbService *_dbService;
}

@end

@implementation PeopleService

+ (instancetype)shareInstance
{
    static id instance = nil;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });

    return instance;
}

- (instancetype)init
{
    if (self = [super init]) {
        NSString *dbName = @"people.db";
        NSString *directory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
        NSString *dbPath = [directory stringByAppendingPathComponent:dbName];
        _dbService = [[DbService alloc] initWithPath:dbPath];
    }
    return self;
}

- (void)createTable
{
    NSString *sql = @"CREATE TABLE People (                                             id INTEGER PRIMARY KEY AUTOINCREMENT,                           str1 TEXT,                                                      str2 TEXT,                                                      float1 REAL,                                                    double1 INTEGER,                                                short1 REAL,                                                    long1 REAL,                                                     date1 TEXT,                                                     bool1 INTEGER,                                                  data1 BLOB                                                      )";
    [_dbService executeUpdate:sql param:nil];
}

- (void)insertOnePerson
{
    NSString *sql = @"insert into People(str1, str2, float1, double1, short1, long1, date1, bool1, data1) values(?,?,?,?,?,?,?,?,?)";

    NSString *text = @"dataValue";
    NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];

    NSArray *param = @[@"bomo", @"male", @70, @175l, @22, @123, [NSDate date], @NO, data];

    [_dbService executeUpdate:sql param:param];
}

- (NSArray *)query
{
    return [_dbService executeQuery:@"select * from People" withArgumentsInArray:nil modelClass:[PersonModel class]];
}

@end

PeopleService.m

  测试

    [[PeopleService shareInstance] createTable];
    [[PeopleService shareInstance] insertOnePerson];
    NSArray *people = [[PeopleService shareInstance] query];

    for (PersonModel *person in people) {
        NSLog(@"name = %@, age = %d", person.name, person.age);
    }

  我们看一下数据库的表结构

  查询操作只需要一行代码,其他的都交给DbService,减少代码量,减少人为错误,由于个人水平有限,如有疏漏或问题,欢迎回复,如果大家有更好的方式,可以一起讨论

  Demo:http://files.cnblogs.com/files/bomo/FmdbDemo.zip

时间: 2024-10-31 11:30:00

【iOS】FMDB封装,查询自动mapping的相关文章

IOS FMDB模糊查询

http://blog.sina.com.cn/s/blog_9630f1310101fx1d.html /查询记录 -(NSArray*)selectitemDream_desc:(JiemengSimple *)item { NSString *sql = [NSString stringWithFormat:@"SELECT * FROM pinyinSimple WHERE alpha like '%@%%'",item.dream_keyword];//模糊查询,查找alph

IOS开发-封装数据库sqlite3之为何选择FMDB

为什么使用第三方轻量级框架FMDB? FMDB是用于进行数据存储的第三方的框架,它与SQLite与Core Data相比较,存在很多优势. FMDB是面向对象的,它以OC的方式封装了SQLite的C语言API,使用起来更加的方便,不需要过多的关心数据库操作的知识. 为什么不使用core data和SQLite? Core Data是ORM的一种体现,实现了界面化操作.使用Core Data需要用到模型数据的转化,虽然操作简单,不需要直接操作数据库,但是性能没有直接使用SQLite高.但是SQLi

CI中写原生SQL(封装查询)

封装查询 封装,通过让系统为你组装各个查询语句,能够简化你的查询语法.参加下面的范例: $sql = "SELECT * FROM some_table WHERE id = ? AND status = ? AND author = ?"; $this->db->query($sql, array(3, 'live', 'Rick')); 查询语句中的问号会自动被查询函数中位于第二个参数位置的数组中的值所替代. 使用封装查询的第二个好处是所有的值都会被自动转义,形成了较为

在iOS微信浏览器中自动播放HTML5 audio(音乐)的2种正确方式

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"

hibernate封装查询,筛选条件然后查询

// 封装查询条件 @Test public void transmitParameter() { Map map = new HashMap<String, String>(); // map.put("sid", "1"); map.put("s_name", ""); test1(Student.class, map); // 可能会根据筛选来查询!有的条件可能值为空 } public void test1(

IOS某个ViewController禁止自动旋转

IOS屏幕自动旋转,强制横竖屏方法: - (BOOL)shouldAutorotate { return YES; } - (NSUInteger)supportedInterfaceOrientations { return (UIInterfaceOrientationMaskAll);// 修改这里 控制显示方向 } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrienta

mybatis 使用Map封装查询的结果

有时我们厌倦了为每个查询写一个Entity类,这时Map开始发挥它的功效. 对于要返回"学号,班级,姓名"结果的查询,可以这样写Mapper: <select id="selectStudent"> select s.code as sNo , s.name as sName, c.name as cName from xStudent s, xClass c where s.cID = c.ID </select> 如下声明我们的dao方法

ios应用, 设置不自动备份到iCloud

原创文章,转载请注明出处 ios项目,如果有内置下载或者程序动态生成文件的话,就要注意所下载或生成的文件,要不要自动备份到iCloud 如果没有合适的理由就自动上传大文件的话,可能在不能通过应用审核. 收到一下类似这样的答复 We also found that your app does not follow the iOS Data Storage Guidelines, which is required per the App Store Review Guidelines. 例如有人遇

ios中封装网络请求类

ios中封装网络请求类 #import "JSNetWork.h" //asiHttpRequest #import "ASIFormDataRequest.h" //xml 的解析 #import "UseXmlParser.h" //判断是否联网 #import "Reachability.h" //sbJson,判断json的解析 #import "JSON.h" @implementation JS