Я не знаю, что будет возвращаемое значение Swift

Xcode говорит, чтобы ввести возвращаемое значение, но я понятия не имею, какое возвращаемое значение использовать.

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

    }
}

Ошибка:

https://s tackru.com/images/b9a8309d66f2e1536a136ff9fa7a738cf82f9ad2.png

2 ответа

Ваш метод был определен для возврата CLKComplicationTemplate, но ваши последние четыре case пункты просто break, ничего не возвращая.

Так как CLKComplicationDataSource все методы, которые используют этот служебный метод, принимают опциональные, вы должны просто определить этот метод, чтобы возвратить опциональный (т.е. CLKComplicationTemplate?) и пусть эти четыре случая вернутся 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
    }
}   

Ваша функция утверждает, что возвращает CLKComplicationTemplate, поэтому во всех случаях он должен сделать это, иначе он не может вернуться. Если есть какие-либо случаи, когда невозможно вернуть значение того типа, который вы обещали, единственный другой разумный вариант - завершить работу программы, чаще всего путем вызова fatalError, (Технически вы также можете заблокировать функцию, чтобы она никогда не возвращалась, например, введя бесконечный цикл, но обычно это бесполезное решение.)

Это оставляет вам много вариантов того, как двигаться вперед:

  • Если есть какое-то разумное значение по умолчанию, вы можете вернуть его для необработанных осложнений.
  • Если вы считаете передачу недопустимых сложностей в эту функцию ошибкой программирования, то разумно fatalError() в тех случаях. Например, доступ к индексу массива за его пределами является ошибкой программирования и приводит к аварийному завершению программы. Вы никогда не должны делать это в ответ на данные, поступающие извне системы (например, данные конфигурации).
  • Вы можете изменить этот метод так, чтобы он принимал перечисление, которое включает в себя только те случаи, которые вы поддерживаете, вместо того, чтобы передавать все сложности. Это делает неправильный вызов невозможным и, как правило, предпочтительнее вызова fatalError,
  • Если допустимо передать недопустимое осложнение, но оно просто ничего не должно делать, вам следует изменить метод на возвращаемый. CLKComplicationTemplate? и пусть звонящий решит, что с этим делать. Например, если вы звоните .first в пустом массиве вы получаете ноль. Это не ошибка; Там просто нет такого элемента.
  • Если передача недопустимого усложнения является ошибкой, но она должна быть обработана вызывающей стороной (например, если это происходит из данных конфигурации), вам следует изменить этот метод, чтобы добавить throws и выбросить ошибку в тех случаях. Например, попытка открыть файл, который не существует, приводит к ошибке. Это неправильно, но это не ошибка программирования. Это особенно полезно, если вы хотите, чтобы звонящий понимал, что пошло не так. Вы можете думать о throws как изменение обещанного типа возвращаемого значения на "либо возвращаемое значение, либо выданная ошибка".
Другие вопросы по тегам