从PHP/MySQL/JSON到iOS/Objective-C/SQLite

从PHP/MySQL/JSON到iOS/Objective-C/SQLite,php,iphone,objective-c,json,ios,Php,Iphone,Objective C,Json,Ios,我正在尝试创建一个iOS应用程序,在加载时,它将首先通过HTTP连接回一个PHP web服务,该服务将从MySQL数据库以JSON格式输出数据。然后,我希望它将这些数据导入iOS应用程序中的本地SQLite数据库。我已经下载了Objective-C的JSON框架 我的问题有两个方面 1) 从PHP输出JSON以便在同一个JSON文件中发送多个数据库表的最佳方式是什么?我有4个我试图发送的数据表(用户、建筑、房间、设备)。 以下是我当前输出JSON数据的方式: // Users $

我正在尝试创建一个iOS应用程序,在加载时,它将首先通过HTTP连接回一个PHP web服务,该服务将从MySQL数据库以JSON格式输出数据。然后,我希望它将这些数据导入iOS应用程序中的本地SQLite数据库。我已经下载了Objective-C的JSON框架

我的问题有两个方面

1) 从PHP输出JSON以便在同一个JSON文件中发送多个数据库表的最佳方式是什么?我有4个我试图发送的数据表(用户、建筑、房间、设备)。 以下是我当前输出JSON数据的方式:

    // Users
    $query = "SELECT * from user";
    $result = mysql_query($query,$conn) or die('Errant query:  '.$query);

    $users = array();
    if(mysql_num_rows($result)) {
      while($user = mysql_fetch_assoc($result)) {
      $users[] = array('user'=>$user);
      }
    }

    // Buildings
    $query = "SELECT * from building";
    $result = mysql_query($query,$conn) or die('Errant query:  '.$query);

    $buildings = array();
    if(mysql_num_rows($result)) {
      while($building = mysql_fetch_assoc($result)) {
       $buildings[] = array('building'=>$building);
     }
    }

    // Rooms
    $query = "SELECT * from room";
    $result = mysql_query($query,$conn) or die('Errant query:  '.$query);

    $rooms = array();
    if(mysql_num_rows($result)) {
     while($room = mysql_fetch_assoc($result)) {
      $rooms[] = array('room'=>$room);
     }
    }

    // Devices
    $query = "SELECT * from device";
    $result = mysql_query($query,$conn) or die('Errant query:  '.$query);

    $devices = array();
    if(mysql_num_rows($result)) {
     while($device = mysql_fetch_assoc($result)) {
      $devices[] = array('device'=>$device);
     }
    }

    header('Content-type: application/json');
    echo json_encode(array('users'=>$users));
    echo json_encode(array('buildings'=>$buildings));
    echo json_encode(array('rooms'=>$rooms));
    echo json_encode(array('devices'=>$devices)); 
我担心这种方法不是发送多个对象的正确方法

2) 在iOS应用程序中,如何自动获取此JSON数据并将其插入SQLite中相应的本地数据库表中

感谢您的帮助。

我无法与2)交谈,但对于1),我建议您将JSON合并到单个数组中。JSON(和数组)的一个优点是能够尽可能深地嵌套元素

echo json_encode(array(
    'users'=>$users,
    'buildings'=>$buildings,
    'rooms'=>$rooms,
    'devices'=>$devices,
)); 

一号。代替JSOn,您可以使用二进制属性列表,它们在iPhone上本机实现,并且有一个库可以将PHP转换为二进制Plist

使用二进制属性列表有很多好处,它们的大小可能是JSON的1/5,您不需要外部库来解析它们,因此所有代码都要简单得多,等等


二号。采用JSON/Plist结构并将其插入SQL数据库并不容易,因为JSON/Plist比SQL表具有更大的灵活性。因此,您必须首先在SQLite DB中创建正确的表,然后使用普通的INSERT将数据一个一个地插入到数据库中,就像您使用PHP一样。

是的,Luke的建议很好,但您可以使用导出表的方式。您可能只需要对结构进行“更深入”的挖掘以获得所需的内容,即您的输出返回一个“数组字典字典”,该字典将包含每个表的数据

至于先下载:

1) NSURLConnection及其委托方法-您可以向Web服务器发送异步请求以获取此文件,并在下载数据时收到通知,这样应用程序中的用户界面就不会被阻止

以下是来自苹果公司的文档和一些好例子:

下载结束时,您将拥有一个NSData对象,然后可以使用
NSString*jsonContents=[[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding
将其转换回字符串

然后,您可以使用JSON解析器库(我推荐使用SBJSON),它将解析数据并根据您的结构将其作为字典或数组返回

从那里,您可以使用字典中的
valueForKey
或数组中的
objectAtIndex:
访问表和值,然后将其映射到所选的本地存储中,我建议您使用Coredata(如果您也熟悉它,也可以使用sqlite)

希望能有帮助。
Rog

在Web服务器上准备SQLite数据库并将其下载到iOS应用程序怎么样?这样,您就可以在PHP端完成繁重的工作。如果数据相对静态,您甚至可以设置一个计划任务,定期生成SQLite数据库

我们已经为我们的一个应用程序完成了这项工作,它运行得非常好

需要记住的一件事是,您应该在Web服务器上启用gzip压缩,以最大限度地减少数据传输。请记住,要在NSURLConnection中使用gzip压缩,您必须做一些额外的工作:


如果您想要一个独立解析库提供的功能更全面的解决方案,您可能需要看看RestKit:

该框架将获取、解析和映射JSON有效负载的操作封装到对象中。它可以处理深度嵌套的结构,并可以直接映射回核心数据以实现持久性

在较高的层次上,以下是在RestKit中获取和发布操作的感受:

- (void)loadObjects {
  [[RKObjectManager sharedManager] loadObjectsAtResourcePath:[@"/path/to/stuff.json" delegate:self];
}

- (void)objectLoader:(RKObjectLoader*)loader didLoadObjects:(NSArray*)objects {
  NSLog(@"These are my JSON decoded, mapped objects: %@", objects);

  // Mutate and PUT the changes back to the server
  MyObject* anObject = [objects objectAtIndex:0];
  anObject.name = @"This is the new name!";
  [[RKObjectManager sharedManager] putObject:anObject delegate:self];
}

该框架负责后台线程上的JSON解析/编码,让我们来声明JSON中的属性如何映射到对象上的属性。社区中的许多人正在使用PHP backends+RestKit取得巨大成功。

您可以使用REST server和RestKit。

ASIHTTPRequest已经处理gzip压缩ion如果你将
setAllowCompressedResponse
设置为
YES
,那么如果你使用这个库,你就不必做任何NSURLConnection操作。顺便说一句,我在一个应用程序中使用了Pieter的建议,效果非常好。我喜欢这种方法。谢谢!