码迷,mamicode.com
首页 > 其他好文 > 详细

Parse Local Datastore

时间:2015-07-31 00:58:23      阅读:275      评论:0      收藏:0      [点我收藏+]

标签:

Parse Local Datastore

简介

本文翻译了Parse关于本地存储的部分,链接如下:Parse Local Datastore

翻译

The Parse iOS/OSX SDK provides a local datastore which can be used to store and retrieve PFObjects, even when the network is unavailable. To enable this functionality, add libsqlite3.dylib and call [Parse enableLocalDatastore] before your call to setApplicationId:clientKey:.
Parse iOS/OSX SDK提供了一个本地数据存储用以存储和检索PFObjects,即使在无网络状态下也可以使用。为了开启这个功能,请先添加libsqlite3.dylib并且在你调用setApplicationId:clientKey:前先调用[Parse enableLocalDatastore]。

@implementation AppDelegate

- (void)application:(UIApplication *)application didFinishLaunchWithOptions:(NSDictionary *)options {
  [Parse enableLocalDatastore];
  [Parse setApplicationId:@"parseAppId" clientKey:@"parseClientKey"];
}

@end

There are a couple of side effects of enabling the local datastore that you should be aware of. When enabled, there will only be one instance of any given PFObject. For example, imagine you have an instance of the "GameScore" class with an objectId of "xWMyZ4YEGZ", and then you issue a PFQuery for all instances of "GameScore" with that objectId. The result will be the same instance of the object you already have in memory.
开启这个功能后有几个方面的影响是你需要注意的。当开启时,只有一个PFObject。例如,假设你有一个objectId为"xWMyZ4YEGZ"的“GameScore”类的实例,然后你用这个objectId来查询“GameScore”的所有实例。结果将是已经在你内存中的那个实例。

Another side effect is that the current user and current installation will be stored in the local datastore, so you can persist unsaved changes to these objects between runs of your app using the methods below.
另一个影响就是当前用户和当前安装表已经存在了本地数据库,所以在你运行你的应用期间,你可以用以下方法来保存这些对象没有保存的内容。

Calling the saveEventually method on a PFObject will cause the object to be pinned in the local datastore until the save completes. So now, if you change the current PFUser and call [[PFUser currentUser] saveEventually], your app will always see the changes that you have made.
在一个PVObject上调用saveEventually方法将会使得对象与本地的数据库相连,直到完全保存。因此如果你修改当前的PFUser并且调用[[PFUser currentUser] saveEventually],你的应用总会看到你所做的修改。

Pinning

You can store a PFObject in the local datastore by pinning it. Pinning a PFObject is recursive, just like saving, so any objects that are pointed to by the one you are pinning will also be pinned. When an object is pinned, every time you update it by fetching or saving new data, the copy in the local datastore will be updated automatically. You don‘t need to worry about it at all.
你可以通过连接本地数据库来存储一个PFObject。连接一个PFObject是递归的,就像保存那样,因此所有对象都会被另一个对象所指向,你所连接的对象同样被别的对象连接。当一个对象被连接,每一次你通过读取后更新或者是保存一个新数据,它在本地数据库中的备份也将会被自动更新。你完全不需要担心。

PFObject *gameScore = [PFObject objectWithClassName:@"GameScore"];
gameScore[@"score"] = @1337;
gameScore[@"playerName"] = @"Sean Plott";
gameScore[@"cheatMode"] = @NO;
[gameScore pinInBackground];

If you have multiple objects, you can pin them all at once with the pinAllInBackground convenience method.
假如你有多个对象,你可以使用简便方法pinAllInBackground来一次性连接全部对象。

[PFObject pinAllInBackground:listOfObjects];

Retrieving Objects

Storing objects is great, but it‘s only useful if you can then get the objects back out later. Retrieving an object from the local datastore works just like retrieving one over the network. The only difference is calling the fromLocalDatastore method to tell the PFQuery where to look for its results.
保存数据是好的,但只有在保存后你可以重新取出数据这种好处才能体现出来。从本地数据库中检索一个对象跟从网络中检索是相似的。唯一不现的是需要调用 fromLocalDatastore 方法来告诉PFQuery该从哪里获取结果。

PFQuery *query = [PFQuery queryWithClassName:@"GameScore"];
[query fromLocalDatastore];
[[query getObjectInBackgroundWithId:@"xWMyZ4YE"] continueWithBlock:^id(BFTask *task) {
  if (task.error) {
    // Something went wrong.
    return task;
  }

  // task.result will be your game score
  return task;
}];

Querying

Often, you‘ll want to find a whole list of objects that match certain criteria, instead of getting a single object by id. To do that, you can use a PFQuery. Any PFQuery can be used with the local datastore just as with the network. The results will include any object you have pinned that matches the query. Any unsaved changes you have made to the object will be considered when evaluating the query. So you can find a local object that matches, even if it was never returned from the server for this particular query.
有时你会想要找到符合某个标准的所有对象的列表,而不是通过id找到的一个单独对象。你可以使用PFQuery来完成这个。任意的PFQuery都可以用于本地存储,使用方法和网络一样。结果会包含所有符合标准的已经被连接的对象。当评估查询时任意你做的没有保存的修改都会被考虑进去。所以即使这个查询你从来没有从服务器上获取过你也可以在本地对象中找到。

PFQuery *query = [PFQuery queryWithClassName:@"GameScore"];
[query fromLocalDatastore];
[query whereKey:@"playerName" equalTo:@"Joe Bob"];
[[query findObjectsInBackground] continueWithBlock:^id(BFTask *task) {
  if (task.error) {
    NSLog(@"Error: %@", task.error);
    return task;
  }

  NSLog(@"Retrieved %d", task.result.count);
  return task;
}];

Security

The same security model that applies to objects in Parse applies to objects in the Local Datastore. Read-write permissions are defined by PFACLs and a user cannot access or modify anything they don‘t have permission to.
被用于Parsec对象的安全模式同样被用于本地数据存储。读写权限定义在PFACL中,并且一个用户在没有权限的情况下无法读取和修改任何的内容。

The only difference is that you won‘t be able to access any data protected by Role based ACLs due to the fact that the Roles are stored on the server. To access this data protected by Role based ACLs, you will need to ignore ACLs when executing a Local Datastore query:
唯一不同的是,你无法访问任何基于ACL的Role表所保护的数据,因为Role数据是存储在服务器上的。为了访问基于ACL的Role表,你需要在执行本地存储查询时忽略ACL:

PFQuery *query = [[[PFQuery queryWithClassName:@"Note"]
                   fromLocalDatastore]
                  ignoreACLs];

Unpinning

When you are done with an object and no longer need it to be in the local datastore, you can simply unpin it. This will free up disk space on the device and keep your queries on the local datastore running quickly.
当你使用完一个对象并且无需它还存留在本地数据存储中时,你可以简单地解除连接。这可以释放你设备的磁盘空间以及让你在本地存储的查询运行得更快。

[gameScore unpinInBackground];

There‘s also a method to unpin several objects at once.
这里还有一个方法可以一次性将多个对象解除连接。

[PFObject unpinAllInBackground:listOfObjects];

Pinning with Labels

Manually pinning and unpinning each object individual is a bit like using malloc and free. It is a very powerful tool, but it can be difficult to manage what objects get stored in complex scenarios. For example, imagine you are making a game with separate high score lists for global high scores and your friends‘ high scores. If one of your friends happens to have a globally high score, you need to make sure you don‘t unpin them completely when you remove them from one of the cached queries. To make these scenarios easier, you can also pin with a label. Labels indicate a group of objects that should be stored together.
手动地连接和解除连接每一个可用的对象有点类似于使用malloc和free。这是一个非常强大的工具,但是在复杂的场景管理这些对象非常困难。例如,假设你正在做一个游戏,游戏中有两个分开的列表分别用来列举全球的高分榜和你的朋友的高分榜。如果你有一个朋友刚好有一个全球性的高分,你需要确保当你从一个缓存查询中移除时没有完全的解除连接。为了使这些场景变得简单,你可以使用标签来进行连接。标签表象一组应该存储在一些的对象。

// Add several objects with a label.
[PFObject pinAllInBackground:someGameScores withName:@"MyScores"];

// Add another object with the same label.
[anotherGameScore pinInBackgroundWithName:@"MyScores"];

To unpin all of the objects with the same label at the same time, you can pass a label to the unpin methods. This saves you from having to manually track which objects are in each group you care about.
为了在同一时间解除所有具有相同标签的对象,你可以传递标签给解除连接的方法。这可以让你从你需要关心的每一组对象中释放出来,无需追踪它们。

[PFObject unpinAllObjectsInBackgroundWithName:@"MyScores"];

Any object will stay in the datastore as long as it is pinned with any label. In other words, if you pin an object with two different labels, and then unpin it with one label, the object will stay in the datastore until you also unpin it with the other label.
不管连接时携带什么标签,这些对象都会一直保存在数据存储中。换句话说,如果你用两个不同的标签去连接同一个对象,然后用其中一个标签解除,对象还会存在于数据存储中,除非你使用另外一个标签去解除连接。

Caching Query Results

Pinning with labels makes it easy to cache the results of queries. You can use one label to pin the results of each different query. To get new results from the network, just do a query and update the pinned objects.
用标签来连接可以使得缓存查询结果变得容易。你可以一个标签来连接每一个不同的查询结果。要从网络上获取新的结果,只需要查询和更新连接的对象即可。

PFQuery *query = [PFQuery queryWithClassName:@"GameScore"];
[query orderByDescending:@"score"];

// Query for new results from the network
[[query findObjectsInBackground] continueWithSuccessBlock:^id(BFTask *task) {
  return [[PFObject unpinAllObjectsInBackgroundWithName:@"HighScores"] continueWithSuccessBlock:^id(BFTask *ignored) {
    // Cache the new results.
    NSArray *scores = task.result;
    return [PFObject pinAllInBackground:scores withName:@"HighScores"];
  }];
}];

When you want to get the cached results for the query, you can then run the same query against the local datastore.
当你想要从查询中获得缓存结果时,你可以在本地存储使用相同的查询语句。

PFQuery *query = [PFQuery queryWithClassName:@"GameScore"];
[query fromLocalDatastore];
[query orderByDescending:@"score"];

[[query findObjectsInBackground] continueWithBlock:^id(BFTask *task) {
  if (task.error) {
    // Something went wrong.
    return task;
  }

  // Yay! Cached scores!
  return task;
}];

Syncing Local Changes

Once you‘ve saved some changes locally, there are a few different ways you can save those changes back to Parse over the network. The easiest way to do this is with saveEventually. When you call saveEventually on a PFObject, it will be pinned until it can be saved. The SDK will make sure to save the object the next time the network is available.
一旦你在本地作了一些修改,你有几种不同的方法存储这些修改至Parse的服务器上。最简单的方法是使用saveEventually。当你调用使用PFObject发送saveEventually消息时,它将会被连接直到被保存。SDK会确保在下次网络可用时保存对象。

[gameScore saveEventually];

If you‘d like to have more control over the way objects are synced, you can keep them in the local datastore until you are ready to save them yourself using saveInBackground. To manage the set of objects that need to be saved, you can again use a label. The fromPinWithName: method on PFQuery makes it easy to fetch just the objects you care about.
如果你想通过同步对象方法进行更多的控制,你可以保持它们在本地存储上直接你使用svaeInBackground保存它们。为了管理需要被保存的对象集合,你可以再次使用标签。PFQuery上的fromPinWithName:方法可以方便地抓取你关心的对象。

PFQuery *query = [PFQuery queryWithClassName:@"GameScore"];
[query fromPinWithName:@"MyChanges"];
[[query findObjectsInBackground] continueWithBlock:^id(BFTask *task) {
  NSArray *scores = task.result;
  for (PFObject *score in scores) {
    [[score saveInBackground] continueWithSuccessBlock:^id(BFTask *task) {
      return [score unpinInBackground];
    }];
  }
  return task;
}];

说明

该篇翻译在很多地方可能都不准确,如果有读者有好的翻译,非常希望可以给个链接让我学习。

Parse Local Datastore

标签:

原文地址:http://www.cnblogs.com/limaofuyuanzhang/p/4691003.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!