Complication not appears in Gallery

1.6k views Asked by At

I have simple complication for launching my app from the Watch Face. It doesn't show any data, just displays an image. I followed Adding Complications to the Gallery guide but I wasn't able to add my complication to the Complications Gallery on in iPhone Watch app.

public func getLocalizableSampleTemplate(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTemplate?) -> Void) {

    guard let tempalte = buildTemplate(for: complication) else {
        fatalError("Unsuported Complication Family.")
    }
    handler(tempalte)
}

// Helper function to build template.

fileprivate func buildTemplate(for complication: CLKComplication) -> CLKComplicationTemplate? {

    let textProvider = CLKSimpleTextProvider.localizableTextProvider(withStringsFileTextKey: "Caffeine")

    switch complication.family {
    case .modularSmall:

        let icon = #imageLiteral(resourceName: "Complication/Modular")

        let complicationTemplate = CLKComplicationTemplateModularSmallSimpleImage()
        complicationTemplate.imageProvider = CLKImageProvider(onePieceImage: icon)

        return complicationTemplate

    case .circularSmall:

        let icon = #imageLiteral(resourceName: "Complication/Circular")

        let complicationTemplate = CLKComplicationTemplateCircularSmallSimpleImage()
        complicationTemplate.imageProvider = CLKImageProvider(onePieceImage: icon)
        return complicationTemplate

    case .utilitarianSmall:

        let icon = #imageLiteral(resourceName: "Complication/Utilitarian")

        let complicationTemplate = CLKComplicationTemplateUtilitarianSmallSquare()
        complicationTemplate.imageProvider = CLKImageProvider(onePieceImage: icon)
        return complicationTemplate

    case .utilitarianLarge:

        let icon = #imageLiteral(resourceName: "Complication/Utilitarian")

        let complicationTemplate = CLKComplicationTemplateUtilitarianLargeFlat()
        complicationTemplate.imageProvider = CLKImageProvider(onePieceImage: icon)
        complicationTemplate.textProvider = textProvider
        return complicationTemplate

    case .utilitarianSmallFlat:

        let icon = #imageLiteral(resourceName: "Complication/Utilitarian")

        let complicationTemplate = CLKComplicationTemplateUtilitarianSmallFlat()
        complicationTemplate.imageProvider = CLKImageProvider(onePieceImage: icon)
        complicationTemplate.textProvider = textProvider
        return complicationTemplate

    case .extraLarge:

        let icon = #imageLiteral(resourceName: "Complication/Extra Large")

        let complicationTemplate = CLKComplicationTemplateExtraLargeSimpleImage()
        complicationTemplate.imageProvider = CLKImageProvider(onePieceImage: icon)
        return complicationTemplate

    default:
        return nil
    }
}

complicationManifest.json file.

{
  "supported complication families" : {
    "3" : "B82ADE2C-045D-491D-87DD-C24148804480.json",
    "6" : "A332202A-4B7B-49E0-83FB-DB398089E4FE.json",
    "4" : "817476CB-1683-4604-A76D-2977236448AD.json",
    "2" : "50AB27ED-0FA3-41AD-A3E7-CC9C62E48D82.json",
    "0" : "DBE31877-7BB0-4671-B065-6FE00333929E.json",
    "7" : "96966B70-AB8D-4DB3-AB64-AFDF1F09EB88.json"
  },
  "client ID" : "net.borisy.ProductDisplayName.watchkitapp.watchkitextension"
}

Project Settings.

Xcode Complication Configuration

Troubleshooting.

  • Tried to Reset simulators.
  • Tried both on the real device and Simulator.
  • Complication Bundle saved as "Create folder reference" by dragging gallery.ckcomplication
  • gallery.ckcomplication located in the project at root level. Same level as .xcodeproj.

Update.

I've added more code. I've also added ckcomplication.strings to the Watch Extension Target.

Reading Apple guide again and following line got me thinking:

For example, MyBundleName.ckcomplication.

Maybe we suppose to rename generated folder name gallery with the bundle name. I've tried to do it. No luck so far.

3

There are 3 answers

1
Yurkevich On BEST ANSWER

I watch this video again and noticed ComplicationController has prefix $(PRODUCT_MODULE_NAME) in the target preferences:

My project didn't had this prefix, I quickly found out that ComplicationController methods never called. Because that was the place when we set tintColor, default complication was displayed.

I solved this by deleting my watch app and watch extension targets and creating new from scratch. The prefix appeared in Xcode and I could see my app icon in Complications Gallery running in Simulator.

9
Mike Welsh On

I'm not sure what the rest of your method looks like, but I had the same problem until I made sure I added enough information for all complication types we support. It then generated the appropriate json and image files.

Seems silly to have a blank text provider (and the template image matches the complication image set), but it seems to be a workaround.

- (void)getLocalizableSampleTemplateForComplication:(CLKComplication *)complication
                                        withHandler:(void(^)(CLKComplicationTemplate *complicationTemplate))handler {
// This method will be called once per supported complication,
// and the results will be cached
  UIImage *templateImage = [UIImage imageNamed:@"template"];
  CLKImageProvider *image =
      [CLKImageProvider imageProviderWithOnePieceImage:templateImage];
  CLKTextProvider *text = [CLKTextProvider textProviderWithFormat:@""];
  CLKComplicationTemplate *complicationTemplate;

  switch (complication.family) {
    case CLKComplicationFamilyCircularSmall: {
      CLKComplicationTemplateCircularSmallSimpleImage *small =
          [[CLKComplicationTemplateCircularSmallSimpleImage alloc] init];
      small.imageProvider = image;
      complicationTemplate = small;
      break;
    }
    case CLKComplicationFamilyExtraLarge: {
      CLKComplicationTemplateExtraLargeSimpleImage *large =
          [[CLKComplicationTemplateExtraLargeSimpleImage alloc] init];
      large.imageProvider = image;
      complicationTemplate = large;
      break;
    }
    case CLKComplicationFamilyModularLarge: {
      // Unexpected complication type.
      break;
    }
    case CLKComplicationFamilyModularSmall: {
      CLKComplicationTemplateModularSmallSimpleImage *small =
          [[CLKComplicationTemplateModularSmallSimpleImage alloc] init];
      small.imageProvider = image;
      complicationTemplate = small;
      break;
    }
    case CLKComplicationFamilyUtilitarianLarge: {
      CLKComplicationTemplateUtilitarianLargeFlat *large =
          [[CLKComplicationTemplateUtilitarianLargeFlat alloc] init];
      large.imageProvider = image;
      large.textProvider = text;
      complicationTemplate = large;
      break;
    }
    case CLKComplicationFamilyUtilitarianSmall: {
      CLKComplicationTemplateUtilitarianSmallSquare *small =
          [[CLKComplicationTemplateUtilitarianSmallSquare alloc] init];
      small.imageProvider = image;
      complicationTemplate = small;
      break;
    }
    case CLKComplicationFamilyUtilitarianSmallFlat: {
      CLKComplicationTemplateUtilitarianSmallFlat *small =
          [[CLKComplicationTemplateUtilitarianSmallFlat alloc] init];
      small.imageProvider = image;
      small.textProvider = text;
      complicationTemplate = small;
      break;
    }
  }
  handler(complicationTemplate);
}

It's hacky and I think the proper solution is to provide real image (and text) data, but this seems to work.

0
Ahmadreza On

In my case in 2020, the complications were fine on watchOS7, but my app also supported WatchOS5 but the complications were not there so I added this to watch extension info.plist file:

<key>CLKComplicationPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).ComplicationController</string>
<key>CLKComplicationSupportedFamilies</key>
<array>
    <string>CLKComplicationFamilyModularSmall</string>
    <string>CLKComplicationFamilyModularLarge</string>
    <string>CLKComplicationFamilyUtilitarianSmall</string>
    <string>CLKComplicationFamilyUtilitarianSmallFlat</string>
    <string>CLKComplicationFamilyUtilitarianLarge</string>
    <string>CLKComplicationFamilyCircularSmall</string>
    <string>CLKComplicationFamilyExtraLarge</string>
</array>