Pee*_*dic 6 store core-data nsmutablearray persist polyline
我正在制作的应用程序Polyline根据用户坐标绘制CLLocationManager(这些都保存在一起NSMutableArray)
当应用关闭时,当前折线消失.如何在应用程序启动时存储要在CoreData中检索的点数组?用户在启动应用程序后所采取的所有过去"路线"应该被恢复并覆盖在地图上(这可能相当多,因此CoreData似乎是我收集的最佳选择).
这是我用来从加载的坐标创建MKPolyline的代码
-(IBAction)didClickLoadCoordinates:(id)sender {
// get a reference to the appDelegate so you can access the global managedObjectContext
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Route"];
NSError *error;
id results = [appDelegate.managedObjectContext executeFetchRequest:request error:&error];
if ([results count]) {
polyLine = (Route *)(results[0]);
NSArray *coordinates = polyLine.coordinates;
int ct = 0;
for (CLLocation *loc in coordinates) {
NSLog(@"location %d: %@", ct++, loc);
}
// this copies the array to your mutableArray
_locationsArray = [coordinates mutableCopy];
}
NSInteger numberOfSteps = _locationsArray.count;
//convert to coordinates array to construct the polyline
CLLocationCoordinate2D clCoordinates[numberOfSteps];
for (NSInteger index = 0; index < numberOfSteps; index++) {
CLLocation *location = [_locationsArray objectAtIndex:index];
CLLocationCoordinate2D coordinate2 = location.coordinate;
clCoordinates[index] = coordinate2;
}
MKPolyline *routeLine = [MKPolyline polylineWithCoordinates:clCoordinates count:numberOfSteps];
[_mapView addOverlay:routeLine];
Run Code Online (Sandbox Code Playgroud)
我创建了一个简单的类,它在应用关闭时保存带有数组的折线,并在应用返回时查询所有折线的核心数据.我假设您知道如何设置核心数据和托管对象上下文.此模式允许您直接设置NSArray对象并将其获取到核心数据对象中.其背后的基本原则是:https://coderwall.com/p/mx_wmq
首先,使用可转换属性(您的数组)和数据属性创建模型.

接下来,在折线对象上创建一个类别.

您现在应该在文件浏览器中包含这些项目

折线+ TransformableAttributes.h
#import "Polyline.h"
@interface Polyline (TransformableAttributes)
#pragma mark transformables
-(NSArray *)coordinates;
-(void)setCoordinates:(id)coordinates;
@end
Run Code Online (Sandbox Code Playgroud)
折线+ TransformableAttributes.m
@implementation Polyline (TransformableAttributes)
#pragma mark Transformables
-(NSArray *)coordinates {
if (!self.coordinates_data)
return nil;
return [NSKeyedUnarchiver unarchiveObjectWithData:self.coordinates_data];
}
-(void)setCoordinates:(id)coordinates {
NSData *coordinates_data = [NSKeyedArchiver archivedDataWithRootObject:coordinates];
[self setValue:coordinates_data forKey:@"coordinates_data"];
}
@end
Run Code Online (Sandbox Code Playgroud)
Appdelegate.m
- (void)applicationDidBecomeActive:(UIApplication *)application
{
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Polyline"];
NSError *error;
id results = [self.managedObjectContext executeFetchRequest:request error:&error];
Polyline *polyline = (Polyline *)(results[0]);
NSArray *coordinates = polyline.coordinates;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:@"Polyline" inManagedObjectContext:self.managedObjectContext];
Polyline *polyline = (Polyline *)object;
[polyline setCoordinates:@[@"a", @"b", @"c"]];
NSError *error;
if ([self.managedObjectContext save:&error]) {
NSLog(@"Saved");
}
else {
NSLog(@"Error: %@", error);
}
}
Run Code Online (Sandbox Code Playgroud)
如果它适合您,请告诉我.如果需要,我会更新我的答案,以便它可以有用.我不记得我最初在哪里找到这种模式,但它是一个非常有帮助和高度赞成的
编辑1:添加了gps视图
这是我添加的新控制器:

GPSViewController.h:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import "Polyline+TransformableAttributes.h"
@interface GPSViewController : UIViewController <CLLocationManagerDelegate>
{
NSMutableArray *_locationsArray;
Polyline *polyLine;
CLLocationManager *locationManager;
}
-(IBAction)didClickStartGPS:(id)sender;
-(IBAction)didClickSaveCoordinates:(id)sender;
-(IBAction)didClickLoadCoordinates:(id)sender;
Run Code Online (Sandbox Code Playgroud)
我的GPSViewController.m中的代码:
初始化数组以存储我的坐标.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
_locationsArray = [NSMutableArray array];
}
Run Code Online (Sandbox Code Playgroud)
单击GPS按钮时,它会显示在此处.locationManager是类的实例变量.
-(IBAction)didClickStartGPS:(id)sender {
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager startUpdatingLocation];
}
Run Code Online (Sandbox Code Playgroud)
这会将坐标保存到折线中并保持不变.注意:使用此代码,我不会执行任何特定的搜索描述符,因此如果您多次单击"保存",您将在核心数据中获得一堆折线,并且它可能每次只加载第一个折线.如果将其添加到折线对象,您可以执行搜索特定ID或日期等内容.
-(IBAction)didClickSaveCoordinates:(id)sender {
/*
NSInteger numberOfSteps = _locationsArray.count;
// you don't need to convert it to a coordinates array.
CLLocationCoordinate2D coordinates[numberOfSteps];
for (NSInteger index = 0; index < numberOfSteps; index++) {
CLLocation *location = [_locationsArray objectAtIndex:index];
CLLocationCoordinate2D coordinate2 = location.coordinate;
coordinates[index] = coordinate2;
}
*/
// get a reference to the appDelegate so you can access the global managedObjectContext
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
// creates a new polyline object when app goes into the background, and stores it into core data.
if (!polyLine) {
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:@"Polyline" inManagedObjectContext:appDelegate.managedObjectContext];
polyLine = (Polyline *)object;
}
[polyLine setCoordinates:_locationsArray];
NSError *error;
if ([appDelegate.managedObjectContext save:&error]) {
NSLog(@"Saved");
}
else {
NSLog(@"Error: %@", error);
}
}
Run Code Online (Sandbox Code Playgroud)
这将从核心数据加载第一个折线对象,并将其转换为CLLocations的_locationArray.我不会对你可以从中得到的CLLocationCoordinate2D做任何事情.
-(IBAction)didClickLoadCoordinates:(id)sender {
// get a reference to the appDelegate so you can access the global managedObjectContext
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Polyline"];
NSError *error;
id results = [appDelegate.managedObjectContext executeFetchRequest:request error:&error];
if ([results count]) {
polyLine = (Polyline *)(results[0]);
NSArray *coordinates = polyLine.coordinates;
int ct = 0;
for (CLLocation *loc in coordinates) {
NSLog(@"location %d: %@", ct++, loc);
}
// this copies the array to your mutableArray
_locationsArray = [coordinates mutableCopy];
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation *currentLocation = [locations lastObject];
CLLocationDegrees latitude = currentLocation.coordinate.latitude;
CLLocationDegrees longitude = currentLocation.coordinate.longitude;
CLLocationCoordinate2D locationCoordinates = CLLocationCoordinate2DMake(latitude, longitude);
//store latest location in stored track array;
[_locationsArray addObject:currentLocation];
}
Run Code Online (Sandbox Code Playgroud)
这段代码在我的github上更新:
github.com/bobbyren/StackOverflowTest.git
编辑:为每个折线添加新的MKPolyline:
NSArray *polylines = [fetchedResultsController allObjects];
for (Polyline *polyline in polylines) {
MKPolyline *mkPolyline = [MKPolyline polylineWithCoordinates:polyline.coordinates count:ct]; // assuming you have written out how to return polyline.coordinates as a CLLocationCoordinate2D[]
[mapView addOverlay:line];
}
[mapView reloadData];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10643 次 |
| 最近记录: |