В моем приложении для iOS установлена версия Apple Watch. И его осложнения показывают текущий день недели и день, например, «Пн 4» или «Вс 31» под значком приложения.
ComplicationController.m
- (void)getCurrentTimelineEntryForComplication:(CLKComplication *)complication withHandler:(void(^)(CLKComplicationTimelineEntry * __nullable))handler {
// Call the handler with the current timeline entry
switch (complication.family) {
case CLKComplicationFamilyExtraLarge:
{
CLKComplicationTemplateExtraLargeStackImage *template = [[CLKComplicationTemplateExtraLargeStackImage alloc]init];
template.line1ImageProvider = [CLKImageProvider imageProviderWithOnePieceImage:[UIImage imageNamed:@"Complication/Extra Large"]];
template.line1ImageProvider.tintColor = UIColorFromRGB(0xffa80b);
NSString *text = [[NSString alloc]initWithFormat:@"%@ %@",[self veryShortDayOfWeek],[self dayOfMonth]];
NSString *locale = [[NSLocale currentLocale] localeIdentifier];
if([locale isEqualToString: @"ja_JP"]){
text = [[NSString alloc]initWithFormat:@"%@%@",[self dayOfMonth],[self veryShortDayOfWeek]];
}
template.line2TextProvider = [CLKSimpleTextProvider textProviderWithText:text];
template.highlightLine2 = NO;
handler([CLKComplicationTimelineEntry entryWithDate:[NSDate date] complicationTemplate:template]);
break;
}
case CLKComplicationFamilyModularSmall:
{
CLKComplicationTemplateModularSmallStackImage *template = [[CLKComplicationTemplateModularSmallStackImage alloc]init];
template.line1ImageProvider = [CLKImageProvider imageProviderWithOnePieceImage:[UIImage imageNamed:@"MemoMa_complication_icon52x28"]];
template.line1ImageProvider.tintColor = UIColorFromRGB(0xffa80b);
NSString *text = [[NSString alloc]initWithFormat:@"%@ %@",[self veryShortDayOfWeek],[self dayOfMonth]];
NSString *locale = [[NSLocale currentLocale] localeIdentifier];
if([locale isEqualToString: @"ja_JP"]){
text = [[NSString alloc]initWithFormat:@"%@%@",[self dayOfMonth],[self veryShortDayOfWeek]];
}
template.line2TextProvider = [CLKSimpleTextProvider textProviderWithText:text];
template.highlightLine2 = NO;
handler([CLKComplicationTimelineEntry entryWithDate:[NSDate date] complicationTemplate:template]);
break;
}
case CLKComplicationFamilyUtilitarianLarge:
{
CLKComplicationTemplateUtilitarianLargeFlat *template = [[CLKComplicationTemplateUtilitarianLargeFlat alloc]init];
NSString *text = [[NSString alloc]initWithFormat:@"%@, %@",[self veryShortDayOfWeek],[self shortDate]];
NSString *locale = [[NSLocale currentLocale] localeIdentifier];
if([locale isEqualToString: @"ja_JP"]){
text = [[NSString alloc]initWithFormat:@"%@ (%@)",[self shortDate],[self veryShortDayOfWeek]];
}
template.textProvider = [CLKSimpleTextProvider textProviderWithText:text];
template.imageProvider = [CLKImageProvider imageProviderWithOnePieceImage:[UIImage imageNamed:@"MemoMa_complication_icon09"]];
template.imageProvider.tintColor = UIColorFromRGB(0xffa80b);
handler([CLKComplicationTimelineEntry entryWithDate:[NSDate date] complicationTemplate:template]);
break;
}
case CLKComplicationFamilyCircularSmall:
{
CLKComplicationTemplateCircularSmallRingImage *template = [[CLKComplicationTemplateCircularSmallRingImage alloc]init];
template.imageProvider = [CLKImageProvider imageProviderWithOnePieceImage:[UIImage imageNamed:@"MemoMa_complication_icon32x32"]];
template.imageProvider.tintColor = UIColorFromRGB(0xffa80b);
template.fillFraction = [self dayFraction];
handler([CLKComplicationTimelineEntry entryWithDate:[NSDate date] complicationTemplate:template]);
break;
}
case CLKComplicationFamilyUtilitarianSmall:
case CLKComplicationFamilyUtilitarianSmallFlat:
{
CLKComplicationTemplateUtilitarianSmallSquare *template = [[CLKComplicationTemplateUtilitarianSmallSquare alloc]init];
template.imageProvider = [CLKImageProvider imageProviderWithOnePieceImage:[UIImage imageNamed:@"MemoMa_complication_icon20"]];
template.imageProvider.tintColor = UIColorFromRGB(0xffa80b);
handler([CLKComplicationTimelineEntry entryWithDate:[NSDate date] complicationTemplate:template]);
break;
}
case CLKComplicationFamilyGraphicBezel:
{
if (@available(watchOS 5.0, *)) {
CLKComplicationTemplateGraphicCircularImage *circularTemplate = [[CLKComplicationTemplateGraphicCircularImage alloc]init];
circularTemplate.imageProvider = [CLKFullColorImageProvider providerWithFullColorImage:[UIImage imageNamed:@"Complication/Graphic Circular"]];
CLKComplicationTemplateGraphicBezelCircularText *template = [[CLKComplicationTemplateGraphicBezelCircularText alloc]init];
template.circularTemplate = circularTemplate;
template.textProvider = [CLKTextProvider textProviderWithFormat:@"%@ %@",[self singleLineDate],[self dayOfWeek]];
handler([CLKComplicationTimelineEntry entryWithDate:[NSDate date] complicationTemplate:template]);
} else {
// Fallback on earlier versions
handler(nil);
}
break;
}
case CLKComplicationFamilyGraphicCorner:
{
if (@available(watchOS 5.0, *)) {
CLKComplicationTemplateGraphicCornerTextImage *template = [[CLKComplicationTemplateGraphicCornerTextImage alloc]init];
template.imageProvider = [CLKFullColorImageProvider providerWithFullColorImage:[UIImage imageNamed:@"Complication/Graphic Corner"]];
NSString *text = [[NSString alloc]initWithFormat:@"%@ %@",[self veryShortDayOfWeek],[self dayOfMonth]];
NSString *locale = [[NSLocale currentLocale] localeIdentifier];
if([locale isEqualToString: @"ja_JP"]){
text = [[NSString alloc]initWithFormat:@"%@%@",[self dayOfMonth],[self veryShortDayOfWeek]];
}
template.textProvider = [CLKTextProvider textProviderWithFormat:@"%@",text];
handler([CLKComplicationTimelineEntry entryWithDate:[NSDate date] complicationTemplate:template]);
} else {
// Fallback on earlier versions
handler(nil);
}
break;
}
case CLKComplicationFamilyGraphicRectangular:
{
if (@available(watchOS 5.0, *)) {
CLKComplicationTemplateGraphicRectangularStandardBody *template = [[CLKComplicationTemplateGraphicRectangularStandardBody alloc]init];
template.headerTextProvider = [CLKTextProvider textProviderWithFormat:@"%@",[self singleLineDate]];
template.body1TextProvider = [CLKTextProvider textProviderWithFormat:@"%@",[self dayOfWeek]];
template.body2TextProvider = [CLKTextProvider textProviderWithFormat:@"MemoMa",nil];
handler([CLKComplicationTimelineEntry entryWithDate:[NSDate date] complicationTemplate:template]);
} else {
// Fallback on earlier versions
handler(nil);
}
break;
}
case CLKComplicationFamilyGraphicCircular:
{
if (@available(watchOS 5.0, *)) {
CLKComplicationTemplateGraphicCircularImage *template = [[CLKComplicationTemplateGraphicCircularImage alloc]init];
template.imageProvider = [CLKFullColorImageProvider providerWithFullColorImage:[UIImage imageNamed:@"Complication/Graphic Circular"]];
handler([CLKComplicationTimelineEntry entryWithDate:[NSDate date] complicationTemplate:template]);
} else {
// Fallback on earlier versions
handler(nil);
}
break;
}
default:
{
NSLog(@"default SOMETHING IS WRONG");
handler(nil);
break;
}
}
}
Похоже, что это работало до watchOS 5. После появления watchOS 6 у меня есть мнение, что сложности больше не обновляют свои тексты, таким образом показывая старую датунеделя и старая дата.
Пытаясь решить проблему, я добавил некоторые коды в приложение ExtensionDelegateDidFinishLaunching, планируя ежечасные обновления.
ExtensionDelegate.m
- (void)applicationDidFinishLaunching {
// Perform any final initialization of your application.
// Update now or schedule later complication updates
NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"suitename"];
if (![userDefaults objectForKey:@"lastComplicationUpdate"]) {
[self updateComplicationServer];
} else {
NSDate *lastComplicationUpdate = [userDefaults objectForKey:@"lastComplicationUpdate"];
NSTimeInterval secondsSinceLastComplicationUpdate = [[NSDate date] timeIntervalSinceDate:lastComplicationUpdate];
if (secondsSinceLastComplicationUpdate > (60 * 60)) {
[self updateComplicationServer];
} else {
[self scheduleHourlyUpdate];
}
}
}
- (void) scheduleHourlyUpdate {
NSCalendar *calendar = [NSCalendar currentCalendar];
[calendar setTimeZone:[NSTimeZone systemTimeZone]];
NSInteger flags = NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour;
NSDateComponents *thisHourComponent = [calendar components:flags fromDate:[NSDate date]];
NSDate *thisHour = [calendar dateFromComponents:thisHourComponent];
NSDate *nextHour = [thisHour dateByAddingTimeInterval:3601];
[[WKExtension sharedExtension] scheduleBackgroundRefreshWithPreferredDate:nextHour userInfo:nil scheduledCompletion:^(NSError * _Nullable error) {
// schedule another one in the next hour
}];
}
- (void)handleBackgroundTasks:(NSSet<WKRefreshBackgroundTask *> *)backgroundTasks {
// Sent when the system needs to launch the application in the background to process tasks. Tasks arrive in a set, so loop through and process each one.
for (WKRefreshBackgroundTask * task in backgroundTasks) {
// Check the Class of each task to decide how to process it
if ([task isKindOfClass:[WKApplicationRefreshBackgroundTask class]]) {
// Be sure to complete the background task once you’re done.
WKApplicationRefreshBackgroundTask *backgroundTask = (WKApplicationRefreshBackgroundTask*)task;
[backgroundTask setTaskCompleted];
[self updateComplicationServer];
} else if ([task isKindOfClass:[WKSnapshotRefreshBackgroundTask class]]) {
// Snapshot tasks have a unique completion call, make sure to set your expiration date
WKSnapshotRefreshBackgroundTask *snapshotTask = (WKSnapshotRefreshBackgroundTask*)task;
[snapshotTask setTaskCompletedWithDefaultStateRestored:YES estimatedSnapshotExpiration:[NSDate distantFuture] userInfo:nil];
[self updateComplicationServer];
} else if ([task isKindOfClass:[WKWatchConnectivityRefreshBackgroundTask class]]) {
// Be sure to complete the background task once you’re done.
WKWatchConnectivityRefreshBackgroundTask *backgroundTask = (WKWatchConnectivityRefreshBackgroundTask*)task;
[backgroundTask setTaskCompleted];
} else if ([task isKindOfClass:[WKURLSessionRefreshBackgroundTask class]]) {
// Be sure to complete the background task once you’re done.
WKURLSessionRefreshBackgroundTask *backgroundTask = (WKURLSessionRefreshBackgroundTask*)task;
[backgroundTask setTaskCompleted];
} else {
// make sure to complete unhandled task types
[task setTaskCompleted];
}
}
}
- (void)updateComplicationServer {
CLKComplicationServer *server = [CLKComplicationServer sharedInstance];
for (CLKComplication *complication in [server activeComplications]) {
[server reloadTimelineForComplication:complication];
}
NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"suitename"];
[userDefaults setObject:[NSDate date] forKey:@"lastComplicationUpdate"];
[userDefaults synchronize];
[self scheduleHourlyUpdate];
}
Пока чторезультат не очень хорошийОсложнения, по-видимому, обновляются только после перезагрузки устройства. Как вы рекомендуете выполнять запланированные обновления для осложнений на watchOS 6? Спасибо.