我正在研究一个Xamarin项目的奇怪问题,我很难过......
我使用HTTPClient发出异步请求。但是,我的应用程序因未能满足Apple的IPV6要求而被应用商店拒绝。也就是说,当通过IPV6连接时,我使用HTTPClient发出的请求失败。奇怪的是,只有当应用程序在IPV4网络上启动然后切换到IPV6网络时才会失败。如果我在连接到IPV6网络时重新启动应用程序,它会成功!此外,如果我启动连接到IPV6的应用程序然后切换到IPV4网络,它也会成功。它仅在IPV4中启动然后切换到IPV6时失败。
这完全是奇怪的 - 就像HttpClient缓存了一些东西,但我们为每个请求创建了一个新的客户端。我没有使用IP地址 - 只是一个地址,而且,正如我所提到的,当应用程序开始连接到仅IPV6网络时,它可以正常工作。它只是从IPV4到IPV6的转换,这似乎导致了这个问题。
PCL中存在的代码:
var client = new HttpClient();
var urlToCall = new Uri("https://www.something.com/someapi/v1");
// Add some headers
...
response = client.GetAsync(urlToCall);
堆栈跟踪:
Trace.Message": "Error: ConnectFailure (Network is unreachable)
at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x00065] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/mcs/class/System/System.Net/HttpWebRequest.cs:946
at System.Threading.Tasks.TaskFactory`1[TResult].FromAsyncCoreLogic (IAsyncResult iar, System.Func`2 endFunction, System.Action`1 endAction, System.Threading.Tasks.Task`1 promise, Boolean requiresSynchronization) <0x10019c730 + 0x0005b> in <filename unknown>:0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003b] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:199
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:170
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:142
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[TResult].GetResult () <0x10013ccc0 + 0x0001b> in <filename unknown>:0
at System.Net.Http.HttpClientHandler+<SendAsync>c__async0.MoveNext () [0x003d6] in /Library/Frameworks/Xamarin.iOS.framework/Versions/9.6.1.9/src/mono/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs:372
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003b] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:199
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:170
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:142
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[TResult].GetResult () <0x10013ccc0 + 0x0001b> in <filename unknown>:0
at System.Net.Http.HttpClient+<SendAsyncWorker>c__async0.MoveNext () [0x000a9] in /Library/Frameworks/Xamarin.iOS.framework/Versions/9.6.1.9/src/mono/mcs/class/System.Net.Http/System.Net.Http/HttpClient.cs:274
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003b] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:199
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:170
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:142
at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () <0x10013c8c0 + 0x0001b> in <filename unknown>:0
at MyApp.RestClient.RestService`2+<SendHttpRequest>d__10[TInput,TOutput].MoveNext () [0x00259] in <filename unknown>:0
Network is unreachable
at System.Net.Sockets.Socket.Connect (System.Net.EndPoint remoteEP) [0x000bc] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/mcs/class/System/System.Net.Sockets/Socket.cs:1235
at System.Net.WebConnection.Connect (System.Net.HttpWebRequest request) [0x001c2] in /Users/builder/data/lanes/3051/5f11db87/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/mcs/class/System/System.Net/WebConnection.cs:213
以前有人见过这样的事吗?有没有人知道如何修复甚至调试这个?
答案 0 :(得分:6)
在iOS Build设置中,将HttpClient Implementation
设置为使用NSURLSession
。
默认继续是由HttpWebRequest提供支持的HttpClient,而您现在可以选择切换到使用iOS,TVOS或OS X的本机传输的实现(NSUrlSession或CFNetwork,具体取决于OS)。好处是较小的二进制文件,下载速度更快,缺点是它需要运行事件循环才能执行异步操作。
您使用的是主机名,而不是硬编码的IPv4 IP地址,这是个好消息!如果您使用的是硬编码的IPv4 IP地址,Apple将拒绝您的应用。
确保检查您的主机名是否可以解析IPv6 IP地址。 System.Net.Dns
中还有一些有用的方法可以帮助您解析IP地址,看看IPv6是否可用。
您还可以尝试使用.MapToIPv6()
扩展程序:Link to MSDN documentation。
答案 1 :(得分:1)
Awesome explanation from the ModernHttpClient author.
很棒,我们将它与所有Xamarin.Forms项目一起使用。
P.S。
我们最新的iOS应用之一也最初遭到拒绝。