[ios] Swift 2에서 사용자 정의 메시지로 오류 / 예외를 발생시키는 가장 간단한 방법은 무엇입니까?

Swift 2에서 다른 여러 언어로 익숙한 작업을하고 싶습니다. 사용자 정의 메시지로 런타임 예외를 throw하십시오. 예를 들어 (Java) :

throw new RuntimeException("A custom message here")

ErrorType 프로토콜을 준수하는 열거 형 유형을 던질 수 있다는 것을 알고 있지만 던지는 모든 유형의 오류에 대해 열거 형을 정의하고 싶지는 않습니다. 이상적으로는 위의 예를 가능한 한 유사하게 모방하고 싶습니다. ErrorType 프로토콜을 구현하는 사용자 정의 클래스를 만들려고 시도했지만 해당 프로토콜에 필요한 것이 무엇인지 파악할 수도 없습니다 ( documentation 참조 ). 아이디어?



답변

가장 간단한 방법은 정의 아마 하나의 정의를 enum단지 하나 case있다 String첨부 :

enum MyError: ErrorType {
    case runtimeError(String)
}

또는 Swift 4 기준 :

enum MyError: Error {
    case runtimeError(String)
}

사용 예는 다음과 같습니다.

func someFunction() throws {
    throw MyError.runtimeError("some message")
}
do {
    try someFunction()
} catch MyError.runtimeError(let errorMessage) {
    print(errorMessage)
}

기존 Error유형 을 사용하려는 경우 가장 일반적인 유형 NSError은이며 사용자 정의 메시지로 유형을 작성하고 던지는 팩토리 메소드를 작성할 수 있습니다.


답변

가장 간단한 방법은 다음을 String준수하는 것입니다 Error.

extension String: Error {}

그런 다음 문자열을 던질 수 있습니다.

throw "Some Error"

문자열 자체를 localizedString오류 로 만들기 위해 대신 확장 할 수 있습니다 LocalizedError.

extension String: LocalizedError {
    public var errorDescription: String? { return self }
}


답변

@ nick-keets의 솔루션은 가장 우아하지만 다음 컴파일 시간 오류로 테스트 대상에서 나에게 고장났습니다.

Redundant conformance of 'String' to protocol 'Error'

다른 접근 방식이 있습니다.

struct RuntimeError: Error {
    let message: String

    init(_ message: String) {
        self.message = message
    }

    public var localizedDescription: String {
        return message
    }
}

그리고 사용하려면 :

throw RuntimeError("Error message.")


답변

이 멋진 버전을 확인하십시오. 아이디어는 String 및 ErrorType 프로토콜을 모두 구현하고 오류의 rawValue를 사용하는 것입니다.

enum UserValidationError: String, Error {
  case noFirstNameProvided = "Please insert your first name."
  case noLastNameProvided = "Please insert your last name."
  case noAgeProvided = "Please insert your age."
  case noEmailProvided = "Please insert your email."
}

용법:

do {
  try User.define(firstName,
                  lastName: lastName,
                  age: age,
                  email: email,
                  gender: gender,
                  location: location,
                  phone: phone)
}
catch let error as User.UserValidationError {
  print(error.rawValue)
  return
}


답변

스위프트 4 :

에 따라 :

https://developer.apple.com/documentation/foundation/nserror

사용자 정의 예외를 정의하지 않으려면 다음과 같이 표준 NSError 객체를 사용할 수 있습니다.

import Foundation

do {
  throw NSError(domain: "my error description", code: 42, userInfo: ["ui1":12, "ui2":"val2"] )
}
catch let error as NSError {
  print("Caught NSError: \(error.localizedDescription), \(error.domain), \(error.code)")
  let uis = error.userInfo
  print("\tUser info:")
  for (key,value) in uis {
    print("\t\tkey=\(key), value=\(value)")
  }
}

인쇄물:

Caught NSError: The operation could not be completed, my error description, 42
    User info:
        key=ui1, value=12
        key=ui2, value=val2

이를 통해 사용자 정의 문자열과 숫자 코드 및 필요한 모든 추가 데이터가 포함 된 사전을 모든 유형으로 제공 할 수 있습니다.

NB : OS = Linux (Ubuntu 16.04 LTS)에서 테스트되었습니다.


답변

추가 확장, 열거 형, 클래스 등이없는 가장 간단한 솔루션 :

NSException(name:NSExceptionName(rawValue: "name"), reason:"reason", userInfo:nil).raise()


답변

@Nick keets 답변을 기반으로 한 더 완전한 예는 다음과 같습니다.

extension String: Error {} // Enables you to throw a string

extension String: LocalizedError { // Adds error.localizedDescription to Error instances
    public var errorDescription: String? { return self }
}

func test(color: NSColor) throws{
    if color == .red {
        throw "I don't like red"
    }else if color == .green {
        throw "I'm not into green"
    }else {
        throw "I like all other colors"
    }
}

do {
    try test(color: .green)
} catch let error where error.localizedDescription == "I don't like red"{
    Swift.print ("Error: \(error)") // "I don't like red"
}catch let error {
    Swift.print ("Other cases: Error: \(error.localizedDescription)") // I like all other colors
}

빠른 블로그에 처음 게시 : http://eon.codes/blog/2017/09/01/throwing-simple-errors/