今天我有一个读取plist站点的应用程序,但它的工作原理如下:
当您打开应用程序时,它会检查用户是否已在设备上安装了plist,以及是否为最新版本。
如果您没有,那么它是最新版本的服务器捕获
http://lab.vpgroup.com.br/aplicativos/teste-catalogo/lista.plist
我怎么能这样做? 我在stackoverflow上看到了很多问题,但没有一个能够按照我的需要工作。
由于
答案 0 :(得分:3)
你永远不想阻止用户界面。下载可能需要很长时间。因此在后台做。最简单的是使用NSURLConnection的便捷方法sendAsynchronousRequest:request
就像名字所说的那样,它是异步的,并在下载完成后调用传递的完成块
NSURL *url = [NSURL URLWithString:@"http://lab.vpgroup.com.br/aplicativos/teste-catalogo/lista.plist"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSDictionary *dict = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:0 format:0 errorDescription:nil];
NSLog(@"%@", dict);
}];
样品:
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
@autoreleasepool {
NSURL *url = [NSURL URLWithString:@"http://lab.vpgroup.com.br/aplicativos/teste-catalogo/lista.plist"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSDictionary *dict = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:0 format:0 errorDescription:nil];
NSLog(@"%@", dict);
}];
//just for demo
[[NSRunLoop currentRunLoop] run];
}
}
答案 1 :(得分:1)
您可以对路径进行HEAD调用,并获取将存储在设备上的Etag,如果设备上保存的etag不等于服务器发送的etag,则下载文件,存储新的Etag并覆盖设备文件。您也可以使用Last-Modified:标头,但etag可能是最好的。您可能需要在服务器上启用实体标记。
为了澄清,HEAD只发送文件的标题,因此通常比发送整个文件的重量轻得多。
这就是浏览器如何管理静态文件和网址的本地缓存,在这种情况下,浏览器发送他们的Etag,浏览器返回304未经修改,因此您还可以查看重现发送存储的etag的协议并拥有浏览器要么返回文件,要么返回304标题。
答案 2 :(得分:0)
我只是回复您可以使用的策略,而不是您如何实现,同步或asyn取决于它所使用的上下文。
我的建议是按照上面Diaj-Djan的建议向NSOperationque添加一个请求。
回答你如何做到这一点: 您可以通过以下几种方式实现这一目标:
选项1:如果您可以向plist文件添加属性,请说出版本,如果您可以公开一个向您发送版本号的服务。其他选项2。 这是您第一次明显下载plist文件,并按照您希望的方式在您的设备上保留该版本。 在随后的下载 - &gt;请检查设备中的持久版本,并查看服务器中是否有新版本可用于公开的服务 - &gt;如果是 - >进行服务调用以获取plist文件 - &gt;否则使用设备中的那个。 这样,每次下载一个plist(特别是如果它的巨大)时,你可以节省大量的时间/数据下载
选项2:您每次都进行一次服务调用,获取plist文件,比较属性并查看是否有任何更改。这不是一个好的选择,它耗费时间,处理很多。
答案 3 :(得分:0)
我使用@ daij-Djan上面创建的基础,工作得很完美。就像这样:
在我的。 H #import
@interface ViewController : UIViewController{
NSArray *paths;
NSString *documentsDirectory;
NSString *myPathDocs;
NSFileManager *fileManager;
NSString *filePath;
NSString *documentsPath;
NSURL *url;
}
在我的。米
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0];
//filename that will save in device
filePath = [documentsDirectory stringByAppendingPathComponent:@"lista.plist"];
[self showData];
[self updatingData];
}
- (void) updatingData {
NSLog(@"updating Data");
url = [NSURL URLWithString:@"http://lab.vpgroup.com.br/aplicativos/teste-catalogo/lista.plist"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSDictionary *dict = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:0 format:0 errorDescription:nil];
NSLog(@"%@", dict);
@try {
[dict writeToFile:filePath atomically:YES];
NSLog(@"Saved!! path: %@", filePath);
}
@catch (NSException *exception) {
NSLog(@"Error writing. Erro: %@", [exception description]);
}
[self showData];
}];
}
- (void) showData {
NSString *pathFinal = filePath;
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
// if failed to get the plist server uses the local built
pathFinal = [[NSBundle mainBundle] pathForResource:@"lista" ofType:@"plist"];
}
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:pathFinal];
NSLog(@"data displayed: %@", dict);
}