[Unity] iOS 에서 Http 다운로드 안되는 현상

Unity 2018.4.18f1 버전을 기준으로 정리합니다.

Unity에서 iOS 빌드를 했을 때 보통 AssetBundle을 다운로드 받기 위해서는 https가 아닌 http 프로토콜을 활용합니다.
무슨 보안 정보도 아닌데 https 씩이나 사용할 이유가 없으니까요.
그런데 iOS는 Secure하지 않다는 이유로 앱에서 Http 프로토콜을 사용하는 것을 기본적으로 차단하고 있습니다.
그렇기 때문에 아래와 같이 다운로드를 수행할 때 실패하게 됩니다.

var download = UnityWebRequest.Get("http://download.game.com/assetbundle");
yield return download.SendWebRequest();

if( download.isHttpError ) {
  Debug.LogError($"ResponseCode : {download.responseCode}");
}
else if( www.isNetworkError ) {
  Debug.LogError($"Error : {download.error}");
}
else {
  Debug.Log("Download Success");
}

위의 코드를 iOS에서 실행하면 "Error : Unknown Error" 라고 출력이 됩니다.

에러가 나면 왜 에러가 났는지를 메시지로 알려줘야 하는데 밑도끝도 없이 Unknown Error라고 해버리니 매우 답답하기 그지없는 상황이 됩니다.

iOS에서 Http를 사용하려면 Unity에서 빌드 후 XCode 프로젝트에서 info.plist를 오픈하여 App Transport Security Settings를 수정해 줘야 합니다.
그런데 문제는 Unity Project Setting에서 Allow downloads over HTTP 옵션을 설정해주면 info.plist에 자동으로 아래의 두가지 옵션을 추가해 줍니다.
- Allow Arbitrary Loads : YES
- Allow Arbitrary Loads in Web Content : YES

위의 옵션에 대한 자세한 내용은 아래의 링크를 참조하면 됩니다.
https://developer.apple.com/documentation/bundleresources/information_property_list/nsapptransportsecurity

문서상으로는 NSAllowArbitraryLoads를 true로 설정하면 Http 프로토콜의 사용이 허용된다고 되어 있습니다.
그런데 NSAllowArbitraryLoads는 전에 Http 프로토콜을 오픈해 버리는 것이기 때문에 여러가지 하위 옵션들을 제공하고 있습니다.
NSAllowsArbitraryLoadsForMedia, NSAllowsArbitraryLoadsInWebContent, NSAllowsLocalNetworking과 같은 옵션이 그렇습니다.

문제는 iOS 9.0과 iOS 10.0 이후의 동작이 약간 다릅니다. 이게 아주 심각한 문제와 혼란을 초래할 수 있습니다.

NSAllowArbitraryLoads는 Http 동작 전체를 허용하거나 허용하지 않는 최상위 옵션이고 기본값은 false입니다.
하지만 NSAllowArbitraryLoads와 동시에
NSAllowsArbitraryLoadsForMedia, NSAllowsArbitraryLoadsInWebContent, NSAllowsLocalNetworking 옵션이 설정되어 있을 때의 동작은 iOS 9.0 이전과 iOS 10.0 이후의 동작이 달라집니다.

iOS 9.0 이전에는 NSAllowArbitraryLoads가 true이면 하위 옵션들의 설정을 무시합니다. 최상위 옵션이니까 허용했으면 걍 다 허용되는 것이죠.

iOS 10.0 이후부터는 NSAllowArbitraryLoads가 true인데 하위 옵션들이 있으면 최상위 옵션을 무시합니다. 즉 NSAllowArbitraryLoads가 false가 되어버리는 것입니다. 왜냐하면 보안 안정성을 올리는 것이 이 옵션의 목적인데 최상위 하나만 설정하는 것으로 보안 설정을 모두 뚫어버리니까 하위 옵션이 설정되면 최상위 옵션을 내리고 좁은 범위의 허용을 우선하겠다는 목적입니다.

그런데 Unity는 Unity Ads를 활성화 한 상태로 빌드하면 NSAllowArbitraryLoads와 NSAllowArbitraryLoadsInWebContent가 동시에 설정됩니다. 그러면 NSAllowArbitraryLoads가 무시되어 버리면서 Http 프로토콜이 막혀 버립니다.
하지만 plist 옵션을 확인해 보면 NSAllowArbitraryLoads가 true로 설정되어 있으니 괜찮아야 할 것 같아서 다른 원인들을 찾아 헤메게 됩니다.

해결책은 NSAllowArbitraryLoads외의 하위 옵션들을 지워주기만 하면 됩니다.

이틀간의 삽질의 기록을 이렇게 남깁니다....

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다