Hello!
I’m trying to implement watch complications in my app based on how Stewart Lynch did in The Dad Jokes App / Building the watchOS Target video, but only a grey circle shows up when I add the complication on my Apple Watch (not simulator). So it doesn’t load the image.
Here is my code:
import ClockKit
class ComplicationController: NSObject, CLKComplicationDataSource {
private let fullColorImageName: String = "fullColorImage"
private let onePieceImageName: String = "onePieceImage"
func complicationDescriptors() async -> [CLKComplicationDescriptor] {
[
CLKComplicationDescriptor(
identifier: "com.gmail.90peter.takacs.Currency-Converter.watchkitapp",
displayName: "Converter",
supportedFamilies: [
.circularSmall,
.modularSmall,
.utilitarianSmall,
.graphicCorner,
.graphicCircular,
.graphicExtraLarge
])
]
}
func localizableSampleTemplate(for complication: CLKComplication) async -> CLKComplicationTemplate? {
guard let fullColorImage = UIImage(named: fullColorImageName),
let onePieceImage = UIImage(named: onePieceImageName)
else {
Print.error("Can't find Complication Images, localizableSampleTemplate")
return nil
}
switch complication.family {
case .circularSmall:
let template = CLKComplicationTemplateCircularSmallSimpleImage(imageProvider: .init(onePieceImage: onePieceImage))
return template
case .modularSmall:
let template = CLKComplicationTemplateModularSmallSimpleImage(imageProvider: .init(onePieceImage: onePieceImage))
return template
case .utilitarianSmall:
let template = CLKComplicationTemplateUtilitarianSmallSquare(imageProvider: .init(onePieceImage: onePieceImage))
return template
case .graphicCorner:
let template = CLKComplicationTemplateGraphicCornerCircularImage(imageProvider: .init(fullColorImage: fullColorImage))
return template
case .graphicCircular:
let template = CLKComplicationTemplateGraphicCircularImage(imageProvider: .init(fullColorImage: fullColorImage))
return template
case .graphicExtraLarge:
let template = CLKComplicationTemplateGraphicExtraLargeCircularImage(imageProvider: .init(fullColorImage: fullColorImage))
return template
default:
return nil
}
}
func currentTimelineEntry(for complication: CLKComplication) async -> CLKComplicationTimelineEntry? {
guard let fullColorImage = UIImage(named: fullColorImageName),
let onePieceImage = UIImage(named: onePieceImageName)
else {
Print.error("Can't find Complication Images, currentTimelineEntry")
return nil
}
switch complication.family {
case .circularSmall:
let template = CLKComplicationTemplateCircularSmallSimpleImage(imageProvider: .init(onePieceImage: onePieceImage))
return .init(date: Date(), complicationTemplate: template)
case .modularSmall:
let template = CLKComplicationTemplateModularSmallSimpleImage(imageProvider: .init(onePieceImage: onePieceImage))
return .init(date: Date(), complicationTemplate: template)
case .utilitarianSmall:
let template = CLKComplicationTemplateUtilitarianSmallSquare(imageProvider: .init(onePieceImage: onePieceImage))
return .init(date: Date(), complicationTemplate: template)
case .graphicCorner:
let template = CLKComplicationTemplateGraphicCornerCircularImage(imageProvider: .init(fullColorImage: fullColorImage))
return .init(date: Date(), complicationTemplate: template)
case .graphicCircular:
let template = CLKComplicationTemplateGraphicCircularImage(imageProvider: .init(fullColorImage: fullColorImage))
return .init(date: Date(), complicationTemplate: template)
case .graphicExtraLarge:
let template = CLKComplicationTemplateGraphicExtraLargeCircularImage(imageProvider: .init(fullColorImage: fullColorImage))
return .init(date: Date(), complicationTemplate: template)
default:
return nil
}
}
}
Both image in the assets catalog are set to Single Scale, onePieceImage render as Template image as in the tutorial video. The code can load the images since it doesn’t print any error (it should if the guard statement fails).
What is different than the tutorial, is that when I added watch target, xCode didn’t add ComplicationController to the project, so I added the file manually and made this setup:
Go to Project → watch app target → Build Settings
- Set “Complication Principal Class” to
$(PRODUCT_MODULE_NAME).ComplicationController
under Info.plist Values - Set “Watch Complication Name” to
Complication
under Asset Catalog Compiler - Options