
Cloud Backend در iOS با استفاده از Parse - بخش اول
جلسه بیست و هشتم : افزودن Cloud Backend به اپ iOS با استفاده از Parse - بخش اول
در اولین جلسه ، ما یک اپ ساده دستور پخت (Recipe App) را با هم ساختیم و نحوه استفاده از table view را به شما نشان دادیم. ورژن اول Recipe App بسیار ساده هست. تمام داده های دستور پخت به صورت محلی در یک آرایه ذخیره می شوند. بعداً ، ما اپ را با گذاشتن دستور پخت ها در یک فایل property list بهبود بخشیدیم. این کار ، تمرین خوبی برای جدا کردن داده های استاتیک از کدها می باشد.
با این حال ، هر دو رویکرد فوق با یک مشکل مشابه مواجه هستند. فرض کنید ، می خواهیم Recipe App را در App Store انتشار دهیم ، و نیاز داشته باشیم که دستور پخت های بیشتر اضافه کنیم و یا تغییراتی در برخی از دستور پخت ها ایجاد کنیم ، چه کار باید انجام دهیم؟
بدیهی است که ما باید کدها (یا property list ) را به روز رسانی کنیم ، اپ را دوباره بسازیم و مجدداً آن را به App Store ارسال نماییم. کاربران اپ نیز قبل از مشاهده دستور پخت های به روز شده ، باید اپ خود را ارتقاء دهند. این روند ، یک پروسه طولانی است (به طور معمول ، بازبینی Apple و صدور تأییدیه برای اپ ، یک هفته طول می کشد).
یک راه حل معمول ، این است که داده های دستور پخت را در یک پایگاه داده قرار دهیم. هر بار که اپ راه اندازی می شود ، داده ها را از backend از طریق وب سرویس ، بازیابی می کند. از آن جایی که داده ها به صورت remote ذخیره و بارگذاری شده اند ، می توانیم داده های اپ را بدون ساخت مجدد آن ، ویرایش نماییم.
نکته منفی این روش این است که باید backend توسعه داده شود. ظاهراً ، این کار نیاز به مهارت های مختلفی و مقدار زیادی کار برای تازه کارها دارد. خوشبختانه ، چندین شرکت ، backend از پیش ساخته شده دارند که می توان اپ را به راحتی با این backend با استفاده از API یکپارچه سازی نمود. این نوع از ارائه دهندگان خدمات ، معمولاً با عنوان Backend و Service Provider (یا به صورت اختصار BaaS) شناخته می شوند. بسیاری از این شرکت ها ، خدمات خود را به صورت رایگان ارائه می دهند ، تا متقاضیان کار را با آنها شروع کنند. تنها زمانی که درخواست برای دسترسی به حجم مشخصی از خدمات اعلام شود ، پرداخت هزینه انجام می شود.
در این مجموعه آموزشی ، به شما ، نحوه ادغام Recipe app با Parse cloud را نشان خواهیم داد. ما Parse را انتخاب می کنیم ، زیرا یکی از ارائه دهندگان خدمات اصلی BaaS است و در حال حاضر ، بخشی از فیس بوک می باشد. Parse ، یک SDK با کاربری آسان را ارائه می دهد که دلیل دیگر ما برای انتخاب Parse در این آموزش می باشد.
ما آموزش را به دو بخش تقسیم می کنیم. بخش اول ، بر روی بازیابی داده از Parse backend اختصاص دارد. به روز رسانی و حذف داده ها را در جلسه بعد ، آموزش خواهیم داد.
بسیار خوب! بیایید کار را شروع کنیم.
بازبینی اپ دستور پخت
قبل از این که Parse backend را راه اندازی کنیم ، اجازه دهید ، Recipe app را مجدداً بازبینی کنیم و یک درکی از نحوه عملکرد آن به دست آوریم. Recipe app یک اپ ساده ای است که لیستی از دستور پخت ها را نمایش می دهد. کاربر ، اجازه دارد بر روی هر دستور پختی که تمایل دارد ضربه بزند و اپ جزئیات آن را نشان خواهد داد.
پس ، چه چیزی را باید تغییر دهیم؟
رابط کاربری و چیدمان table ، بدون تغییر باقی می مانند. پس از اتمام این جلسه ، کار ما ، با یک اپی که ظاهر آن درست مثل اپ قبلی است پایان می یابد. با این حال ، در داخل اپ ، دستور پخت ها را به backend می فرستیم و قابلیت “Pull to Refresh” را به table view اضافه خواهیم کرد.
برای صرفه جویی در زمان ساخت Recipe App ، می توانید فایل پروژه را از download the Xcode project from here دانلود کنید (تست شده در Xcode 4.6.3). فایل را از حالت زیپ خارج کرده و آن را extract نمایید. بقیه آموزش را به ساخت تمپلت کد ، اختصاص خواهیم داد.
ایجاد Parse Backend و setup داده ها
ابتدا ، یک حساب کاربری رایگان در Parse.com ایجاد می کنیم. در طول فرآیند sign-up ، شما اجازه ایجاد اولین اپ خود را خواهید داشت. نام اپ را “RecipeApp” قرار می دهیم.
پس از ثبت نام ، وارد داشبورد می شویم. داشبورد ، قابلیت های عمومی و متریک های کاربردی ویژه اپلیکیشن برای API ها را فراهم می کند و یک data browser برای مشاهده داده ها در backend و رابط (interface) برای مدیریت push notification ها را ارائه می کند. در این آموزش ، ما عمداً با data browser کار خواهیم کرد که برای مدیریت داده دستور پخت استفاده می شود.
قبل از این که داده های دستور پخت را در Parse backend آپلود کنیم ، باید کلاس recipe را در data browser تعریف کنیم. روی “New Class” برای ایجاد یک کلاس جدید کلیک می کنیم. نام کلاس را “Recipe” قرار داده و type آن را “Custom” انتخاب می کنیم. پس از ایجاد کلاس ، باید بتوانیم کلاس را در زیر بخش class sidebar مشاهده کنیم.
در Recipe App ، یک دستور پخت شامل خصیصه های زیر است:
- نام دستور پخت (name of recipe)
- تصویر دستور پخت (recipe image)
- مدت زمان پخت (preparation time)
- مواد اولیه (ingredients)
هر کدام از خصیصه های فوق باید به یک ستون خاص در کلاس Recipe ، در data browser نگاشت (map) شوند. پس ، کلاس Recipe را انتخاب کرده و روی “+Col” برای افزودن یک ستون کلیک می کنیم.
وقتی که درخواست ایجاد ستون را می دهیم ، نام آن را “name” و Type آن را “String” قرار می دهیم. روند مشابهی را برای سه ستون دیگر با نام و نوع های زیر ، تکرار می کنیم:
- Recipe image – نام ستون را “imageFile” و type را “File” تنظیم می کنیم. نوع PFile برای داده های باینری مانند image استفاده می شود.
- Preparation time – نام ستون را “prepTime” و نوع آن را “String” تنظیم می کنیم.
- Ingredients – نام ستون را “ingredients” و نوع ان را “Array” ، تنظیم می کنیم.
Parse SDK ، کار ترجمه انواع type از ساختار native Objective-C را به JSON هندل می نماید. برای مثال ، اگر نوع String را از Parse ، بازیابی کنیم ، در اپ به شیء NSString ، ترجمه خواهد شد.
در ادامه ، داده های دستور پخت را به کلاس Recipe اضافه خواهیم کرد. روی کلید “+Row” برای ایجاد یک ردیف جدید ، کلیک می کنیم.
هر ردیف ، یک دستور پخت واحد را نشان می دهد. نیاز داریم که تصویر دستور پخت را آپلود کرده و ستون های نام ، مدت زمان پخت و مواد اولیه را تکمیل کنیم. برای ستون های objectId ، createAt و updateAt ، مقادیر به طور خودکار ، توسط Parse تولید خواهند شد.
به عنوان مثال ، کد یک شیء Recipe ، مطابق کد زیر می باشد:
Recipe *recipe1 = [Recipe new];
recipe1.name = @"Egg Benedict";
recipe1.prepTime = @"30 min";
recipe1.imageFile = @"egg_benedict.jpg";
recipe1.ingredients = [NSArray arrayWithObjects:@"2 fresh English muffins", @"4 eggs", @"4 rashers of back bacon", @"2 egg yolks", @"1 tbsp of lemon juice", @"125 g of butter", @"salt and pepper", nil];
برای قرار دادن این دستور پخت در Parse ، ستون“name” را با “Egg Benedict” ، ستون “prepTime” را با “30 min” تکمیل کرده و برای ستون “imageFile” ، تصویر “egg_benedict.jpg” را آپلود می کنیم. برای پر کردن آرایه “ingredients” ، فرمت زیر را استفاده می کنیم:
روند فوق را برای اضافه کردن سایر دستور پخت ها ، تکرار می کنیم.
آیا وارد کردن داده ها به صورت تک به تک ، برای شما خسته کننده نیست؟ در واقع ، ما یک فایل داده ای را برای این منظور برای شما آماده کرده ایم ؛ زیرا فقط می خواهیم به شما مفاهیم data browser را انتقال دهیم. در هر صورت ، می توانید فایل داده های دستور پخت را از اینجا download the recipe data file here دانلود کرده و داده ها را به data browser مربوطه Import نمایید ( ممکن است نیاز داشته باشید که کلاس Recipe را قبل از import کردن ، رها (drop) کنید.)
راه اندازی پروژه Xcode برای Parse
با داشتن داده های پیکربندی شده فوق ، اکنون می توانیم اپ دستور پخت را برای بازیابی داده ها از backend دستکاری نماییم. اما ، در ابتدا نیاز داریم که پروژه Xcode را برای کار با Parse پیکربندی کنیم.
ابتدا ، download the Parse SDK for iOS را دانلود کنید. فایل را unzip کرده و پوشه Parse.framework را به داخل پوشه پروژه Xcode خود ، درگ نمایید.
نیاز هست که کتابخانه های زیر به داخل پروژه ، اضافه شوند.
- AudioToolbox.framework
- CFNetwork.framework
- CoreGraphics.framework
- CoreLocation.framework
- libz.1.1.3.dylib
- MobileCoreServices.framework
- QuartzCore.framework
- Security.framework
- StoreKit.framework
- SystemConfiguration.framework
در زیر بخش “RecipeBook” ، گزینه “Build Phases” را انتخاب کرده و “Link Binary with Libraries” را بسط می دهیم. روی کلید “+” کلیک کرده و کتابخانه های فوق را یک به یک ، اضافه می کنیم.
قبل از این که اپ ، بتواند به Parse متصل شود ، باید اپ را در هنگام راه اندازی در backend ، ثبت (register) نماییم. فایل “RecipeBookAppDelegate.m” را باز کرده و header زیر را در ابتدای فایل ، اضافه می کنیم:
#import <Parse/Parse.h>
در ادامه ، کد زیر را به متد didFinishLaunchingWithOptions: اضافه می کنیم:
[Parse setApplicationId:@"IRVN6Y5kIGL9RnHcFnpgbAq4QwVWWVBxN2lTTvLq"
clientKey:@"ANOHDG88JXVfHqYRbT3wLK9bXBOou94bTyWktOkU"];
Application ID و client key شما ، با موارد فوق متفاوت خواهند بود. مطمئن شوید که این مقادیر را با ID و client key خود ، جایگزین نمایید. این مقادیر را می توانید در بخش “Setting” از داشبورد Parse پیدا کنید.
پیکربندی با Parse را تکمیل نمودیم. اکنون ، اپ باید برای اتصال با Parse backend آماده شده باشد. سعی می کنیم اپ را کامپایل و اجرا نماییم. اگر همه چیز ، به درستی انجام شده باشد ، باید بتوانیم اپ را بدون خطا اجرا نماییم.
در ادامه ، نحوه بازیابی recipe objects از Parse را که اخیراً ایجاد کرده ایم ، به شما نشان خواهیم داد.
استفاده از PFQueryTableViewController برای داده های Cloud
در حال حاضر ، اپ از UITableViewController استاندارد ، برای نمایش لیستی از دستور پخت ها استفاده می نماید. این یک روش استاندارد در iOS برای نمایش دادن داده ها در جدول می باشد. با این حال ، بازیابی داده ها از backend و قرار دادن آنها در جدول ، داستان دیگری دارد. چندین موضوع است که باید مورد توجه قرار گیرند:
- از آن جایی که نیاز داریم داده ها را در backend از طریق شبکه ، لود نماییم. ، نیاز به هندل کردن خطاهای مرتبط با شبکه همانند اتصالات ناموفق ، داریم.
- اکنون می توانیم دستور پخت ها را در backend به روز رسانی نماییم. اپ باید ، یک ابزاری برای کاربر فراهم نماید تا بتواند داده ها را بدون راه اندازی مجدد اپ ، refresh نماید.
- اپ موجود ، دستور پخت ها و تصاویر را به صورت محلی ، ذخیره می کند. داده های دستور پخت ، آماده بارگذاری در جدول در هنگام راه اندازی اپ هستند. داستان کاملاً متفاوتی در هنگام بازیابی دستور پخت ها از backend وجود دارد. در طول راه اندازی اپ ، داده های دستور پخت ، ممکن است آماده نباشند. دانلود کردن داده ها و تصاویر ، زمان بر است. چگونه می توانیم مطمئن شویم که داده ها قبل از نمایش آنها در جدول آماده هستند؟
- مدت زمان لازم برای لود شدن تصاویر ، بر اساس سرعت شبکه متفاوت می باشد. آیا اپ باید صبر کند تا قبل از نمایش دستور پخت ها در جدول ، تمام تصاویر دانلود شوند؟ اگر لود شدن بیش از حد طول بکشد ، تجربه کاربری ناخوشایندی است. بهتر است ، لیستی از دستور پخت ها را هنگام لود شدن تصاویر دستور پخت از backend ، نمایش دهیم.
- اگر یک مجموعه بزرگ از دستور پخت ها را داشته باشیم ، چه کار باید انجام دهیم؟ در چنین موردی ، ما نمی خواهیم که تمام موارد را به یک باره در اپ ، لود کنیم. برای داشتن عملکرد بهتر ، ممکن است ، بخواهیم که فقط ، زیر مجموعه ای از دستور پخت ها را لود نماییم. اپ باید بتواند زیر مجموعه دیگر از دستور پخت ها را ، هنگامی که کاربر بر روی گزینه “load more” ضربه می زند نمایش دهد.
- برای داشتن بهترین عملکرد ، ممکن است کش کردن (caching) داده در اپ را مدنظر قرار دهیم. در این صورت ، پس از این که دستور پخت ها دانلود می شوند ، به صورت محلی در اپ ، کش خواهند شد.
برخی از موارد فوق ، ملاحظات طراحی می باشند که در هنگام توسعه اپ های مبتنی بر داده با backend ، باید مورد توجه قرار گیرند. خوشبختانه ، Parse SDK ، کنترلر از پیش ساخته به نام PFQueryTableViewController دارد که عملیات های background loading ، caching و error exception ( خطا استثناء) را هندل می نماید. این SDK میزان زیادی از کارها را ، برای ایجاد راه حل ها کاهش داده و در زمان صرفه جویی می نماید.
با استفاده از این کلاس ، ما می توانیم UITableView را برای نمایش داده های Parse تنظیم نماییم. این کلاس از UITableViewController ارث بری کرده است ، اما با متدهای متفاوتی همراه است که عملیات های پرس و جوها (query) ، صفحه بندی (paginate) و نمایش اشیاء از Parse backend را ساده می نمایند.
نحوه استفاده از PFQueryTableViewController
در هنگام استفاده از Parse ، هر سلول از UITableView معمولاً داده مربوط به PFObject را نمایش می دهد. اساساً ، برای نمایش داده در PFQueryTableViewController ، باید اجرای این دو متد را لغو کنیم:
- (PFTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
- (PFQuery *)queryForTable
متد اول ، بسیار شبیه به متد cellForRowAtIndexPath: است که در پروتکل UITableViewDataSource تعریف شده است. ما از این متد برای فراهم کردن یک سلول سفارشی در جدول برای PFObject چشم پوشی می نماییم. متد queryForTable: برای لود کردن اشیاء از Parse backend است.
در ادامه ، اپ Recipe را اندکی تغییر می دهیم و UITableView را با PFQueryTableViewController جایگزین می کنیم. ابتدا ، فایل RecipeBookViewController.h را باز کرده و آن را به عنوان زیر کلاسی از PFQueryTableViewController ، تغییر می دهیم. هم چنین ، نباید فراموش کنیم که هدر Parse را import کنیم.
#import <Parse/Parse.h>
@interface RecipeBookViewController : PFQueryTableViewController
اکنون ، فایل RecipeBookViewController.m را باز می کنیم. از آن جایی که دیگر از UITableView و آرایه recipe ، استفاده نخواهیم کرد ، متدهای زیر و کد مقداردهی اولیه را در متد viewDidLoad: حذف می کنیم:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [recipes count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = @"RecipeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
Recipe *recipe = [recipes objectAtIndex:indexPath.row];
UIImageView *imageView = (UIImageView*) [cell viewWithTag:100];
imageView.image = [UIImage imageNamed:recipe.imageFile];
UILabel *nameLabel = (UILabel*) [cell viewWithTag:101];
nameLabel.text = recipe.name;
UILabel *prepTimeLabel = (UILabel*) [cell viewWithTag:102];
prepTimeLabel.text = recipe.prepTime;
return cell;
}
و آنها را با این متدها ، جایگزین می کنیم:
- (id)initWithCoder:(NSCoder *)aCoder
{
self = [super initWithCoder:aCoder];
if (self) {
// The className to query on
self.parseClassName = @"Recipe";
// The key of the PFObject to display in the label of the default cell style
self.textKey = @"name";
// Whether the built-in pull-to-refresh is enabled
self.pullToRefreshEnabled = YES;
// Whether the built-in pagination is enabled
self.paginationEnabled = NO;
}
return self;
}
- (PFQuery *)queryForTable
{
PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
return query;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *simpleTableIdentifier = @"RecipeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
// Configure the cell
PFFile *thumbnail = [object objectForKey:@"imageFile"];
PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
thumbnailImageView.image = [UIImage imageNamed:@"placeholder.jpg"];
thumbnailImageView.file = thumbnail;
[thumbnailImageView loadInBackground];
UILabel *nameLabel = (UILabel*) [cell viewWithTag:101];
nameLabel.text = [object objectForKey:@"name"];
UILabel *prepTimeLabel = (UILabel*) [cell viewWithTag:102];
prepTimeLabel.text = [object objectForKey:@"prepTime"];
return cell;
}
بیایید ، تک تک کدهای فوق را بررسی کنیم. در متد initWithCoder: ، ما رفتار PFQueryTableView پیکربندی می کنیم. در اینجا ، نام کلاس Parse را برای بازیابی کردن ، تنظیم می نماییم ، قابلیت از پیش ساخته شده pull-to-refresh را فعال می نماییم ، اما قابلیت pagination را غیرفعال می کنیم.
نکته: اگر به مستند Parse مراجعه کنید ، ممکن است متوجه شوید که کدهای فوق ، کمی با کد نمونه متفاوت است. از آن جایی که ما از Storyboard برای طراحی table view استفاده می کنیم ، از متد initWithCoder: به جای متد initWithStyle: استفاده می نماییم. متد initWithStyle: ، در هنگام استفاده از Storyboard ، به عنوان آغازگر (initializer) تعیین شده است.
ما ، اشیاء را برای لود کردن در PFQueryTableView با پیاده سازی متد queryForTable: ، مشخص می کنیم. کلاس PFQuery یک روش سودمند ، برای لود کردن لیستی از اشیاء از Parse ، فراهم می کند. به سادگی می توانیم شیء PFQuery را با کلاس Parse ، برای انجام پرس و جوها ایجاد کنیم.
متد cellForRowAtIndexPath: بسیار شبیه به آن چه که قبلاً پیاده سازی کرده ایم ، است. تفاوت اصلی آنها در استفاده از PFObject است. به طور خلاصه ، ذخیره سازی داده ها در Parse در حول PFObject انجام می شود. هر PFObject حاوی جفت های key-value از داده های سازگار با JSON است. در اینجا ، یک نمونه از PFObject از کلاس Recipe آورده شده است:
"imageFile": {
"__type": "File",
"name": "2516c9e3-ebd6-4e11-89cf-972ad77a942b-mushroom_risotto.jpg",
"url": "http://files.parse.com/4838f7c6-c40b-4ed8-b750-a5a3d2948599/2516c9e3-ebd6-4e11-89cf-972ad77a942b-mushroom_risotto.jpg"
},
"ingredients": [
"1 tbsp dried porcini mushrooms",
"2 tbsp olive oil",
"1 onion, chopped",
"2 garlic cloves",
"350g/12oz arborio rice",
"1.2 litres/2 pints hot vegetable stock",
"salt and pepper",
"25g/1oz butter"
],
"name": "Mushroom Risotto",
"prepTime": "30 min"
وقتی که متد cellForRowAtIndexPath: فراخوانی می شود ، یک PFObject از کلاس recipe دریافت می کنیم. به عبارت دیگر ، یک دستور پخت واحد را دریافت می کنیم. برای به دست آوردن مقادیر از PFObject ، از متد objectForKey: استفاده می کنیم. به این متد می گوییم که مقادیر کلید “name” را بگیرد. کد زیر را استفاده می کنیم:
nameLabel.text = [object objectForKey:@"name"];
Parse ، فایل ها (مانند فایل های تصویری ، صوتی و اسناد) را در cloud در فرم PFFile ذخیره می کند. ما از PFFile برای مراجعه به تصویر دستور پخت استفاده می کنیم. Parse SDK ، یک کلاس سودمند به نام PFImageView ارائه می دهد که تصاویر راه دور ذخیره شده بر روی سرور parse را دانلود کرده و نمایش می دهد. بهتر از همه ، دانلود به صورت خودکار در پس زمینه (background) انجام می شود.
PFFile *thumbnail = [object objectForKey:@"imageFile"];
PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
thumbnailImageView.image = [UIImage imageNamed:@"placeholder.jpg"];
thumbnailImageView.file = thumbnail;
[thumbnailImageView loadInBackground];
ما به سادگی ، تصویر دستور پخت (یعنی تصویر بندانگشتی thumbnail) را برای لود شدن ، با تنظیم خصیصه “file” از PFImageView ، مشخص می کنیم. قبل از دانلود کامل تصویر دستور پخت ، image view ، فقط تصویر placeholder را نشان می دهد.
در نهایت ، به Storyboard بر می گردیم. کلاس thumbnail در Recipe Book View Controller را از UIImageView به PFImageView ، تغییر می دهیم.
اکنون ، اپ را کامپایل و اجرا می کنیم. اگر همه چیز درست انجام شده باشد ، اپ Recipe ، باید بتواند داده ها را از Parse backend بازیابی نماید.
عملیات pull برای انجام تازه سازی و صفحه بندی
PFQueryTableView همانند UITableView به نظر می رسد. اما سعی می کنیم ، جدول را پایین بیاوریم و “Pull To Refresh” را که از پیش ساخته شده است مشاهده نماییم. به data browser بر می گردیم ، و یک دستور پخت جدید را آپلود می کنیم. هنگامی که داده ها را برای تازه سازی (refresh کردن)، pull می کنیم ، ما دستور پخت جدید را مشاهده خواهیم کرد. جالب است، موافق هستید؟ اکنون می توانیم تمام داده ها در backend را مدیریت نماییم.
علاوه بر قابلیت pull برای refresh نمودن داده ها ، کنترلر PFQueryTableViewController با قابلیت دیگری به نام pagination همراه است. در بخش فوق ، ما قابلیت pagination را غیرفعال کردیم. برای فعال کردن آن ، خصیصه paginationEnabled را به YES ، تغییر می دهیم. به طور پیش فرض ، این قابلیت برای هر صفحه ، 25 شیء را نشان می دهد. می توانیم تعداد اشیاء را با تغییر خصیصه objectsPerPage عوض کنیم.
self.paginationEnabled = YES;
self.objectsPerPage = 10;
بیایید ، تعداد اشیاء موجود در هر صفحه را به 10 محدود کنیم. اپ را دوباره کامپایل و اجرا می نماییم. اپ در هنگام اجرای اول ، فقط ده دستور پخت ابتدا را لود می کند. با ضربه زدن بر روی گزینه “Load more” ، به طور خودکار 10 ردیف بعدی ، بازیابی خواهد شد. قابلیت pagination ، بخصوص در زمانی که با مجموعه بزرگی از داده ها سروکار داریم ، مفید است.
کش کردن برای دسترسی سریع و offline
اپ را می بندیم و سعی می کنیم دوباره آن را راه اندازی نماییم. هر بار که اپ باز می شود ، روی صفحه عبارت “Loading…” را مشاهده خواهیم کرد ، که نشان می دهد اپ در حال دانلود کردن دستور پخت ها از backend است. اگر دسترسی به شبکه وجود نداشته باشد ، چه اتفاقی می افتد؟ سعی می کنیم اپ را ببندیم و اتصال اینترنت iPhone یا شبیه ساز را قطع نماییم. هنگام اجرای دوباره اپ ، با پیام خطای زیر ، مواجه خواهیم شد:
یک روش بهتر ، برای هندل کردن چنین شرایطی وجود دارد. Parse query ، پشتیبانی داخلی برای کش کردن (caching) دارد ، که ذخیره سازی نتایج پرس و جوها را بر روی دیسک ، بسیار آسان تر می کند. در چنین شرایطی ، نیاز به دسترسی به شبکه وجود ندارد. اپ می تواند نتایج را از حافظه کش ، لود نماید. هم چنین ، Caching ، عملکرد اپ را بهبود می بخشد. به جای این که در هر بار اجرای اپ ، داده ها ، از Parse لود شوند ، آنها در هنگام راه اندازی اپ ، از کش بازیابی می شوند.
به طور پیش فرض ، قابلیت caching ، غیرفعال است. اما ، به راحتی می توان آن را با استفاده از یک خط کد ، فعال نمود. کد زیر را به متد queryForTable: (بعد از مقداردهی PFquery) اضافه می کنیم:
query.cachePolicy = kPFCachePolicyCacheThenNetwork
Parse Query انواع سیاست های cacheing را پشتیبانی می کند. سیاست kPFCachePolicyCacheThenNetwork فقط یکی از انواع این سیاست ها می باشد. این سیاست ، ابتدا داده ها را از casche و سپس از شبکه لود می نماید.
سعی می کنیم اپ را دوباره کامپایل و اجرا نماییم. پس از این که ، یک بار اپ را راه اندازی کردیم ، اتصال WiFi و یا سایر اتصالات شبکه را قطع می کنیم و اپ را دوباره راه اندازی می نماییم. این بار ، اپ باید بتواند دستور دستور پخت ها را نشان دهد ، حتی اگر در حالت offline باشد.
تمرین شما
بخش نمایش جزئیات دستور پخت ، در حال حاضر کار نمی کند. زمانی که یکی از دستور پخت ها را انتخاب نماییم ، صفحه خالی ، بدون اطلاعات دستور پخت ها ، نمایش داده می شود. تا کنون ، هیچ کدی را در کلاس RecipeDetailViewController تغییر نداده ایم. هم چنین ، متد prepareForSegue: هنوز به آرایه recipes مراجعه می کند ، که قبلاً آن را منسوخ کردیم. تغییرات این بخش را به عنوان تمرین ، به شما واگذار می کنیم.
موضوع جلسه بعد چیست؟
در این آموزش ، ما تمام دستور پخت ها را از اپ به Parse cloud backend ، انتقال دادیم. با استفاده از Parse SDK ، یکپارچه سازی اپ با Parse برای بازیابی داده ها از cloud ، کار بسیار راحتی است. این مقاله ، بخش اول از این سری آموزشی می باشد. در بخش دوم ، ما به شما نحوه ذخیره سازی و حذف دستور پخت ها در backend را نشان خواهیم داد.
Parse فقط یکی از ارائه دهندگان BaaS در بازار است. کار با Parse ساده و انجام یکپارچه سازی اپ با آن راحت است. با این حال ، شما می توانید از خدمات سایر ارائه دهندگان خدمات backend (مانند StackMob ، Kinvey ، Kii Cloud ، MobDB و غیره ) استفاده نمایید و مناسب ترین را برای توسعه اپ خود ، انتخاب نمایید. هزینه راه اندازی ارائه دهندگان خدمات backend ، تقریباً صفر است. این خدمات برای استفاده ، رایگان هستند و تنها زمانی لازم به پرداخت هزینه است که تعداد درخواست از یک حد مشخصی افزایش یابد.
ادامه دارد...
این فصل در یک نگاه:
…
در این دوره آموزشی ، برنامه نویسی اندروید و ios را با استفاده از زامارین خواهیم آموخت. همچنین به صورت کاملا پروژه محور ، اپلیکیشن فروشگاهی مشابه دیجی کالا را پیاده سازی خواهیم کرد. در انته…این فصل در یک نگاه:
در این فصل:-نمایش notification به کاربر زمانی که اتفاقاتی از قبیل لایک کردن پست و ... میافتد(این مبحث مبحثی مهم بوده و ج…
توضیحات کلی دوره: با سلام خوش اومدین به حرفه ای ترین دوره ی Swift ابتدای کار ممکن است سوالی برای شما پیش آید: -من نیازی به ساخت اپلیکیشن اجتماعی ندارم چرا باید این دوره را ببینم؟ ج…این فصل در یک نگاه:
…
اپل نویس حرفه ای شوید... با این پکیج کسب درآمد میلیونی کنید.... در این پکیج به نکات ریز و درشت زیادی پرداختیم که خیلی خیلی میتونه به شما کمک کنه که تبدیل به برنامه نویس حرفه ای شوید... …این فصل در یک نگاه:
فصل 16 فصل آخرمون هست و میایم توی این فصل یه سری مباحث کوچیکی که جامونده و کارهای نهایی برای انتشار برنامه توی مایکت های…
با سلام نکته:هیچ نیازی به mac و یا iphone نیست... نکته:هیچ نیازی به بلد بودن برنامه نویسی از قبل نیست... مباحثی که توی این دوره مرور میکنیم میتونه ما رو از سطح صفر برنامه نویسی ios به صد …این فصل در یک نگاه:
در این فصل آپدیت های مربوط به دوره را قرار میدهیم…
با سلام و خسته نباشد خدمت کلیک سایتی های عزیز در ادامه با توضیحات مختصری درمورد دوره ی react native با ما همراه باشید: React Native چیست؟ قطعا یکی از آرزوهای برنامه نویسان این میباشد که ب…این فصل در یک نگاه:
اموزش پرداخت درون برنامه ای بازار در یونیتی-اموزش خرید سکه در بازی-اموزش خرید مصرفی و غیر مصرفی…
توضیحات کلی مجموعه: آموزش مقدماتی تا پیشرفته یونیتی(ساخت بازی توپ چرخنده-اموزش بازی دوبعدی-اموزش بازی سه بعدی اول شخص شوتر-اموزش بازی سه بعدی رالی (ماشین سواری)) سرفصلهای دوره: نصب ی…این فصل در یک نگاه:
آموزش ساخت یک فروشگاه کوچک-آموزش کار با bottom navigation -آموزش کار با تب بار-آموزش کار با scrollview - آموزش کار با ان…
توضیحات کلی مجموعه: آموزش دوره فلاتر از پایه تا پیشرفته(این دوره به دوره متخصص فلاتر تغییر پیدا کرد) درسال های گذشته تعدا زیادی فریمورک معرفی شد که هرکدام تجربه خاص خودش رو داشت،اما فلاتر …این فصل در یک نگاه:
فصل پنجم…
توضیحات کلی مجموعه: درباره گیت: لذت پیش بردن پروژه های برنامه نویسی خود را با بهترین ورژن کنترل سیستم جهان تجربه کنید کامل ترین دوره ی آموزشی گیت و گیت هاب به همراه مثال های کاربردی گی…