使用解析函數執行每週一次,我試圖減少網絡的通話量,以努力限制非基本數據的我的API請求進行解析。要做到這一點,我認爲最好在同一天每週只調用一次函數,並將前一週的任何差異上傳到安裝類(用於在我的情況下同步推送通知通道)的iOS解析(減少API請求)在每週的同一天
那麼如何你每週在特定的一天每週打一次功能?如果這一天已經過去了,你會怎麼樣?所以說你想在每個星期四發生一些事情,但是用戶在週四之後的星期天才打開應用程序,你應該同步數據?
使用解析函數執行每週一次,我試圖減少網絡的通話量,以努力限制非基本數據的我的API請求進行解析。要做到這一點,我認爲最好在同一天每週只調用一次函數,並將前一週的任何差異上傳到安裝類(用於在我的情況下同步推送通知通道)的iOS解析(減少API請求)在每週的同一天
那麼如何你每週在特定的一天每週打一次功能?如果這一天已經過去了,你會怎麼樣?所以說你想在每個星期四發生一些事情,但是用戶在週四之後的星期天才打開應用程序,你應該同步數據?
在實踐中,我發現一個固定的時間間隔更有意義比日曆里程碑更多的病例。有了這個NSDate邏輯,我可以讓我的模型保證它的數據至多N秒過期。
要做到這一點,我有模型單隻保留最後更新日期的軌跡:
// initialize this to [NSDate distantPast]
@property(nonatomic,strong) NSDate *lastUpdate;
該接口還提供了一個非同步更新方法,如:
- (void)updateWithCompletion:(void (^)(BOOL, NSError *))completion;
我覆蓋lastUpdate
的合成獲取/設置器以包裹餘輝:
// user defaults in this case, but there are several ways to persist a date
- (NSDate *)lastUpdate {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
return [defaults valueForKey:@"lastUpdate"];
}
- (void)setLastUpdate:(NSDate *)lastUpdate {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setValue:lastUpdate forKey:@"lastUpdate"];
[defaults synchronize];
}
最後,非同步更新不透明決定當前的數據是否足夠好,或者我們是否應該調用API parse.com ...
- (void)updateWithCompletion:(void (^)(BOOL, NSError *))completion {
NSTimeInterval sinceLastUpdate = -[self.lastUpdate timeIntervalSinceNow];
NSTimeInterval updatePeriod = [self updatePeriod];
if (sinceLastUpdate < updatePeriod) {
// our current data is new enough, so
return completion(YES, nil);
} else {
// our current data is stale, so call parse.com to update...
[...inBackgroundWithBlock:(NSArray *objects, NSError *error) {
if (!error) {
// finish the update here and persist the objects, then...
self.lastUpdate = [NSDate date];
completion(YES, nil);
} else {
completion(NO, error);
}
}];
}
}
的方法updatePeriod
回答任何NSTimeInterval
應用程序認爲是可以接受的年齡數據。通常,我會以相當高的頻率(如每日)從parse.config中獲取此信息。這樣,我可以調整模型更新的頻率,因爲我認爲適合野外客戶。
因此,我很少用NSDate
邏輯來保持客戶端「最新足夠」,甚至可以動態地決定「足夠」的部分。
編輯 - 我們仍然可以保持簡潔並將我們的模型過期設置爲日曆日。我會做如下:
- (NSDate *)lastSaturday {
NSDate *now = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *startOfWeek;
[calendar rangeOfUnit:NSCalendarUnitWeekOfMonth startDate:&startOfWeek interval:NULL forDate:now];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:-1];
return [calendar dateByAddingComponents:components toDate:startOfWeek options:0];
}
現在,而不是當間隔到期更新,更新如果最後一次更新是在上週六(或週日什麼之前,你想...通過調整setDay調整: - N)
// change the date condition in updateWithCompletion
if (self.lastUpdate == [self.lastUpdate earlierDate:[self lastSaturday]) {
// do the update
} else {
// no need to update
}
你想要做的第一件事是檢查,如果今天是你想要的數據同步的一天。因此,舉例來說,我希望每個星期四都會調用一個函數將一個對象數組同步到「頻道」列。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([self isTodayThursday]) {
} else {
}
}
- (BOOL) isTodayThursday {
NSDateFormatter *nameOfDayOfWeekFormatter = [[NSDateFormatter alloc] init];
[nameOfDayOfWeekFormatter setDateFormat:@"EEEE"];
if ([[nameOfDayOfWeekFormatter stringFromDate:[NSDate date]] isEqualToString:@"Thursday"]) {
return YES;
}
return NO;
}
很簡單,我們在這裏檢查星期幾的名稱是星期四。現在,我們要確保我們不會堆疊同步,並確保我們今天已經或未同步,如果是星期四。我們通過在NSUserDefaults
驗證針對的對象:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([self isTodayThursday]) {
if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"lastSynced"] isEqualToString:[[self dateFormatter] stringFromDate:[NSDate date]]]) {
//So we check against a custom date formatter that we want of the last sync date we performed, and if it's already been synced today, then do nothing
} else {
//if not, sync plist (or whatever we want) to channels array
[self syncPlistToParse];
}
} else {
}
}
- (NSDateFormatter *)dateFormatter {
NSDateFormatter *formatedDate = [[NSDateFormatter alloc] init];
[formatedDate setDateFormat:@"yyyyMMdd"];
NSLog(@"Today is %@", [formatedDate stringFromDate:[NSDate date]]);
return formatedDate;
}
同步的plist到PFInstallation
通道陣列
-(void)syncPlistToParse {
//First obtain whatever data you have from where ever you store it for the week. I chose to save all the data in a plist until the next sync date to reduce API calls.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
NSString *plistPath = [path stringByAppendingPathComponent:@"AlertSubscriptions.plist"];
NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:plistPath];
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation addUniqueObjectsFromArray:array forKey:@"channels"];
[currentInstallation saveInBackgroundWithBlock:^(BOOL success, NSError *error) {
if (success) {
//if successful save lastSynced date to NSUserDefaults to today
[[NSUserDefaults standardUserDefaults] setObject:[[self dateFormatter] stringFromDate:[NSDate date]] forKey:@"lastSynced"];
} else {
//It wasn't a successful save so you can do whatever you want on an unsuccessful save, but I chose to use `saveEventually` as a back-up for connectivity issues etc
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation addUniqueObjectsFromArray:array forKey:@"channels"];
[currentInstallation saveEventually];
}
}];
}
所以,如果今天是不週四我們如何確定它是否之前或之後的lastSynced日期以及我們如何確定如何設置下一個同步日期?
現在讓我們使用這些日期作爲一個例子:
June 2015
---------------------------------------------
|SUN | MON | TUES | WED | THURS | FRI | SAT |
---------------------------------------------
| | | | | 18 | 19 | 20 |
---------------------------------------------
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
---------------------------------------------
| 28 | 29 | 30 | 1 | 02 | 03 | 04 |
---------------------------------------------
因此,可以說最後的同步週四月18日,並且用戶不打開他們的應用程序,直到六月(星期五)26我們需要驗證反對。我們已經檢查過,如果今天是星期四,而且我們知道這不是星期五26日以來的情況。因此,我們需要做兩項檢查和平衡,最重要的是,我們需要檢查星期五是否在當前同步週期(第19週五)的同一周內,但在這種情況下,自本週週期以來通過因爲我們沒有打開,直到過去的下一個週期(這應該是6月25日)
if ([self isTodayThursday]) {
if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"lastSynced"] isEqualToString:[[self dateFormatter] stringFromDate:[NSDate date]]]) {
//So we check against a custom date formatter that we want of the last sync date we performed, and if it's already been synced today, then do nothing
} else {
//if not, sync plist (or whatever we want) to channels array
[self syncPlistToParse];
}
} else {
//Not Thursday. So we need to check if its within the same week of the sync cycle or passed that date
int lastSyncDate = [[self lastSyncDate] intValue];
NSLog(@"lastSyncDate int %d", lastSyncDate);
int nextSyncDate = [[self nextSyncDate] intValue];
NSLog(@"nextSyncDate int %d", nextSyncDate);
if (lastSyncDate < nextSyncDate) {
NSLog(@"next sync date is this coming thursday");
} else {
// if not before thursday (already passed Thursday), sync and save today as lastSynced
[self syncPlistToParse];
}
}
}
- (NSString *)lastSyncDate {
NSString *date = [[NSUserDefaults standardUserDefaults] objectForKey:@"lastSynced"];
return date;
}
- (NSString *)nextSyncDate {
NSCalendar *cal = [NSCalendar currentCalendar];
NSDate *lastSync = [[self dateFormatter] dateFromString:[self lastSyncDate]];
NSDateComponents *components = [cal components:(NSCalendarUnitDay) fromDate:lastSync];
[components setDay: +[self daysUntilNearestThursday]];
NSDate *nextSync = [cal dateByAddingComponents:components toDate:lastSync options:0];
return [[self dateFormatter] stringFromDate:nextSync];
}
-(int)daysUntilNearestThursday {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"EEEE"];
//Note the day of the week is including today thats why it's always +1
if ([[dateFormatter stringFromDate:[NSDate date]] isEqualToString:@"Monday"]) {
return 4;
}
if ([[dateFormatter stringFromDate:[NSDate date]] isEqualToString:@"Tuesday"]) {
return 3;
}
if ([[dateFormatter stringFromDate:[NSDate date]] isEqualToString:@"Wednesday"]) {
return 2;
}
if ([[dateFormatter stringFromDate:[NSDate date]] isEqualToString:@"Friday"]) {
return 7;
}
if ([[dateFormatter stringFromDate:[NSDate date]] isEqualToString:@"Saturday"]) {
return 6;
}
if ([[dateFormatter stringFromDate:[NSDate date]] isEqualToString:@"Sunday"]) {
return 5;
}
return 0;
}
注意不要緊的nextSyncDate是什麼,因爲我們經常檢查它是否週四,然後再採取相應的行動
這是我個人的看法,有人問我這件事,這是我想出了。我覺得自己像一個孤單簡單的解決方案,在那裏,準確因此,通過各種手段重置nextSync到最近的週四,而不是[components setDay: +[self daysUntilNearestThursday]];
,請加輸入/建議和意見,使這個爲未來的問題,求職者一個更好的機會。我認爲解析是太棒了,但同時它是一個業務,他們必須採取相應的行動,但像一切永遠爲可擴展的應用程序(2000個+用戶)API請求某些事情是怎麼樣的壞習慣,如果你打算在保持開發人員。這是我想要幫助我的朋友出門的一種選擇,它需要工作,並不是說它是唯一的方式,而是我認爲可以爲他們的項目工作的方式。請不要害羞,添加編輯或更正。
我喜歡你的答案,你的右邊,非常少的代碼,更簡潔的眼睛,但我的朋友是有這個問題是具有'updatePeriod'被設置爲一個特定的日期,而不是一個intervalPeriod儘管間隔時間在技術上是一週,但他們希望在週五專門上傳它,因爲他們在週六向特定頻道發送推送通知。所以那些在週五打開應用程序的人在下一次推送前同步他們的數據。但是對於那些只需要一般時間框架的人來說,你的答案非常棒! – soulshined
謝謝,我更新了處理週週年紀念並保持相對較低的代碼。 – danh
...並容易在眼睛上 – soulshined