서버 응답에서 Double값이 NaN으로 내려올때
회사 프로젝트에서 특정 네트워크 API를 콜할 때 디코딩 오류가 나는 케이스가 있었다. 데이터 응답을 살펴보니 Double값이 들어와야 할 자리에 NaN이 떨어지고 있었다. Kotlin(서버)에서 0으로 나누기 같은 비정상 연산을 수행하면 발생할 수 있다고 한다.
Swift에서는 0으로 나누기 같은 에러 발생시 그냥 터져버리는데, 언어 특성상 사칙연산이 throwable하지 않으니 ArithmeticException과 같은 에러가 발생하지는 않는다. 그러므로 개발자가 주의해야 한다.
리포트하니 서버단에서 수정해주시긴 했는데 다른 곳에서도 발생할 수 있으므로 클라이언트에서 추가적인 대응을 하려고 했다.
JSONDecoder의 nonConformingFloatDecodingStrategy 프로퍼티에서 해당 설정을 해줄 수 있다. NaN 이외에 무한대의 경우를 같이 설정하도록 되어 있다.
import Foundation
let jsonDecoder = JSONDecoder()
jsonDecoder.nonConformingFloatDecodingStrategy = .convertFromString(
positiveInfinity: "Inf",
negativeInfinity: "-Inf",
nan: "NaN"
)
각 경우에 대해 문자열로 받는데, JSONDecoder가 서버 스펙에 종속되기 때문에 서버 개발자와 스펙을 논의해야 한다. 다른 언어 로 동작하는 서버(Python 등...)에서 호출하는 경우 언어에서 표현하는 값에 따라 달라질 수 있다. 따라서 API단위 또는 서버단위로 설정할 수 있도록 네트워킹 객체가 확장성을 가져야 한다.
NaN은 0과는 다른 취급이고, == 연산이 무조건 false를 뱉기 때문에 주의해야 한다. value.isNan을 통해 여부를 알 수 있다.
종종 Stackoverflow에서 보이던 JSON을 열어서 값을 String타입으로 디코딩해 확인하고 0으로 바꾸는 것보다는 깔끔한 것 같다.