Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Pro Core Data for iOS. Глава №1. Теоретическая часть

Anna | 2.07.2014 | нет комментариев

Сегодня хочу начать свободный перевод книги Михаеля Привата и Роберта Варнера «Pro Core Data for iOS», которую можете скачать по этой ссылке. Всякая глава будет содержать теоретическую и фактическую часть.

image

Оглавление:

  • Глава №1. Приступаем (Фактическая часть)
  • Глава №2. Усваиваем Core Data
  • Глава №3. Хранение данных: SQLite и другие варианты
  • Глава №4. Создание модели данных
  • Глава №5. Трудимся с объектами данных
  • Глава №6. Обработка результатирующих множеств
  • Глава №7. Настройка продуктивности и применяемой памяти
  • Глава №8. Управление версиями и миграции
  • Глава №9. Управление таблицами с применением NSFetchedResultsController
  • Глава №10. Применение Core Data в продвинутых приложениях

Приступаем

Что такое Core Data?

Применяя компьютеры для выполнения своих задач, люди рассчитывают, что внесенные ими метаморфозы будет сохранены. Сохранение изменений играет значимую роль в офисных программных пакетах, текстовых редакторах, играх, браузерах и тд. Множество программного обеспечения нуждается в вероятности беречь введенные пользователем данные для дальнейшего поправления состояния работы, но безусловно же есть и такое ПО, которое в этом не нуждается — калькуляторы, новостные ленты, будильники, виджеты о погоде.
Осознавание того, каким образом дозволено беречь данных на iDevice, является скептически значимым при разработке продвинутых приложений.

Apple предоставляет эластичный фрэймворк для работы с хранимыми на устройстве данными — Core Data. Безусловно же Core Data не панацея и есть другие варианты хранения данных, которые могут отменнее подойти при решении определенных задач, но уж дюже отлично и прекрасно Core Data вписывается в Cocoa Touch. Множество деталей по работе с хранилищем данных Core Data скрывает, разрешая вам сконцентрироваться на том, что подлинно делает ваше приложение веселым, уникальным и комфортным в применении.

Не смотря на то, что Core Data может беречь данные в реляционной базе данных как бы SQLite, Core Data не является СУБД. По-правде Core Data в качестве хранилища может вообще не применять реляционные базы данных. Core Data не является чем-то как бы Hibernate, правда и предоставляет некоторые вероятности ORM. Core Data скорее является оболочкой/фрэймворком для работы с данными, которая разрешает трудиться с сущностями и их связями (отношениями к иным объектами), признаками, в том виде, тот, что напоминает работы с объектным графом в обыкновенном объектно-ориентированном программировании.

Знаете ли Вы?

Core Data был внедрён лишь начиная с Mac OS X 10.4 Tiger и iPhone SDK 3.0

История хранения данных в iOS

Как за выпущенные Pixar мультики мы обязаны благодарить компанию NeXT, так и за Core Data мы обязаны сказать ей спасибо. Core Data родилась и эволюционировала из спецтехнологии, называемой Enterprise Objects Framework (EOF).
Дебют фрэймворка доводится на 2005 год с запуском Mac OS X 10.4 (Tiger), а вот в IPhone возникает лишь начиная с версии 3.0.
До того, как Core Data пришла на IPhone, разработчикам доводилось не приторно и для хранения данных могли быть использованы следующие варианты:
1) Списки свойств, которые содержали пары ключ-значение из разных типов данных.
2) Сериализация данных и хранение их в файлах (применялся протокол NSCoding)
3) Реляционная база данных SQLite
4) Хранение данных в облаке

Эти способы всё еще продолжают применяться, правда и ни один способ из четырёх не сравнится по удобству с применением Core Data. Невзирая на рождение таких фрэймворком, как FMDatabase и ActiveRecord, для решения задачи с хранением данных до возникновения Core Data, разработчики с удовольствием переключились на Core Data позже его возникновения.
Правда повторюсь, что Core Data не является лекарством от всех болезней, изредка вы безусловно будете обращаться к решениям с применением, скажем, списка свойств, но чаще каждого вы будете сталкиваться с необходимостью и желанием применять в своих приложениях именно Core Data, как инструмент, тот, что наилучшим образом разрешает решить вашу задачу.
Чем Почаще и чем огромнее вы будете программировать и применять Core Data, тем Почаще у вас будет появляться не вопрос «Стоит ли мне применять Core Data?», а «Есть ли повод не применять Core Data?».

Создание простого приложения с Core Data

В этой сегменты мы сотворим примитивное приложение основанное на Core Data из одного из образцов XCode, основные части которого разберём. В конце этой части вы осознаете, каким образом приложение взаимодействует с Core Data для хранения и приобретения данных.

Осознавание основных компонентов Core Data

Перед тем, как погрузиться в код и разбор тестового приложения, нужно иметь представление о компонентах Core Data. На рисунке ниже продемонстрированы основные элементы, которые мы будем применять в тестовом приложении.

Как пользователь Core Data вы никогда не обязаны трудиться напрямую с хранилищем данных. Абстрагируйтесь от хранилища, от типа хранилища, думайте только о данных! Спецификой такого подхода является вероятность безболезненно сменить тип хранилища (был XML файл, а стал SQLite) не меняя огромное кол-ва написанного вами кода.
Объекты, которые находятся под управлением фрэймворка (Core Data) обязаны наследовать методы/свойства класса NSManagedObject.
Так же, как и людям, объектам необходима среда в которой они могут существовать, такая среда есть и, именуется она managed object context (среда управляемых объектов) либо легко context. Среда, в которой находится объект, следить не только за тем, в каком состоянии находится объект с которым вы трудитесь, но и за состояниями связанных объектов (объектов, которые зависимы от данного и от которых зависим он сам).
Экземпляр класса NSManagedObjectContext предоставляет ту самую среду для объектов, объект данного типа должен быть доступен в вашем приложении неизменно. Обыкновенно экземпляр класса NSManagedObjectContext является свойством делегата вашего приложения. Без среды, без экземпляра класса NSManagedObjectContext вам легко не удастся трудиться с Core Data.

Создание нового плана

Запустим XCode и сделаем новейший план из образца Master-Detail Application:
image

Заполним поля дальнейшим образом:
image

И позже заключения создания увидим приблизительно такую картину:
image

Запускаем наш план

Перед тем как начать разбираться, что находится под капотом данного приложения, давайте запустим и разберемся, что вообще делает приложение.
Жмём на кнопку «Run» и перед нами появится вот такое:
image

Нажмем несколько раз на кнопку с ” ” и в списке появится несколько записей со временем.
image

Сейчас закончим (остановим) работу приложения и, если приложение не использовало бы Core Data для хранения данных, то при очередном запуске мы увидели бы пустой список вновь, впрочем позже перезапуска мы видим всё ту же картину:
image

Разбираем составляющие приложения

Конструкция приложения касательно примитивна. В присутствие имеется модель данных, которая описывает сущность хранимую в базе данных (хранилище); контроллер, тот, что облегчает взаимодействия между экраном (таблицей) и хранилищем данных; делегат приложения, тот, что помогает инициализировать и запустить приложение.
На изображении представленном ниже показаны классы используемые в приложении и как они соотносятся друг с ином:
image

Обратите внимание на то, что класс MasterViewController содержит качество, которое ссылается на экземпляр класса NSManagedObjectContext для взаимодействия с Core Data. Пройдясь по коду дозволено увидеть, что MasterViewController получает managed object context из свойства делегата приложения.

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
   self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
   if(self){
      self.title = NSLocalizedString(@"Master", @"Master");
      id delegate = [[UIApplication sharedApplication] delegate];
      self.managedObjectContext = [delegate managedObjectContext];
   }

   return self;
}

BasicApplication.xcdatamodel представляет собой директорию в файловой системе, которая содержит информацию о структуре модели данных. Модель данных является основой всякого приложения использующего Core Data.
Модель данных данного приложения описывает лишь одну сущность — Event. Сущность Event содержит лишь одно качество (поле, признак) — timeStamp типа Date.

Сущность Event типа NSManagedObject, тот, что считается основным для всех сущностей находящимся под управлением Core Data. Во 2-й главе мы разглядим тип NSManagedObject больше детально.

Извлечение/выборка данных

Дальнейшим классом, тот, что нас волнует, является MasterViewController. В его заголовочном файле описаны два свойства на которые мы обратим внимание:

@property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;

NSFetchedResultsController представляет собой контроллер, предоставляемый фрэймворком Core Data для управления запросами к хранилищу.
NSManagedObjectContext является знаменитой нам теснее средой существования объектов типа NSManagedObject.

Реализация класса MasterViewController, которую дозволено обнаружить в файле MasterViewController.m, показывает, каким образом дозволено взаимодействовать с Core Data для приобретения и хранения данных. В реализации класса MasterVIewController имеется очевидный геттер fetchedResultsController, тот, что изготавливает заблаговременную настройку запроса на выборку данных из хранилища.

Первым шагом к осуществлению запроса на выборку данных является создание запроса:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

Итоги запроса могут быть отсортированы при помощи NSSortDescriptor. NSSortDescriptor определяет поле для сортировки и тип сортировки (по возрастанию либо убыванию).
В нашем примере сортируем по убыванию времена создания записей:

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];

Позже того, как запрос определен, мы можем приступить к созданию NSFetchedResultsController.
Применяя в качестве делегата NSFetchedResultsController MasterVIewController мы можем следить за состоянием данных хранилища (удаление, добавление, перемещение и тд) и безболезненно интегрировать данное решение с UITableView. Мы можем безусловно же получить те же итоги вызывая способ executeFetchRequest в managed object context, но в таком случае мы не получим и не сумеем воспользоваться всеми превосходствами NSFetchedResultsController.
Создание и настройка переменной экземпляра класса NSFetchedResultsController:

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;

Знаете ли Вы?

Вы вероятно подметили, что применяемый ранее способ initWithFetchRequest имеет параметр cacheName. При передаче в качестве довода nil Вы исключаете вероятность кэширования итога запроса, но при указании названия кэша, вы разрешаете Core Data проверить присутствие такого же ранее осуществленного запроса и воротить итог из кэша. В отвратном случае, если запроса с таким именем кэша нет, то будет осуществлен запрос к хранилищу и возвращены нужные данные, которые будет закэшированы позднее.

В заключение нам осталось только исполнить запрос для приобретения данных:

NSError *error = nil;
if(![self.fetchedResultsController performFetch:&error]){
   NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
   abort();
}

Ниже вы можете ознакомиться с полным геттером fetchedResultsController:

- (NSFetchedResultsController *)fetchedResultsController
{
    if (_fetchedResultsController != nil)
        return _fetchedResultsController;

   NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
   NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];
   [fetchRequest setEntity:entity];

   [fetchRequest setFetchBatchSize:20];

   NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];
   NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
   [fetchRequest setSortDescriptors:sortDescriptors];

   NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"];
   aFetchedResultsController.delegate = self;
   self.fetchedResultsController = aFetchedResultsController;

   NSError *error = nil;
   if(![self.fetchedResultsController performFetch:&error]){
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
      abort();
   }

   return __fetchedResultsController;
}

NSFetchedResultsController представляет собой кое-что как бы коллекции объектов типа NSManagedObject, для этого у него даже имеется свойства fetchedObjects типа NSArray для приобретения доступа к итогам запроса.
Класс MasterVIewController, тот, что так же расширяет вероятности UITableViewController, показывает нам насколько комфортно применять NSFetchedResultsController для управления содержимым таблиц.

Вставка нового объекта

Стремительно окинув взором способ insertNewObject: станет ясно, каким образом создаются и добавляются новые события в хранилище. NSManagedObject определяются изложением сущности из модели данных и могут существовать только в определенном контексте (среде). Первым шагом для создания нового объекта является приобретение контекста в котором данный объект будет сделан:

NSManagedObjectContext *managedObjectContext = [self.fetchedResultsController managedObjectContext];
NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];

Создаём NSManagedObject:

NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntity:[entity name] inManagedObjectContext:context];
[newManagedObject setValue:[NSDate date] forKey:@"timeStamp"];

Последним шагом, тот, что нужно осуществить, является сохранение контекста в котором был сделан новейший объект. Учтите, что при сохранении контекста все несохраненные ранее метаморфозы будут сохранены.

NSError *error = nil;
if(![context save:&error]){
   NSLog(@"Unresolved error: %@, %@", error, [error userInfo]);
   abort();
}

Полный способ добавления нового объекта представлен ниже:

- (void)insertNewObject {
   NSManagedObjectContext *managedObjectContext = [self.fetchedResultsController managedObjectContext];
   NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
   NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];

   [newManagedObject setValue:[NSDate date] forKey:@"timeStamp"];

   NSError *error = nil;
   if(![context save:&error]){
      NSLog(@"Unresolved error: %@, %@", error, [error userInfo]);
      abort();
   }
}
Инициализация контекста (среды)

Видимо, что всё, что мы прежде делали не может быть достигнуто без создания объекта контекста, без той самой среды в которой существует и живет объект. Как раз за создание этой самой среды отвечает делегат приложения. Три свойства, которые обязаны быть непременно в любом приложении использующем Core Data приложении:

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

Обратите внимание на то, что все три свойства readonly, делается это для того, Дабы извне их невозможно было установить. Исследуя BasicApplicationAppDelegate.m видно, что все три свойства имеют очевидные геттеры.

Managed Object Model:

- (NSManagedObjectModel *)managedObjectModel {
   if(_managedObjectModel != nil){
      return _managedObjectModel;
   }

   NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"BasicApplication" withExtension:@"momd"];
   _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modeURL];

   return _managedObjectModel;
}

Позже чего создается хранилище поддерживающее сделанные модели данных. В нашем случае, собственно, как и в большинстве других с применением Core Data, хранилище данных базируется на SQLite.

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
   if(_persistentStoreCoordinator != nil){
      return _persistentStoreCoordinator;
   }

   NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"BasicApplication.sqlite"];

   NSError* error = nil;
   _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
   if(![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]){
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
      abort();
   }

   return _persistentStoreCoordinator;
}

Создаём контекст (среду):

- (NSManagedObjectContext *)managedObjectContext {
   if(_managedObjectContext != nil){
      return _managedObjectContext;
   }

   NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
   if(coordinator != nil){
      _managedObjectContext = [[NSManagedObjectContext alloc] init];
      [_managedObjectContext setPersistentStoreCoordinator:coordinator];
   }

   return _managedObjectContext;
}

Контекст применяется во всём приложении в качестве интерфейса для взаимодействия с Core Data и непрерывным хранилищем.
Последовательность инициализации Core Data:

Механизм запускается при вызове способа application:didFinishLaunchingWithOptions:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

   MasterViewController *controller = [[MasterViewController alloc] initWithNibName:@"MasterViewController" bundle:nil];
   self.navigationController = [[UINavigationController alloc] initWithRootViewController:controller];
   self.window.rootViewController = self.navigationController;

   [self.window makeKeyAndVisible];
   return YES;
}

Вызывая геттер свойства managedObjectContext делегата приложения на выполнение запускается цепочка действий:
— (NSManagedObjectContext *)managedObjectContext вызывает
— (NSPersistentStoreCoordinator *)persistentStoreCoordinator, тот, что в свою очередь изготавливает вызов
— (NSManagedObjectModel *)managedObjectModel.
Таким образом вызов геттер-способа managedObjectContext инициализирует каждый стэк объектов Core Data и приводит Core Data в подготовленность.

Добавление Core Data в теснее присутствующий план

Осуществляется в три шага:

  1. Добавление фрэймворка Core Data
  2. Создание модели данных
  3. Инициализация контекста (среды)
Добавление фрэймворка Core Data

В мире Objective-C библиотеки называют фрэймворками.
Типовые фрэймворки, которые теснее подключены в «чистых» планах и которые вы Почаще каждого увидите:

  • UIKit
  • Foundation
  • Core Graphics

Где производится добавление новых фрэймворков:

Выбираем фрэймворк для подключения:

Создание модели данных

Ни одно приложение Core Data не может считаться законченным без модели данных. Модель данных описывает все сущности, которые будут находиться в ведении Core Data.
Для создания новой модели данных: File -> New -> New File

Назовем нашу модель MyModel.xcdatamodeld:

Позже создания модели перед вами откроется окно редактирования (создания) сущностей.

Сделать новую сущность дозволено кликнув на кнопку ” ” в левой нижней части XCode, а добавить новейший признак сущности дозволено нажав на кнопку ” ” теснее в разделе «Attributes» и после этого предпочесть его тип.

Инициализация контекста (среды)

Конечный шаг состоит в инициализации контекста, хранилища и объектной модели. Почаще каждого вы можете воспользоваться кодом, тот, что механически генерируется XCode в «пустых» планах использующих Core Data.

DemoAppAppDelegate.h

#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>

@interface DemoAppDelegate : UIResponder <UIApplicationDelegate> {
}

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) UINavigationController *navigationController;

@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (void)saveContext;
- (NSURL *)applicationsDocumentsDirectory;

@end

Переключимся в *.m файл DemoAppAppDelegate и напишем следующие строки:

@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

Дальше следует код, тот, что изготавливает инициализацию модели данных, хранилища и контекста.

- (NSManagedObjectModel *)managedObjectModel {
   if (_managedObjectModel != nil){
      return _managedObjectModel;
   }

   NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyModel" withExtension:@"momd"];
   _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modeURL];

   return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
   if(_persistentStoreCoordinator != nil){
      return _persistentStoreCoordinator;
   }

   NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"DemoApp.sqlite"];

   NSError *error = nil;
   _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
   if(![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error&error]){
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
      abort();
   }

   return _persistentStoreCoordinator;
}
- (NSManagedObjectContext *)managedObjectContext {
   if(_managedObjectContext != nil){
      return _managedObjectContext;
   }

   NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
   if(coordinator != nil){
      _managedObjectContext = [[NSManagedObjectContext alloc] init];
      [_managedObjectContext setPersistentStoreCoordinator:coordinator];
   }

   return _managedObjectContext;
}

Способы, тот, что ранее мы еще нигде не реализовывали:

- (NSURL *)applicationDocumentsDirectory{
   return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
- (void)saveContext {
   NSError *error = nil;
   NSManagedObjectContext *managedObjectContext = [self managedObjectContext];

   if(managedObjectContext != nil) {
      if([managedObjectContext hasChanges] && ![managedObjectContext save:&error]){
         NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
         abort();
      }
   }
}

Сейчас, когда мы подключили Core Data, наше приложение может применять его для хранения данных.
Давайте реализуем легкой пример, тот, что бы дозволил нам удостовериться в том, что всё работает так, как нужно и данные подлинно сохраняются.
В тестовом примере мы будем определять кол-во раз, которое было запущено наше приложение.
Внесём маленькие метаморфозы в способ application:didFinishLaunchingWithOptions: делегата приложения в виде приобретения кол-ва раз, которое приложения запускалось ранее и добавление нового события запуска.

Код для приобретения предыдущих запусков приложения:

NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyData" inManagedObjectContext:context];
[request setEntity:entity];
NSArray *results = [context executeFetchRequest:request error:nil];

Позже чего мы можем пройтись по каждому массиву дальнейшим образом:

for(NSManagedObject *object in results){
   NSLog(@"Found %@", [object valueForKey:@"myAttribute"];
}

Добавим новую запись и сбережем:

NSString *launchTitle = [NSString stringWithFormat:@"launch %d", [results count]];
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
[object setValue:launchTitle forKey:@"myAttribute"];
[self saveContext];
NSLog(@"Added : %@", launchTitle);

Позже первого запуска приложение выведет в консоль следующую строку:

2011–02-25 05:13:23.783 DemoApp[2299:207] Added: launch 0

Позже второго запуска:

2011–02-25 05:15:48.883 DemoApp[2372:207] Found launch 0 
2011–02-25 05:15:48.889 DemoApp[2372:207] Added: launch 1

Полный способ выглядит дальнейшим образом:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   NSManagedObjectContext *context = [self managedObjectContext];
   NSFetchRequest *request = [[NSFetchRequest alloc] init];
   NSEntityDescription *entity = [NSEntityDescription entytyForName:@"MyData" inManagedObjectContext:context];
   [request setEntity:entity];
   NSArray *results = [context executeFetchRequest:request error:nil];

   for(NSManagedObject *object in results){
      NSLog(@"Found %@", [object valueForKey:@"myAttribute"]);
   }

   NSString *launchTitle = [NSString stringWithFormat:@"launch %d", [results count]];
   NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
   [object setValue:launchTitle forKey:@"myAttribute"];
   [self saveContext];
   NSLog(@"Added : %@", launchTitle);   

   [self.window makeKeyAndVisible];
   return YES;
}
В заключение

Умоляю об ошибках не писать в комментариях, отменнее сразу в собственные сообщения.

Продолжать ли переводы? Есть ли интерес к данной теме?

Благодарствую за внимание!

 

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB