title: What Is Preventing My Conversion From String to Int When Decoding Using Swift 4’s Codable?
body: <p>I am getting the following JSON back from a network request:</p>
  
  <pre class="lang-swift prettyprint-override"><code>{
      "uvIndex": 5
  }
  </code></pre>
  
  <p>I use the following type to decode the string-to-data result:</p>
  
  <pre class="lang-swift prettyprint-override"><code>internal final class DataDecoder&lt;T: Decodable&gt; {
  
      internal final class func decode(_ data: Data) -&gt; T? {
          return try? JSONDecoder().decode(T.self, from: data)
      }
  
  }
  </code></pre>
  
  <p>The following is the model that the data is to be transformed into:</p>
  
  <pre class="lang-swift prettyprint-override"><code>internal struct CurrentWeatherReport: Codable {
  
      // MARK: Properties
  
      internal var uvIndex: Int?
  
      // MARK: CodingKeys
  
      private enum CodingKeys: String, CodingKey {
          case uvIndex
      }
  
      // MARK: Initializers
  
      internal init(from decoder: Decoder) throws {
          let container = try decoder.container(keyedBy: CodingKeys.self)
          if let uvIndexInteger = try container.decodeIfPresent(Int.self, forKey: .uvIndex) {
              uvIndex = uvIndexInteger
          } else if let uvIndexString = try container.decodeIfPresent(String.self, forKey: .uvIndex) {
              uvIndex = Int(uvIndexString)
          }
      }
  
  }
  </code></pre>
  
  <p>The following are the tests used to verify the decoding:</p>
  
  <pre class="lang-swift prettyprint-override"><code>internal final class CurrentWeatherReportTests: XCTestCase {
  
      internal final func test_CurrentWeather_ReturnsExpected_UVIndex_FromIntegerValue() {
          let string =
          """
          {
              "uvIndex": 5
          }
          """
          let data = DataUtility.data(from: string)
          let currentWeatherReport = DataDecoder&lt;CurrentWeatherReport&gt;.decode(data)
          XCTAssertEqual(currentWeatherReport?.uvIndex, 5)
      }
  
      internal final func test_CurrentWeather_ReturnsExpected_UVIndex_FromStringValue() {
          let string =
          """
          {
              "uvIndex": "5"
          }
          """
          let data = DataUtility.data(from: string)
          let currentWeatherReport = DataDecoder&lt;CurrentWeatherReport&gt;.decode(data)
          XCTAssertEqual(currentWeatherReport?.uvIndex, 5)
      }
  
  }
  </code></pre>
  
  <p>The difference between the tests is the value of <code>uvIndex</code> in the JSON; one is a string and the other is an integer. I am expecting an integer, but I want to handle any cases in which the value may come back as a string rather than a number since that seems to be a common practice with a few APIs that I work with. However, my second test keeps failing with the following message: <code>XCTAssertEqual failed: ("nil") is not equal to ("Optional(5)") -</code></p>
  
  <p>Am I doing something incorrectly with regard to the <code>Codable</code> protocol that is causing this failure? If not, then what is causing my second test to fail with this seemingly-simple cast?</p>
  
  <p><a href="https://i.stack.imgur.com/U1QmK.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/U1QmK.png" alt="Screenshot of failing unit test in Xcode"></a></p>