Для приложений является общим требованием, чтобы сервер сохранял данные, передавал их другим пользователям и синхронизировал между устройствами пользователя.
Создание этого бэкэнда может потребовать времени, другого набора навыков и других ресурсов (например, серверов, служб 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 .
При создании приложения вы увидите окно, содержащее идентификаторы и ключи вашего приложения. Они будут использованы позже в приложении iOS.
Загрузите Parse SDK здесь . Разархивируйте файл и перетащите фреймворк в папку группы Frameworks вашего проекта.
Далее нам нужно добавить несколько библиотек в проект. Выберите свой проект в навигаторе проекта, убедитесь, что цель проекта выбрана, а затем нажмите на вкладку «Фазы сборки». Разверните «Связать двоичные файлы с библиотеками».
Щелкните значок «Добавить» в нижней части списка платформ и добавьте следующие библиотеки.
- AudioToolbox.framework
- CFNetwork.framework
- CoreGraphics.framework
- CoreLocation.framework
- libz.dylib
- MobileCoreServices.framework
- QuartzCore.framework
- Security.framework
- StoreKit.framework
- SystemConfiguration.framework
Откройте файл AppDelegate.m
application: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 в вашем браузере. Выберите ваше приложение и нажмите на вкладку Браузер данных. Вы должны увидеть данные таблицы объекта, который был создан выше.
На панели инструментов вы найдете элементы управления для добавления / удаления строк и столбцов, установки разрешений, экспорта класса и даже удаления всего класса. TestObject
TestObject
Удалите его, нажав кнопку « Дополнительно» и выбрав « Удалить класс» . Также удалите код, который создает Post
Вы можете не только создавать объекты программно, как мы делали выше, но вы также можете делать это с помощью панели инструментов. Мы собираемся создать класс Post
Нажмите на кнопку New Class и назовите класс title
Оставьте тип как пользовательский . Добавьте два строковых столбца: content
title
Добавьте несколько строк данных, просто заполните поля заголовка и содержимого.
Помимо столбцов content
UITableViewController
objectId , creationAt , updatedAt и ACL . ACL расшифровывается как списки контроля доступа. Они используются для указания контроля доступа, который пользователи и / или роли имеют в определенных объектах.
Вернувшись в наше приложение, мы создадим контроллер представления для представления таблицы заметок. У Parse есть удобный класс, который является подклассом PFQueryTableViewController
JKENotesListViewController
Мы будем использовать некоторые функции, которые он предлагает, такие как «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 Indicator
Subtitle
JKENotesViewController
Настройки находятся в Инспекторе Атрибутов.
Теперь мы дадим возможность сохранять заметки. На панели навигации есть кнопка «Добавить», при нажатии на которую открывается представление «Добавить / редактировать». Чтобы приложение было простым, я буду использовать тот же вид для добавления, редактирования и просмотра заметок.
Создайте контроллер для представления. Я назвал мой UIViewController
Это подкласс JKENotesViewController
Установите класс как контроллер представления сцены Add / Edit Notes, выбрав Add / Edit view controller в раскадровке и установив пользовательский класс как JKENotesListViewController.m
Перед редактированием нового класса добавьте следующее в файл addNote
Если вы посмотрите на свою раскадровку, есть два push-сегмента, ведущих к контроллеру представления Add / Edit. Я назвал их showNote
addNote
showNote
showNote
Приведенный ниже код проверяет, какой segue был активирован, и, если это PFObject
JKENotesViewController
- (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
contentTextView
saveWasPressed
Создайте соединение действия с помощью кнопки Сохранить. Я назвал мой @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
В viewDidLoad
self.note
prepareForSegue:sender:
Если пользователь нажал на заметку, то объект post был передан этому контроллеру представления методом title
Если сообщение было передано, то мы устанавливаем заголовок TextField и контент TextView с content
saveNote
При нажатии кнопки «Сохранить» выполняется аналогичная проверка, чтобы определить, будет ли создаваться новая заметка путем вызова updateNote
saveNote
В PFObject
saveInBackgroundWithBlock:
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
Я назвал свой JKESignupViewController
JKESignupViewController.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:
PFUser
signUpInBackgroundWithBlock:
Если регистрация прошла успешно, пользователь будет переведен в табличное представление со списком заметок. Запустите и протестируйте приложение с некоторыми данными.
Теперь мы позволим пользователю выйти из системы. Добавьте подключение к действию с помощью кнопки «Выход».
В JKENotesListViewController.h
@interface JKENotesListViewController : PFQueryTableViewController
- (IBAction)logout:(id)sender;
@end
В JKENotesListViewController.m
- (IBAction)logout:(id)sender {
[PFUser logOut];
[self performSegueWithIdentifier:@"showLogin" sender:self];
}
Теперь пользователь может выйти из системы.
Мы собираемся создать отношения между постами и пользователем. В JKENotesViewController.m
newNote[@"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 . Они предоставляют разные услуги по разным ценам, и стоит посмотреть и сравнить разные продукты, чтобы решить, что лучше всего соответствует вашим потребностям.