Статьи

Создание облачного бэкенда для вашего iOS-приложения с помощью Parse

Для приложений является общим требованием, чтобы сервер сохранял данные, передавал их другим пользователям и синхронизировал между устройствами пользователя.

Создание этого бэкэнда может потребовать времени, другого набора навыков и других ресурсов (например, серверов, служб push-уведомлений и т. Д.). К счастью, есть несколько платформ, которые предоставляют готовые настраиваемые бэкэнды, которые вы можете интегрировать в свои приложения. Они известны как «Backend as a Service», или, вкратце, BaaS .

Плюсы и минусы использования BaaS

Pros

  • Экономит ваше время и ресурсы.
  • Предоставляет разные услуги в одном пакете. Большинство доступных поставщиков BaaS не только предоставляют внутреннее облачное хранилище для ваших данных, они также предлагают такие услуги, как push-уведомления, аналитика, интеграция с социальными сетями и т. Д.
  • Обслуживает масштабирование. Платформы BaaS созданы для масштабирования, и, как разработчик, вам не нужно будет выполнять дополнительную работу, если вы набираете большое количество пользователей, просто платите больше.
  • Легко вносить изменения. Вы можете легко вносить изменения в функциональность вашего приложения, не требуя много переписывать его бэкэнд. Модели базы данных легко изменить с помощью панели инструментов платформы. Это пригодится всем, кто следует итеративной «методологии бережного запуска» доставки и улучшения приложения на основе данных об использовании.

Cons

  • Использование BaaS может быть дорогим. Хотя большинство этих услуг предлагают бесплатный пакет услуг для определенного количества запросов в месяц. Вещи могут внезапно стать дорогостоящими, если ваше приложение должно было стать успешным и быстро завоевать множество пользователей.
  • Вы можете столкнуться с блокировкой поставщика, когда переход на другую платформу затруднен Это становится меньшей проблемой, так как большинство сервисов теперь облегчают миграцию. Возможно, вам придется отказаться от некоторых функций, поскольку не все платформы BaaS предлагают то же самое.
  • Огромным недостатком, который следует учитывать перед использованием BaaS, является зависимость вашего приложения от стороннего сервиса. Поставщик может внести изменения в свою услугу (например, изменить тарифные планы), которые вам придется либо принять, либо искать другое решение. Существует также возможность закрытия службы. Это очень неудобно, так как вы будете вынуждены перенести свои данные другому провайдеру или создать свой собственный бэкэнд. Примером этого является недавнее отключение StackMob, которое вынудило разработчиков переносить свои данные.

Введите Parse

В этом уроке мы рассмотрим Parse, чтобы предоставить бэкэнд для приложения iOS. Мы кратко рассмотрим, что он предлагает, а затем создадим приложение, которое будет использовать его для регистрации пользователей, аутентификации и хранения пользовательских данных.

Parse — одна из самых популярных платформ Backend as a Service. Сервис предлагает три продукта в одном пакете: Parse Core, Parse Push и Parse Analytics.

Parse Core, как правило, обеспечивает сохранение данных и интеграцию с социальными сетями. Это также позволяет вам писать свой собственный код, который будет выполняться в облаке, обеспечивая тем самым пользовательскую логику на стороне сервера.

Parse Push используется для отправки push-уведомлений. Это позволяет разработчику настраивать, планировать и отправлять push-уведомления всем зарегистрированным пользователям или избранной группе пользователей.

Parse Analytics позволяет отслеживать данные вашего приложения. Вы можете отслеживать данные об использовании, такие как установки, активные пользователи, удержание пользователей, скорость открытия push-уведомлений и т. Д.

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

Проект состоит из входа в систему, регистрации, представления таблицы заметок и представления добавления / редактирования заметок, как показано ниже.

Обзор нашего приложения

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

Для начала вы должны сначала создать учетную запись на parse.com, если у вас ее еще нет. После входа в систему откройте панель инструментов, где вы сможете создать новое приложение, а также увидеть список всех ваших приложений. Создайте приложение под названием NoteApp .

Создать новое приложение в Parse

При создании приложения вы увидите окно, содержащее идентификаторы и ключи вашего приложения. Они будут использованы позже в приложении iOS.

Обзор приложения в Parse

Загрузите Parse SDK здесь . Разархивируйте файл и перетащите фреймворк в папку группы Frameworks вашего проекта.

Папка Frameworks в проекте iOS

Далее нам нужно добавить несколько библиотек в проект. Выберите свой проект в навигаторе проекта, убедитесь, что цель проекта выбрана, а затем нажмите на вкладку «Фазы сборки». Разверните «Связать двоичные файлы с библиотеками».

Добавьте фреймворки в ваше приложение для iOS

Щелкните значок «Добавить» в нижней части списка платформ и добавьте следующие библиотеки.

  • AudioToolbox.framework
  • CFNetwork.framework
  • CoreGraphics.framework
  • CoreLocation.framework
  • libz.dylib
  • MobileCoreServices.framework
  • QuartzCore.framework
  • Security.framework
  • StoreKit.framework
  • SystemConfiguration.framework

Откройте файл AppDelegate.mapplication:didFinishLaunchingWithOptions:

 #import <Parse/Parse.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [Parse setApplicationId:@"YOUR APP ID"
                  clientKey:@"YOUR CLIENT KEY"];
    return YES;
}

Чтобы проверить SDK, вставьте следующие строки под вызовом метода, который устанавливает идентификатор приложения и ключ клиента в application:didFinishLaunchingWithOptions:

 PFObject *testObject = [PFObject objectWithClassName:@"TestObject"];
testObject[@"foo"] = @"bar";
[testObject saveInBackground];

Запустите приложение и перейдите на панель анализа Parse в вашем браузере. Выберите ваше приложение и нажмите на вкладку Браузер данных. Вы должны увидеть данные таблицы объекта, который был создан выше.

Детали приложения в панели инструментов Parse

На панели инструментов вы найдете элементы управления для добавления / удаления строк и столбцов, установки разрешений, экспорта класса и даже удаления всего класса. TestObjectTestObject Удалите его, нажав кнопку « Дополнительно» и выбрав « Удалить класс» . Также удалите код, который создает Post

Вы можете не только создавать объекты программно, как мы делали выше, но вы также можете делать это с помощью панели инструментов. Мы собираемся создать класс Post

Нажмите на кнопку New Class и назовите класс title Оставьте тип как пользовательский . Добавьте два строковых столбца: contenttitle Добавьте несколько строк данных, просто заполните поля заголовка и содержимого.

Помимо столбцов contentUITableViewControllerobjectId , creationAt , updatedAt и ACL . ACL расшифровывается как списки контроля доступа. Они используются для указания контроля доступа, который пользователи и / или роли имеют в определенных объектах.

Вернувшись в наше приложение, мы создадим контроллер представления для представления таблицы заметок. У Parse есть удобный класс, который является подклассом PFQueryTableViewControllerJKENotesListViewController Мы будем использовать некоторые функции, которые он предлагает, такие как «pull to refresh» и «нумерация страниц» (что позволяет вам установить количество результатов, которые получает каждый запрос).

Создать новый класс. Я назвал мой PFQueryTableViewController Это должен быть подкласс PFQueryTableViewController

Джеймс Ю, один из создателей Parse, написал суть шаблона initWithStyle: Я заменил инициализатор шаблона initWithCoder:JKENotesListViewController.m

Ниже приведен код в // JKENotesListViewController.m
// NoteApp
//
// Created by Joyce Echessa on 6/5/14.
// Copyright (c) 2014 Joyce Echessa. All rights reserved.
//

#import "JKENotesListViewController.h"

@interface JKENotesListViewController ()

@end

@implementation JKENotesListViewController

- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithClassName:@"Post"];
self = [super initWithCoder:aDecoder];
if (self) {
// The className to query on
self.parseClassName = @"Post";

// Whether the built-in pull-to-refresh is enabled
self.pullToRefreshEnabled = YES;

// Whether the built-in pagination is enabled
self.paginationEnabled = YES;

// The number of objects to show per page
self.objectsPerPage = 15;
}
return self;
}

#pragma mark - UIViewController

- (void)viewDidLoad {
[super viewDidLoad];

// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;

// Uncomment
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

#pragma mark - PFQueryTableViewController

// Override to customize the look of a cell representing an object. The default is to display
// a UITableViewCellStyleDefault style cell with the label being the textKey in the object,
// and the imageView being the imageKey in the object.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
static NSString *CellIdentifier = @"Cell";

PFTableViewCell *cell = (PFTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[PFTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"EEEE, MMMM d yyyy"];
NSDate *date = [object createdAt];

// Configure the cell
cell.textLabel.text = [object objectForKey:@"title"];
cell.detailTextLabel.text = [dateFormatter stringFromDate:date];
cell.imageView.image = [UIImage imageNamed:@"note"];

return cell;
}

#pragma mark - UITableViewDelegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
}
@end

 

Чтобы определить класс в качестве контроллера представления для сцены, выберите контроллер представления таблицы из раскадровки. На вкладке «Инспектор идентификации» выберите JKENotesListViewController

Добавление пользовательского класса

Запустите приложение, и вы увидите список, отображающий названия заметок, которые вы создали на панели инструментов Parse.

Список заметок

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

В приведенном выше коде initWithCoder:Post Мы также установили некоторые параметры, которые позволят обновлять данные таблицы, потянув вниз список и активируя нумерацию страниц, которая устанавливает максимальное количество результатов, возвращаемых каждым запросом, которое мы устанавливаем равным 15.

tableView:cellForRowAtIndexPath:object:Cell В приведенном выше примере мы настраиваем каждую ячейку для отображения изображения, заголовка заметки и даты ее создания (в качестве субтитра). Если вы загрузили начальный проект, используемое изображение находится в папке группы «Вспомогательные файлы». В файле раскадровки ячейка-прототип таблицы имеет идентификатор Disclosure IndicatorSubtitleJKENotesViewController Настройки находятся в Инспекторе Атрибутов.

Редактирование представления ячейки таблицы

Теперь мы дадим возможность сохранять заметки. На панели навигации есть кнопка «Добавить», при нажатии на которую открывается представление «Добавить / редактировать». Чтобы приложение было простым, я буду использовать тот же вид для добавления, редактирования и просмотра заметок.

Создайте контроллер для представления. Я назвал мой UIViewController Это подкласс JKENotesViewController Установите класс как контроллер представления сцены Add / Edit Notes, выбрав Add / Edit view controller в раскадровке и установив пользовательский класс как JKENotesListViewController.m

Перед редактированием нового класса добавьте следующее в файл addNote Если вы посмотрите на свою раскадровку, есть два push-сегмента, ведущих к контроллеру представления Add / Edit. Я назвал их showNoteaddNote showNoteshowNote

Приведенный ниже код проверяет, какой segue был активирован, и, если это PFObjectJKENotesViewController- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"showNote"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
PFObject *object = [self.objects objectAtIndex:indexPath.row];

JKENotesViewController *note = (JKENotesViewController *)segue.destinationViewController;
note.note = object;
}
}
Таким образом, вы можете передавать данные между контроллерами представления.

 @property (nonatomic, strong) PFObject *note;

Добавьте следующее свойство в файл `JKENotesViewController.h`

 JKENotesViewController

Добавьте следующие выходы в файл реализации titleTextField contentTextViewsaveWasPressed Создайте соединение действия с помощью кнопки Сохранить. Я назвал мой @interface JKENotesViewController ()

@property (weak, nonatomic) IBOutlet UITextField *titleTextField;
@property (weak, nonatomic) IBOutlet UITextView *contentTextView;

@end
.
.
@implementation JKENotesViewController
- (IBAction)saveWasPressed:(id)sender {
}
@end
(Я предполагаю, что читатель знает, как это сделать. Если не смотреть на это руководство для действий и это для торговых точек ).

 JKENotesViewController.m

Я внес следующие изменения в файл //
// JKENotesViewController.m
// NoteApp
//
// Created by Joyce Echessa on 6/6/14.
// Copyright (c) 2014 Joyce Echessa. All rights reserved.
//

#import "JKENotesViewController.h"

@interface JKENotesViewController ()

@property (weak, nonatomic) IBOutlet UITextField *titleTextField;
@property (weak, nonatomic) IBOutlet UITextView *contentTextView;

@end

@implementation JKENotesViewController

- (void)viewDidLoad
{
[super viewDidLoad];

// Check to see if note is not nil, which let's us know that the note
// had already been saved.
if (self.note != nil) {
self.titleTextField.text = [self.note objectForKey:@"title"];
self.contentTextView.text = [self.note objectForKey:@"content"];
}
}

- (IBAction)saveWasPressed:(id)sender {

NSString *title = [self.titleTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

if ([title length] == 0) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error!"
message:@"You must at least enter a title"
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
}
else {

if (self.note != nil) {
[self updateNote];
}
else {
[self saveNote];
}
}

}

- (void)saveNote
{

PFObject *newNote = [PFObject objectWithClassName:@"Post"];
newNote[@"title"] = self.titleTextField.text;
newNote[@"content"] = self.contentTextView.text;

[newNote saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
[self.navigationController popViewControllerAnimated:YES];
} else {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error!"
message:[error.userInfo objectForKey:@"error"]
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
}
}];

}

- (void)updateNote
{

PFQuery *query = [PFQuery queryWithClassName:@"Post"];

// Retrieve the object by id
[query getObjectInBackgroundWithId:[self.note objectId] block:^(PFObject *oldNote, NSError *error) {

if (error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error!"
message:[error.userInfo objectForKey:@"error"]
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
}
else {
oldNote[@"title"] = self.titleTextField.text;
oldNote[@"content"] = self.contentTextView.text;

[oldNote saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
[self.navigationController popViewControllerAnimated:YES];
} else {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error!"
message:[error.userInfo objectForKey:@"error"]
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
}
}];
}

}];

}

@end

 

В viewDidLoadself.noteprepareForSegue:sender: Если пользователь нажал на заметку, то объект post был передан этому контроллеру представления методом title Если сообщение было передано, то мы устанавливаем заголовок TextField и контент TextView с contentsaveNote

При нажатии кнопки «Сохранить» выполняется аналогичная проверка, чтобы определить, будет ли создаваться новая заметка путем вызова updateNotesaveNote

В PFObjectsaveInBackgroundWithBlock:saveEventually Этот метод сохраняет данные асинхронно, поэтому ваше приложение не будет заблокировано до завершения сохранения. Если сеть медленная, вы можете вернуться к представлению таблицы заметок, и данные все равно будут сохранены. В Parse также есть метод saveEventually Если сетевое соединение отсутствует, updateNote

В методе saveInBackgroundWithBlock:objectId, и вызываем JKENotesListViewController.m

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

В - (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self loadObjects];
}

 viewDidLoad

Запустите приложение, и теперь, когда заметка добавлена ​​или отредактирована, изменения будут видны в виде таблицы.

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

Внесите следующие изменения в JKENotesListViewController.m- (void)viewDidLoad {
[super viewDidLoad];

PFUser *currentUser = [PFUser currentUser];
if (currentUser) {
NSLog(@"Current user: %@", currentUser.username);
}
else {
[self performSegueWithIdentifier:@"showLogin" sender:self];
}
}

 PFUser

Поскольку создание учетных записей пользователей является распространенным требованием в приложениях, Parse предоставляет класс currentUser

В приведенном выше примере мы проверяем, вошел ли пользователь в систему. Метод showLogin Если пользователь вошел в систему, мы регистрируем его имя пользователя, и представление загружается как обычно. Если пользователь не вошел в систему, то будет отображен вид входа в систему. В начальном проекте я уже создал переход к контроллеру представления Login и дал ему идентификатор UIViewController

Создайте новый класс и сделайте его подклассом JKELoginViewController Я назвал мой JKELoginViewController Выберите контроллер представления Login на раскадровке и на вкладке Identity Inspector установите его пользовательский класс в JKELoginViewController.h

Создайте подключения к розетке из поля ввода имени пользователя и пароля, а подключение к действию — из кнопки «Вход». Ниже показаны изменения в файле @interface JKELoginViewController : UIViewController

@property (weak, nonatomic) IBOutlet UITextField *usernameTextField;
@property (weak, nonatomic) IBOutlet UITextField *passwordTextField;

- (IBAction)login:(id)sender;

@end

 JKELoginViewController.m

Затем я внес следующие изменения в файл //
// JKELoginViewController.m
// NoteApp
//
// Created by Joyce Echessa on 6/6/14.
// Copyright (c) 2014 Joyce Echessa. All rights reserved.
//

#import "JKELoginViewController.h"
#import <Parse/Parse.h>

@interface JKELoginViewController ()

@end

@implementation JKELoginViewController

- (void)viewDidLoad
{
[super viewDidLoad];

self.navigationItem.hidesBackButton = YES;
}

- (IBAction)login:(id)sender {
NSString *username = [self.usernameTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSString *password = [self.passwordTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

if ([username length] == 0 || [password length] == 0) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error!"
message:@"You have to enter a username and password"
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
}
else {

[PFUser logInWithUsernameInBackground:username password:password block:^(PFUser *user, NSError *error) {
if (error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error!"
message:[error.userInfo objectForKey:@"error"]
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
}
else {
[self.navigationController popToRootViewControllerAnimated:YES];
}
}];
}
}

@end

 

В viewDidLoad Мы не хотим, чтобы пользователь мог вернуться к представлению таблицы заметок.

Метод login: Если аутентификация успешна, будет вызван корневой контроллер представления. В нашем случае это контроллер табличного представления, отображающий список заметок.

Теперь мы создадим контроллер для обработки регистрации пользователей. Создайте подкласс UIViewController Я назвал свой JKESignupViewControllerJKESignupViewController.h

Создайте следующие розетки и активные соединения. В @interface JKESignupViewController : UIViewController

@property (weak, nonatomic) IBOutlet UITextField *usernameTextField;
@property (weak, nonatomic) IBOutlet UITextField *emailTextField;
@property (weak, nonatomic) IBOutlet UITextField *passwordTextField;

- (IBAction)signup:(id)sender;

@end

 JKESignupViewController.m

В //
// JKESignupViewController.m
// NoteApp
//
// Created by Joyce Echessa on 6/6/14.
// Copyright (c) 2014 Joyce Echessa. All rights reserved.
//

#import "JKESignupViewController.h"
#import <Parse/Parse.h>

@interface JKESignupViewController ()

@end

@implementation JKESignupViewController

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}

- (IBAction)signup:(id)sender {
NSString *username = [self.usernameTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSString *password = [self.passwordTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSString *email = [self.emailTextField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

if ([username length] == 0 || [password length] == 0 || [email length] == 0) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error!"
message:@"You have to enter a username, password, and email"
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
}
else {
PFUser *newUser = [PFUser user];
newUser.username = username;
newUser.password = password;
newUser.email = email;

[newUser signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error!"
message:[error.userInfo objectForKey:@"error"]
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
}
else {
[self.navigationController popToRootViewControllerAnimated:YES];
}
}];
}
}

@end

 

Метод signup:PFUsersignUpInBackgroundWithBlock: Если регистрация прошла успешно, пользователь будет переведен в табличное представление со списком заметок. Запустите и протестируйте приложение с некоторыми данными.

Теперь мы позволим пользователю выйти из системы. Добавьте подключение к действию с помощью кнопки «Выход».

В JKENotesListViewController.h

 @interface JKENotesListViewController : PFQueryTableViewController

    - (IBAction)logout:(id)sender;

@end

В JKENotesListViewController.m

 - (IBAction)logout:(id)sender {
    [PFUser logOut];
    [self performSegueWithIdentifier:@"showLogin" sender:self];
}

Теперь пользователь может выйти из системы.

Мы собираемся создать отношения между постами и пользователем. В JKENotesViewController.mnewNote[@"content"]saveNote

 newNote[@"author"] = [PFUser currentUser];

При добавлении новой заметки зарегистрированный пользователь будет сохранен как его автор. При первом запуске колонка автора будет автоматически создана в Parse перед сохранением данных, поэтому вам не нужно создавать ее с помощью панели мониторинга, прежде чем вы сможете ее использовать.

Добавьте следующий метод в файл JKENotesListViewController.m

 // Override to customize what kind of query to perform on the class. The default is to query for
	// all objects ordered by createdAt descending.
	- (PFQuery *)queryForTable {
    
    	// Create a query
    	PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
    
    	// Follow relationship
    	if ([PFUser currentUser]) {
        	[query whereKey:@"author" equalTo:[PFUser currentUser]];
    	}
    	else {
        	// I added this so that when there is no currentUser, the query will not return any data
        	// Without this, when a user signs up and is logged in automatically, they briefly see a table with data
        	// before loadObjects is called and the table is refreshed.
        	// There are other ways to get an empty query, of course. With the below, I know that there
        	// is no such column with the value in the database.
        	[query whereKey:@"nonexistent" equalTo:@"doesn't exist"];
    	}
    
    	return query;
	}

Запустите и протестируйте приложение. Любая новая заметка, которую вы сохраните, теперь будет связана с вами, и только вы сможете увидеть свои заметки.

Наше приложение может сохранять и редактировать заметки, но не может их удалять. Я не буду добавлять функцию удаления, но если вы хотите удалить какой-либо объект, вы можете использовать метод deleteInBackground

 [myObject deleteInBackground];

Вывод

Мы рассмотрели использование Parse в качестве системы BaaS для ваших приложений. Использование таких готовых серверных сервисов имеет множество преимуществ, но оно также сопряжено с некоторыми подводными камнями, которые следует сравнивать с преимуществами при принятии решения о том, собирать ли его с нуля или использовать решение BaaS.

Даже если вы планируете создать свой собственный бэкэнд, возможно, стоит начать с BaaS, чтобы сократить время, необходимое вашему приложению, чтобы выйти на рынок, а также протестировать приложение на рынке и быстро проверить функциональность на основе данных об использовании.

Помимо Parse, существует несколько таких решений / сервисов, как Apigee , Backendless , Kii , built.io , Firebase . Они предоставляют разные услуги по разным ценам, и стоит посмотреть и сравнить разные продукты, чтобы решить, что лучше всего соответствует вашим потребностям.