【问题标题】:From PHP/MySQL/JSON to iOS/Objective-C/SQLite从 PHP/MySQL/JSON 到 iOS/Objective-C/SQLite
【发布时间】:2011-07-01 12:52:28
【问题描述】:

我正在尝试创建一个 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中对应的本地数据库表中?

感谢您的帮助。

【问题讨论】:

    标签: php iphone objective-c json ios


    【解决方案1】:

    关于 1. 您可以使用二进制属性列表代替 JSOn,它们在 iPhone 上原生实现,并且有一个库可以将 PHP 转换为二进制 Plist https://github.com/rodneyrehm/CFPropertyList

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

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

    【讨论】:

      【解决方案2】:

      是的,Luke 的建议很好,但您导出表格的方式会很好。您可能只需要“更深入”地挖掘结构以获得您想要的东西 - 即您的输出返回一个“数组字典的字典”,然后将包含每个表的数据。

      至于先下载:

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

      这里有一些来自 Apple 的优秀示例的文档:http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html

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

      然后您可以使用 JSON 解析器库 - 我推荐 SBJSON https://github.com/stig/json-framework - 它将解析数据并根据您的结构将其作为字典或数组返回。

      从那里您可以使用字典中的valueForKey 或数组中的objectAtIndex: 访问您的表和值,然后将其映射到您选择的本地存储中,为此我推荐Coredata(或者如果您熟悉的话,您可以使用sqlite也是)。

      希望对您有所帮助。 罗格

      【讨论】:

        【解决方案3】:

        我不能说 2),但对于 1),我建议将您的 JSON 组合成一个数组。 JSON(和数组)的优点之一是可以随意嵌套元素。

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

        【讨论】:

          【解决方案4】:

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

          我们已经为我们的一个应用做了这个,效果很好。

          然后要记住的一件事是,您应该在网络服务器上启用 gzip 压缩以最大程度地减少数据传输。请记住,您必须做一些额外的事情才能将 gzip 压缩与 NSURLConnection 一起使用:

          http://www.bigevilempire.com/codelog/entry/nsurlconnection-with-gzip/

          【讨论】:

          • 如果您将setAllowCompressedResponse 设置为YESASIHTTPRequest 已经处理gzip 压缩,因此如果您使用这个库,那么您实际上不需要做任何NSURLConnection 摆弄。顺便说一句,我在一个应用程序中使用了 Pieter 的建议,它就像做梦一样。 allseeing-i.com/ASIHTTPRequest/How-to-use#gzip
          • 我喜欢这种方法。谢谢!
          【解决方案5】:

          您可以使用 REST 服务器和 RESTKit。

          【讨论】:

            【解决方案6】:

            如果您想要独立解析库提供的功能更全面的解决方案,您可能需要查看 RestKit:http://restkit.org/

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

            概括地说,这是您在 RestKit 中的 fetch 和 post 操作的感觉:

            - (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 后端 + RestKit 并取得了巨大的成功。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-11-16
              • 1970-01-01
              • 2018-11-02
              • 2018-08-31
              相关资源
              最近更新 更多