-1

Xcode is saying to input a return value but I have no clue as to what return value to use.

func getCurrentTimelineEntry(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimelineEntry?) -> Void) {
    let entry = CLKComplicationTimelineEntry(date: Date(), complicationTemplate: constructTemplate(for: complication))
    handler(entry)
}

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

private func constructTemplate(for complication: CLKComplication) -> CLKComplicationTemplate {
    switch complication.family {
        case .modularSmall:
            let template = CLKComplicationTemplateModularSmallSimpleText()
            let provider = CLKSimpleTextProvider(text: GioTexts.TitleLeft.rawValue)
            template.textProvider = provider

            return template
        case .modularLarge:
            let t = CLKComplicationTemplateModularLargeStandardBody()
            t.headerImageProvider = CLKImageProvider(onePieceImage: UIImage(named: "Complication/Circular")!)
            t.headerTextProvider = CLKSimpleTextProvider(text: GioTexts.TitleLeft.rawValue)
            t.body1TextProvider = CLKSimpleTextProvider(text: GioTexts.SubtitleLeft.rawValue)
            t.body2TextProvider = CLKSimpleTextProvider(text: GioTexts.SubtitleRight.rawValue)
            return t
        case .extraLarge:
            let t = CLKComplicationTemplateExtraLargeColumnsText()
            t.row1Column2TextProvider = CLKSimpleTextProvider(text: GioTexts.TitleLeft.rawValue)
            t.row1Column1TextProvider = CLKSimpleTextProvider(text: "")
            t.row2Column2TextProvider = CLKSimpleTextProvider(text: GioTexts.SubtitleLeft.rawValue)
            t.row2Column1TextProvider = CLKSimpleTextProvider(text: GioTexts.SubtitleRight.rawValue)
            t.column2Alignment = .trailing
            return t
        case .utilitarianSmallFlat, .utilitarianSmall:
            let t = CLKComplicationTemplateUtilitarianSmallFlat()
            t.imageProvider = CLKImageProvider(onePieceImage: UIImage(named: "Complication/Circular")!)
            t.textProvider = CLKSimpleTextProvider(text: GioTexts.TitleLeft.rawValue)
            return t
        case .utilitarianLarge:
            let t = CLKComplicationTemplateUtilitarianLargeFlat()
            t.textProvider = CLKSimpleTextProvider(text: GioTexts.TitleLeft.rawValue)
            return t
        case .circularSmall:
            let t = CLKComplicationTemplateCircularSmallStackImage()
            t.line1ImageProvider = CLKImageProvider(onePieceImage: UIImage(named: "Complication/Circular")!)
            t.line2TextProvider = CLKSimpleTextProvider(text: GioTexts.TitleLeft.rawValue)
            return t
        case .graphicCorner: break
        case .graphicBezel: break
        case .graphicCircular: break
        case .graphicRectangular: break

    }
}

Error:

screenshot

halfer
  • 19,824
  • 17
  • 99
  • 186
Maxbo5020
  • 25
  • 2

2 Answers2

2

Your method has been defined to return a CLKComplicationTemplate, but your last four case clauses simply break, not returning anything.

Since the CLKComplicationDataSource methods that use this utility method all accept optionals, you should just define this method to return an optional (i.e., CLKComplicationTemplate?) and have these four cases return nil:

func getCurrentTimelineEntry(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimelineEntry?) -> Void) {
    let entry = constructTemplate(for: complication).flatMap {
        CLKComplicationTimelineEntry(date: Date(), complicationTemplate: $0)
    }
    handler(entry)
}

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

private func constructTemplate(for complication: CLKComplication) -> CLKComplicationTemplate? {
    switch complication.family {
        case .modularSmall:
            ...
        case .modularLarge:
            ...
        case .extraLarge:
            ...
        case .utilitarianSmallFlat, .utilitarianSmall:
            ...
        case .utilitarianLarge:
            ...
        case .circularSmall:
            ...
        case default:
            return nil
    }
}   
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • 1
    `case .graphicCorner, .graphicBezel, .graphicCircular, .graphicRectangular` => `default` – matt Feb 12 '19 at 15:34
  • 1
    @matt There's good arguments for either approach IMO. In this particular case, I'd prefer Rob's approach because it would force me to reconsider the code if new cases were added. That's also a reason to favor default, so it's really just style here IMO. – Rob Napier Feb 12 '19 at 15:38
  • @matt - Yeah, I’d probably use `default` (esp in light of the forthcoming contemplation of unknown cases in Swift 5). I was just trying to do the most modest change to address OP’s question. But `default` is prudent here, and I’ve adjusted accordingly. – Rob Feb 12 '19 at 16:11
0

Your function claims to return a CLKComplicationTemplate, so in all cases it must do so or else it cannot return. If there are any cases where it's impossible to return a value of the type you've promised, your only other reasonable option is to crash the program, most commonly by calling fatalError. (Technically you can also block the function so it never returns, for example by entering an infinite loop, but this generally isn't a useful solution.)

That leaves you many options of how to move forward:

  • If there is some default value that is sensible, you can return that for unhandled complications.
  • If you consider passing invalid complications to this function to be a programming error, then it is reasonable to call fatalError() in those cases. For example, accessing an array index outside its bounds is a programming error and crashes the program this way. You should never do this in response to data that comes from outside the system (such as configuration data).
  • You can change this method to accept an enum that just includes the cases you support, rather than passing the whole complication. This makes calling it incorrectly impossible, and is generally preferable to calling fatalError.
  • If passing an invalid complication is acceptable, but should just do nothing, then you should change the method to return CLKComplicationTemplate? and let the caller decide what to do about it. For example, if you call .first on an empty array, you get nil. It's not an error; there's just no such element.
  • If passing an invalid complication is an error, but one that should be handled by the caller (if it comes from configuration data for example), then you should change this method to add throws and throw an error in those cases. For example, trying to open a file that does not exist throws an error. It's wrong, but it's not a programming mistake. This is particularly useful if you want the caller to understand what went wrong. You can think of throws as changing the promised return type in to "either a returned value or a thrown error."
Rob Napier
  • 286,113
  • 34
  • 456
  • 610