简体   繁体   English

我应该如何构建我的iPhone应用程序来与我的网站交谈?

[英]How should I architect my iPhone app to talk to my website?

I'm planning my first iPhone app and I'd like to get some inputs as to how to build it, right from the start. 我正在计划我的第一个iPhone应用程序,我想从一开始就得到一些关于如何构建它的输入。 The iPhone app is being built to be paired with a public facing web application that is already built in PHP. iPhone应用程序正在与面向公众的Web应用程序配合使用,该应用程序已经用PHP构建。

I'd like the web platform to be central (data is housed in a mySQL database), and have the iPhone clients talk to it and use REST'ful methods to perform the functions of the site (fetching latest content, posting content, voting, account management as examples). 我希望网络平台成为核心(数据存储在mySQL数据库中),并让iPhone客户端与它通信并使用REST'方法来执行网站功能(获取最新内容,发布内容,投票) ,帐户管理作为例子)。

I'd like the clients to get a local copy of the data in a SQLite database, but refresh to get the latest version of the feed (similar to the Twitter app). 我希望客户在SQLite数据库中获取数据的本地副本,但刷新以获取最新版本的feed(类似于Twitter应用程序)。

Couple of thoughts I have right now: 我现在有几个想法:

  • Use something like ASIHTTPRequest to send/recieve data to PHP files on the server listening for requests 使用ASIHTTPRequest之类的东西将数据发送/接收到侦听请求的服务器上的PHP文件

  • JSON - would I be better off to send the GET/POSTS to a PHP that returns JSON objects, and work with some sort of wrapper that manages the data and communicates changes to the local SQLite database? JSON - 我最好将GET / POSTS发送到返回JSON对象的PHP,并使用某种管理数据并将更改传递给本地SQLite数据库的包装器?

  • Am I totally off in how I should be building this thing to communicate with the web? 我完全不知道应该如何构建这个与网络通信的东西? Is there a best practice for this? 这是最好的做法吗?

I'd really appreciate any input on how you would architect this sort of a setup. 我非常感谢您如何构建这种设置。

Thank you, 谢谢,

EDIT : After reading my own post again, I know it sounds like a Twitter client, but it is NOT, although it has similar features/structure of a Twitter type setup. 编辑 :再次阅读我自己的帖子后,我知道它听起来像一个Twitter客户端,但它不是,虽然它有类似的功能/结构的Twitter类型设置。 Thanks! 谢谢!

As you already outlined in your plan, XML and REST are a great way to communicate with a web application. 正如您在计划中已经概述的那样,XML和REST是与Web应用程序通信的好方法。 I want to suggest few details about how to actually design and build it, or what you should keep in mind. 我想建议一些关于如何实际设计和构建它的细节,或者你应该记住什么。

First of all, I believe it's important to stick with MVC. 首先,我认为坚持使用MVC非常重要。 I've seen people creating HTTP connections in view-controllers, controllers being NSXMLParser's delegate, controllers containing data in member variables. 我见过人们在视图控制器中创建HTTP连接,控制器是NSXMLParser的委托,控制器包含成员变量中的数据。 I've even seen UITableCells establishing HTTP connections. 我甚至看到UITableCells建立HTTP连接。 Don't do it! 不要这样做!

Your model and its basic manipulation code should be as much extracted from user interface as possible. 您的模型及其基本操作代码应尽可能从用户界面中提取。 As you already have created the model in your web-application, try to recreate the entities in your iPhone project. 由于您已在Web应用程序中创建了模型,请尝试在iPhone项目中重新创建实体。 Don't be afraid of having some simple methods in entity classes, but do not make them use external resources, especially tcp connections. 不要害怕在实体类中使用一些简单的方法,但不要让它们使用外部资源,尤其是tcp连接。 As an example of methods in entity class you might have methods that formats data in specific ways (dates as an example, or returning fullname as concatenation of firstname and surname), or you can even have a method like - (void)update that would act as a wrapper to call class responsible to update the model. 作为实体类中方法的一个示例,您可能拥有以特定方式格式化数据的方法(日期作为示例,或返回fullname作为firstname和surname的串联),或者您甚至可以使用类似- (void)update的方法充当调用负责更新模型的类的包装器。

Create another class for updating the model - fetching the XMLs from web-app. 创建另一个用于更新模型的类 - 从web-app中获取XML。 Do not even consider using synchronous connections, not even from a dedicated thread. 甚至不考虑使用同步连接,甚至不使用专用线程。 Asynchronous connections with delegate is the way to go. 与委托的异步连接是要走的路。 Sometimes multiple requests need to be made to get all required data. 有时需要多个请求来获取所有必需的数据。 You might want to create some kind of state-machine to keep the information about in which stage of downloading you are, and progress from stage to stage, skipping to the end if error occurs, re-executing from failed stage after some moments. 您可能希望创建某种状态机来保存有关下载哪个阶段的信息,以及从一个阶段到另一个阶段的进度,如果发生错误则跳到最后,在一段时间后从失败的阶段重新执行。

Download data somewhere temporarily, and first when you have it all, make a switch and update user interface. 暂时在某处下载数据,首先在完成所有操作后,进行切换并更新用户界面。 This helps responsiveness during launching the app - user gets to work immediately with data stored locally, while the update mechanism is downloading the new data. 这有助于在启动应用程序期间的响应性 - 用户可以立即使用本地存储的数据工作,而更新机制正在下载新数据。

If you need to download lots of files, try to download them simultaneously, if dependencies between files allow for that. 如果您需要下载大量文件,请尝试同时下载它们,如果文件之间的依赖关系允许的话。 This involves creating a connection per request, probably delegate instance for each of them. 这涉及为每个请求创建一个连接,可能为每个请求委托实例。 You can of course have only one delegate instance for all of those connections, but it gets a bit more complex to track the data. 当然,对于所有这些连接,您只能有一个委托实例,但跟踪数据会有点复杂。 Downloading simultaneously might decrease latency considerably, making the mechanism much faster for the user. 同时下载可能会大大减少延迟,使用户的机制更快。

To save the time and bandwidth, consider using HTTP's If-Modified-Since and/or ETag headers. 要节省时间和带宽,请考虑使用HTTP的If-Modified-Since和/或ETag标头。 Remember the time or tag when you requested the data the last time, and next time send it in HTTP's header. 记住上次请求数据时的时间或标记,下次将其发送到HTTP的标题中。 Your web-application should return HTTP code 304 if content has not been changed. 如果内容尚未更改,您的Web应用程序应返回HTTP代码304。 iPhone app should react on this code accordingly in connection:didReceiveResponse: . iPhone应用程序应相应地响应此代码connection:didReceiveResponse: .

Create a dedicated class to parse the XML and update the model. 创建一个专用类来解析XML并更新模型。 You can use NSXMLParser, but if your files are not huge I strongly recommend TouchXML, it's such a pleasure to work with XML as document (it also supports XPath), instead of an event based API. 您可以使用NSXMLParser,但如果您的文件不是很大,我强烈推荐使用TouchXML,很高兴使用XML作为文档(它也支持XPath),而不是基于事件的API。 You can use this parser also when files are downloaded to check their validity - re-download if parsing fails. 您还可以在下载文件时使用此解析器来检查其有效性 - 如果解析失败则重新下载。 That's when dedicated class for parsing comes handy. 那时解析的专用类很方便。

If your dataset is not huge, if you do not need to persist downloaded data on iPhone forever, you probably don't need to store them in SQLite database, you can simply store them in XML format - just a simple caching. 如果你的数据集不是很大,如果你不需要永久地在iPhone上保存下载的数据,你可能不需要将它们存储在SQLite数据库中,你可以简单地以XML格式存储它们 - 只是一个简单的缓存。 That at least might be the way for a twitter app. 这至少可能是推特应用程序的方式。 It gets easier that way, but for bigger data sets XML consumes lots of memory and processing power - in that case SQLite is better. 这种方式变得更容易,但对于更大的数据集,XML会占用大量内存和处理能力 - 在这种情况下,SQLite会更好。

I'd suggest using Core Data, but you mention this is your first iPhone app, so I suggest you don't use it. 我建议使用Core Data,但你提到这是你的第一个iPhone应用程序,所以我建议你不要使用它。 Yet. 然而。

Do not forget about multitasking - your app can go to sleep in the middle of download, you need to cancel connections, and cleanup your update mechanisms. 不要忘记多任务处理 - 您的应用程序可以在下载过程中进入休眠状态,您需要取消连接并清理更新机制。 On app's wake-up you might want to resume the update. 在应用程序唤醒时,您可能希望恢复更新。

Regarding the view part of the application - use Interface Builder. 关于应用程序的视图部分 - 使用Interface Builder。 It might be painful in the beginning, but it pays off in the long run. 它可能在开始时很痛苦,但从长远来看它会得到回报。

View controllers are the glue between model and views. 视图控制器是模型和视图之间的粘合剂。 Do not store data in there. 不要在那里存储数据。 Think twice about what to implement where, and who should call it. 三思而后行,在哪里实施,谁应该称之为。

This is not related to architecture of the app, but I want to remind that Objective-C is very expressive language. 这与应用程序的体系结构无关,但我想提醒一下,Objective-C是一种非常富有表现力的语言。 Code should read much like a sentence. 代码应该像句子一样阅读。 Extend classes with protocols. 使用协议扩展类。 As an example the other day I needed first line of a string. 作为一个例子,有一天我需要第一行字符串。 Sure, you can write a one-liner where you find first occurrence of a new-line, and get a substring from beginning till there. 当然,你可以写一个单行,你会发现第一次出现一个新行,并从头到那里得到一个子串。 But it doesn't look right. 但它看起来并不正确。 I've added - (NSString*)firstLine into my NSString's protocol. 我已将- (NSString*)firstLine到我的NSString协议中。 Code looks so much better this way, it doesn't need any comments. Code以这种方式看起来好多了,它不需要任何评论。

There are lots of things to consider in both architecture and design of any project, they both should go hand in hand. 在任何项目的架构和设计中都要考虑很多事情,它们都应该齐头并进。 If one is causing trouble to the other, you need to adapt. 如果一个人给另一个人造成麻烦,你需要适应。 Nothing is written in stone. 没有什么是一成不变的。

I'm currently working on an app that sounds similar to yours. 我正在开发一款听起来与你类似的应用。 I'd also suggest ASIHTTPRequest, and probably something like TouchJSON for JSON parsing, or extending/making a delegate of NSXMLParser if you want to parse XML. 我还建议使用ASIHTTPRequest,或者像TouchJSON一样用于JSON解析,或者如果要解析XML,则扩展/制作NSXMLParser的委托。

As suggested by JosephH, depending on how your app works you may want to consider alternate authentication methods: I'd take a look at something token-based like OAuth, which has ready-made libraries for people to dig in to. 正如JosephH所建议的那样,根据您的应用程序的工作原理,您可能需要考虑其他身份验证方法:我会看一下基于令牌的内容,例如OAuth,它有现成的库供人们使用。

SQLite is totally viable for feed caching, although I prefer NSCoding so that you can freeze-dry your custom data structures. SQLite完全适用于Feed缓存,虽然我更喜欢NSCoding,因此您可以冻结自定义数据结构。

As a general suggestion, make sure to spend a lot of time thinking about every use case and corner case for connections: it's easy to assume a user will only contact the server in certain ways and at certain times, and then after you throw in multitasking/incoming calls/lock screen/memory warnings, things can get hairy without any planning. 作为一般建议,请确保花费大量时间考虑连接的每个用例和角落情况:很容易假设用户只能以某种方式和特定时间联系服务器,然后再投入多任务处理/来电/锁定屏幕/内存警告,事情可能会变得毛茸茸而没有任何计划。

All in all, you seem to be on the right track, just make sure you plan out everything beforehand :) 总而言之,你似乎走在正确的轨道上,只要确保你事先计划好一切:)

Apple有一个全新的深度示例代码 - MVCNetworking ,它深入展示了如何使用NSHTTPRequests和NSOperationQueues的子类。

As others mentioned, I think you are asking the right questions and are heading in the right direction. 正如其他人提到的那样,我认为你正在提出正确的问题,正朝着正确的方向前进。 All of the replies above are valuable advice. 以上所有回复都是有价值的建议。 Here is my advice, and I hope you'll find it useful. 这是我的建议,我希望你会发现它很有用。

No matter which method/library you choose to talk to your web services, I think it's important to make a clean separation in the way you design your data model on the phone VS. 无论您选择哪种方法/库与您的Web服务进行通信,我认为在您在手机VS上设计数据模型的方式进行清晰分离非常重要。 the data model in your web application. Web应用程序中的数据模型。 You have 3 major distinctions to keep in mind for your design: 您有三个主要区别要记住您的设计:

  1. Data model on the web application (reflected by your existing mySQL database) Web应用程序上的数据模型(由您现有的mySQL数据库反映)

    Since this is already there, there is not much to say about it, except that it will influence a lot your design for the following 2 parts. 由于它已经存在,所以没有太多可说的,除了它会对以下两个部分的设计产生很大的影响。 I suggest to make this model the 'master reference' for how your data is represented across platforms. 我建议将此模型作为跨平台表示数据的“主参考”。

  2. Data model on the iPhone app (reflected by the information you need to display in the iPhone app) iPhone应用程序上的数据模型(反映在iPhone应用程序中需要显示的信息)

    This is where the fun begins. 这就是乐趣的开始。 First, you need a good understanding of what data you need to display in the phone app. 首先,您需要很好地了解需要在手机应用中显示哪些数据。 So have a good, high level design of your app first (use pen and paper, draw mock-ups of each view and the interactions between them, model the navigation between your view controllers etc.). 因此,首先要对您的应用程序进行良好的高级设计(使用笔和纸,绘制每个视图的模型以及它们之间的交互,在视图控制器之间建模导航等)。 It really helps to understand the interactions between your view controllers and the various bits and pieces of data you want to show in the app. 了解视图控制器与您希望在应用程序中显示的各种数据之间的相互作用确实很有帮助。 This will help you create the requirements for the data model on the phone. 这将帮助您在手机上创建数据模型的要求。 Based on these requirements, map the existing (web) data model to a new model, suited to your iPhone app. 根据这些要求,将现有(Web)数据模型映射到适合您的iPhone应用程序的新模型。 This new model may or may not include all tables and fields found in your web app. 此新模型​​可能包含也可能不包含您的网络应用中的所有表格和字段。 But the general representation of the 2 models should be very similar (eg relationships, data types, etc.) 但是2个模型的一般表示应该非常相似(例如关系,数据类型等)

  3. Data model used to communicate between the 2 above (this is your 'data exchange protocol') 用于上述2之间通信的数据模型(这是您的'数据交换协议')

    Once you have the 2 representations of your data above, you need to 'translate' from one to the other, both ways . 一旦您对上述数据进行了2次表示,您就需要从两种方式 “翻译”到另一种方式 Design your data exchange protocol to be as simple and compact as possible. 设计您的数据交换协议尽可能简单紧凑。 You don't want to waste bytes on useless information, as transmissions over the network are costly. 您不希望在无用信息上浪费字节,因为网络上的传输成本很高。 (As a side note, you might think of compressing the transmitted data later on, but it's just as important to have a good design from the beginning). (作为旁注,您可能会想到稍后压缩传输的数据,但从一开始就拥有一个好的设计同样重要)。 It's probably best to begin with a protocol in which the metadata is the same as the one in your web application model (eg same relationships, names of tables, attributes, etc.). 最好从一个协议开始,其中元数据与Web应用程序模型中的元数据相同(例如,相同的关系,表的名称,属性等)。 But remember, you'll only have to serialize/de-serialize those entities and relationships that you listed in point 2) above. 但请记住,您只需序列化/反序列化您在上面第2点中列出的实体和关系。 So design accordingly. 所以设计相应。 Your exchange protocol may also include session tokens, authentication info, a version number, or other metadata, if you need it. 如果需要,您的交换协议还可能包括会话令牌,身份验证信息,版本号或其他元数据。

    Remember: your data exchange protocol is what will de-couple your web application and iPhone application models. 请记住:您的数据交换协议将解除您的Web应用程序和iPhone应用程序模型的分离。 I found that it's best to de-couple them because they may both evolve over time. 我发现最好将它们分开,因为它们可能会随着时间的推移而发展。 The data model on the iPhone for example, may evolve a lot especially when you will find that you need to re-model some relationships or add/remove attributes from your entities in order to improve application responsiveness, or the user experience, the navigation, or whatever. 例如,iPhone上的数据模型可能会发展很多,尤其是当您发现需要重新建模某些关系或添加/删除实体中的属性以提高应用程序响应能力或用户体验,导航时,管他呢。

    Since this is a whole concern in and by itself, well, you need to design a generic serialization/de-serialization mechanism on top of your (JSON/XML/whatever parser you choose) that is flexible enough to sustain the potential differences between your 2 data models. 因为这本身就是一个完整的问题,所以你需要在你的(JSON / XML /你选择的任何解析器)之上设计一个通用的序列化/反序列化机制,它足够灵活,可以维持你之间的潜在差异。 2个数据模型。 These differences might be: entity/attribute/relationship names, primary key identifier names, data types, attributes to ignore, and the list goes on. 这些差异可能是:实体/属性/关系名称,主键标识符名称,数据类型,要忽略的属性以及列表继续。 I would definitely implement a serializer/de-serializer utility class in the iPhone app, backed by a .plist configuration file containing all supported entities, concerns, aliases you might have. 我肯定会在iPhone应用程序中实现一个序列化器/反序列化器实用程序类,由.plist配置文件支持,该文件包含您可能拥有的所有受支持的实体,关注点和别名。 Of course, each model object should 'know' how to serialize, de-serialize itself and its relationships (ie the required object graph depth). 当然,每个模型对象都应该“知道”如何序列化,反序列化自身及其关系(即所需的对象图深度)。

    One last note, since you will end up with 2 representations of your data, you will need a way to uniquely identify an object on both sides. 最后一点,由于您最终会得到2个数据表示,因此您需要一种方法来唯一地识别双方的对象。 So for example, think of adding a uuid attribute to all data that needs to be exchanged, or use any other approach that suits your needs. 例如,考虑将uuid属性添加到需要交换的所有数据中,或者使用任何其他适合您需求的方法。

I am building an app that has similar requirements to yours, and these are the approaches I found to be best so far. 我正在构建一个与您的应用程序具有类似要求的应用程序,这些是我发现目前为止最好的方法。 Also, you might find this video useful (it inspired me a lot on how to implement some of the issues I mentioned above and is especially interesting if you're using CoreData) : 此外,您可能会发现这个视频很有用(它激发了我很多关于如何实现上面提到的一些问题,如果你使用的是CoreData,它会特别有趣):

http://itunes.apple.com/ca/podcast/linkedin-important-life-lessons/id384233225?i=85092597 (see the lecture entitled "LinkedIn: Important Life Lessons on CoreData & GameKit (March 12, 2010)" ) http://itunes.apple.com/ca/podcast/linkedin-important-life-lessons/id384233225?i=85092597 (参见题为“LinkedIn:关于CoreData和GameKit的重要生活课程(2010年3月12日)”的讲座)

Good luck! 祝好运!

It's quite a broad question, and I think you're going in the right way anyway, however I'll do my best to give some advice: 这是一个相当广泛的问题,我认为无论如何你都会以正确的方式进行,但我会尽力提出一些建议:

JSON, ASIHTTPRequest and POSTs to PHP scripts sound like a great way to go. JSON,ASIHTTPRequest和PHP脚本的POST听起来是一个很好的方式。

If the data is not really sensitive, I'd use http most of the time, and use https only for a login page that either sets a cookie or returns a "token" that you use in subsequent requests. 如果数据不是真的敏感,我大部分时间都会使用http,并且只对登录页面使用https,该登录页面设置cookie或返回您在后续请求中使用的“令牌”。 (HTTPS can be quite slow over a 3G connection as the overhead in terms of number of packets to setup an SSL connection is higher than a plain TCP connection.) (对于3G连接,HTTPS可能相当慢,因为设置SSL连接的数据包数量高于普通TCP连接。)

You should make sure you correctly pass any data from the input to the PHP scripts to the database, to avoid any SQL injection attacks - ie. 您应该确保正确地将输入中的任何数据传递到PHP脚本到数据库,以避免任何SQL注入攻击 - 即。 used parameterised SQL, don't create sql queries by doing " SELECT * from users where username="+$_GET['username'] " 使用参数化SQL, 不要通过“ SELECT * from users where username="+$_GET['username'] “来创建sql查询

I would do this like I have done with a lot of AJAX web-page stuff. 我会这样做,就像我已经完成了很多AJAX网页的东西。 ie: 即:

  1. Have a URL on your server side package the information to be transmitted into XML format. 让服务器端的URL将要传输的信息打包成XML格式。 (This can be through a CGI/PHP script or whatever). (这可以通过CGI / PHP脚本或其他)。 Your transmitting XML in the message body - so it's easy to human read and debug with a standard web browser. 您在消息体中传输XML - 因此使用标准Web浏览器可以轻松地进行人工读取和调试。

  2. Use the standard iPhone NSXMLParser methods to parse out the individual data fields from the XML doc, and write it back to your database. 使用标准的iPhone NSXMLParser方法从XML文档中解析出各个数据字段,并将其写回数据库。 This method is equiped to both fetch the data from a URL and parse it in one call - like: 此方法适用于从URL获取数据在一次调用中解析它 - 如:

 NSURL *xmlURL = [NSURL URLWithString:@"http://www.example.com/livefeed.cgi"]; NSXMLParser *myParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL]; 
  1. Walk through the data hierarchy with the NSXMLParser methods and populate your database accordingly. 使用NSXMLParser方法遍历数据层次结构并相应地填充数据库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 这是我的 Iphone 应用程序的优秀架构师吗? - Is this a good architect for my Iphone app? 我应该如何为基于回合制的多人iPhone桌面游戏构建我的数据库和API服务器? (想想nodejs,mongo,沙发等) - How should I architect my DB & API server for a turn based multiplayer iPhone board game? (thinking about nodejs, mongo, couch, etc) 我应该如何在tabbar iPhone应用程序中管理我的NSTimer? - How should I manage my NSTimer in a tabbar iPhone app? 我应该将我的 Android 应用程序移植到 iPhone 上吗? - Should I port my Android app to the iPhone? 如何在我的Iphone应用程序中使用“ MPMusicPlayerController”从网站播放列表 - How can i use “MPMusicPlayerController” to playlist from my website in my Iphone app 人们如何将iPhone应用程序从我的网站下载到他们的iPhone? - How can people download an iPhone app from my website to their iPhone? 我应该如何在我的iPhone应用程序中存储和使用我的500kB数据文件? - How should I store and use my 500kB data file in my iPhone app? 我为什么要将Core Data用于我的iPhone应用程序? - Why should I use Core Data for my iPhone app? 我应该在哪里存储我的iPhone应用程序的SQLite数据库? - Where should I store the SQLite DB for my iPhone app? 我应该获得Mac来开发或测试我的iPhone网络应用程序吗? - Should I obtain a Mac to develop or test my iPhone web app?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM