Как я могу добавить элемент управления `do-try-catch` в эту функцию ниже? - PullRequest
0 голосов
/ 20 марта 2019

Как добавить do-try-catch элемент управления к этой функции ниже?

self.convertDateFromString("23282019111259318")

func convertDateFromString(stringDateTimeParameter : String)
{
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "MMddyyyyHHmmssSSS"

    guard let myDate = dateFormatter.date(from: stringDateTimeParameter) else {
    fatalError("ERROR: Date conversion failed due to mismatched format.")}

    print("myDate: \(myDate)")
}

Как вы видите выше образец. Я отправляю 23 значения в месяц, чтобы получить ошибку. И тогда приложение останавливается устройством. Мне нужно справиться с этой ситуацией. Приложение не должно останавливаться, и я должен увидеть печать (ошибка) в области видимости.

Как добавить элемент управления do-try-catch в эту функцию? Я написал это, но я не увидел строку печати в области видимости. Вот почему я спрашиваю.

Ответы [ 2 ]

3 голосов
/ 20 марта 2019

Вы не можете сделать так, чтобы форматировщики даты выдавали ошибки, но вы можете выдать ошибку из этого метода, если хотите, например,

enum DateConversionError: Error {
    case unableToParseString
}

func dateFromString(stringDateTimeParameter: String) throws -> Date {
    let formatter = DateFormatter()
    formatter.dateFormat = "MMddyyyyHHmmssSSS"
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.timeZone = TimeZone(secondsFromGMT: 0)     // or omit to use your current time zone

    guard let date = formatter.date(from: stringDateTimeParameter) else {
        throw DateConversionError.unableToParseString
    }

    return date
}

И тогда вы могли бы сделать что-то вроде:

do {
    let date = try dateFromString(stringDateTimeParameter: "23282019111259318")
    print(date)
} catch {
    print(error)
}

Как уже было сказано, мы чувствуем, что мы искажаемся, чтобы выбросить ошибки.Проще использовать дополнительные параметры:

func dateFromString(stringDateTimeParameter: String) -> Date? {
    let formatter = DateFormatter()
    formatter.dateFormat = "MMddyyyyHHmmssSSS"
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.timeZone = TimeZone(secondsFromGMT: 0)     // or omit to use your current time zone

    return formatter.date(from: stringDateTimeParameter)
}

guard let date = dateFromString(stringDateTimeParameter: "23282019111259318") else {
    print("unable to parse date")
    return
}

// use `date` here

Если вы анализируете ответы веб-API, если этот ответ находится в формате JSON, я склонен использовать JSONDecoder и указать форматер вdateDecodingStrategy:

let decoder = JSONDecoder()

let formatter = DateFormatter()
formatter.dateFormat = "MMddyyyyHHmmssSSS"
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)

decoder.dateDecodingStrategy = .formatted(formatter)

// use `decoder` to parse your JSON and it will handle conversions/errors for you

Возникает вопрос, почему вы используете формат MMddyyyyHHmmssSSS по сравнению со стандартными форматами, такими как yyyy-MM-dd'T'HH:mm:ss.SSSX, но это отдельный вопрос.


И, наконец, создание форматеров даты - дорогостоящий процесс.Вы действительно не хотите, чтобы это скрывалось внутри вашего dateFromString метода, который вы, вероятно, будете вызывать много раз.Создайте модуль форматирования один раз, а затем используйте метод dateFromString, который использует уже созданный модуль форматирования.

1 голос
/ 21 марта 2019

Если вы хотите использовать do-catch для обработки ошибок, вам нужно создать тип ошибки для вашей функции, чтобы выбросить:

struct DateConvertError : Error
{
    let description: String
}

Форматировщик не сообщает вам, почему он не смог проанализировать, хотя это не имеет большого смысла, но тогда ваша функция может быть помечена как throws:

func convertDateFromString(stringDateTimeParameter : String) throws -> Date
{
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "MMddyyyyHHmmssSSS"

    guard let date = dateFormatter.date(from: stringDateTimeParameter) else {
        throw DateConvertError(description: "Could not parse")
    }

    return date
}

А потом, когда вы это называете, вы do a try:

let date: Date
do {
    date = try convertDateFromString(stringDateTimeParameter: "23282019111259318")
} catch {
    // Handle failure
}
...