ios - Xamarin Forms App 在 iOS 上以 Release模式崩溃,但在 Debug模式下工作

标签 ios xamarin.forms xamarin.ios crash release-mode

我有支持 iOS 和 Android 的 Xamarin Forms 应用程序。它在 Android 上以 Release模式正常工作。在 iOS 上,它在 Release模式下不工作,但在 Debug模式下工作。单击调用很少功能的按钮时它会崩溃。我在下面附上了错误日志。奇怪的是,它可以在 Release模式下的模拟器上运行。

错误日志:

Incident Identifier: 391C564C-028D-4084-BC4A-21ED49BB1F25
CrashReporter Key:   30B4418D-AA04-4575-97A3-97A9F491C62D
Hardware Model:      iPhone7,2
Process:         TestApp.iOS [600]
Path:            /var/containers/Bundle/Application/7F4E5392-9BEA-4578-9E23-02112B61EB96/TestApp.iOS.app/TestApp.iOS
Identifier:      uk.co.company.testapp
Version:         0.0.1 (1.0)
Code Type:       ARM-64
Parent Process:  ??? [1]

Date/Time:       2018-01-22T13:02:31Z
Launch Time:     2018-01-22T13:02:23Z
OS Version:      iPhone OS 9.3.2 (13F69)
Report Version:  104-Xamarin

Exception Type:  SIGABRT
Exception Codes: #0 at 0x180da811c
Crashed Thread:  0

Application Specific Information:
*** Terminating app due to uncaught exception 'System.ArgumentNullException', reason: 'System.ArgumentNullException: Value cannot be null.'

Xamarin Exception Stack:
Parameter name: method
  at System.Linq.Expressions.Expression.Call (System.Linq.Expressions.Expression instance, System.Reflection.MethodInfo method, System.Collections.Generic.IEnumerable`1[T] arguments) [0x00111] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src/mono/external/corefx/src/System.Linq.Expressions/src/System/Linq/Expressions/MethodCallExpression.cs:1239 
  at System.Linq.Expressions.Expression.Call (System.Linq.Expressions.Expression instance, System.Reflection.MethodInfo method, System.Linq.Expressions.Expression[] arguments) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src/mono/external/corefx/src/System.Linq.Expressions/src/System/Linq/Expressions/MethodCallExpression.cs:1046 
  at System.Linq.Expressions.Expression.Call (System.Reflection.MethodInfo method, System.Linq.Expressions.Expression[] arguments) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src/mono/external/corefx/src/System.Linq.Expressions/src/System/Linq/Expressions/MethodCallExpression.cs:1001 
  at System.Dynamic.ExpandoObject+MetaExpando.BindSetMember (System.Dynamic.SetMemberBinder binder, System.Dynamic.DynamicMetaObject value) [0x00033] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src/mono/external/corefx/src/System.Linq.Expressions/src/System/Dynamic/ExpandoObject.cs:863 
  at System.Dynamic.SetMemberBinder.Bind (System.Dynamic.DynamicMetaObject target, System.Dynamic.DynamicMetaObject[] args) [0x00035] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src/mono/external/corefx/src/System.Linq.Expressions/src/System/Dynamic/SetMemberBinder.cs:57 
  at System.Dynamic.DynamicMetaObjectBinder.Bind (System.Object[] args, System.Collections.ObjectModel.ReadOnlyCollection`1[T] parameters, System.Linq.Expressions.LabelTarget returnLabel) [0x000c6] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src/mono/external/corefx/src/System.Linq.Expressions/src/System/Dynamic/DynamicMetaObjectBinder.cs:90 
  at System.Runtime.CompilerServices.CallSiteBinder.BindCore[T] (System.Runtime.CompilerServices.CallSite`1[T] site, System.Object[] args) [0x00019] in <8bc31b0df50a4d32b3f1d5af764165ad>:0 
  at System.Runtime.CompilerServices.CallSiteOps.Bind[T] (System.Runtime.CompilerServices.CallSiteBinder binder, System.Runtime.CompilerServices.CallSite`1[T] site, System.Object[] args) [0x00000] in <8bc31b0df50a4d32b3f1d5af764165ad>:0 
  at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
  at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:305 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:152 
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Exception source) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:156 
  at System.Linq.Expressions.Interpreter.ExceptionHelpers.UnwrapAndRethrow (System.Reflection.TargetInvocationException exception) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src/mono/external/corefx/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/Utilities.cs:172 
  at System.Linq.Expressions.Interpreter.MethodInfoCallInstruction.Run (System.Linq.Expressions.Interpreter.InterpretedFrame frame) [0x00035] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src/mono/external/corefx/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/CallInstruction.cs:327 
  at System.Linq.Expressions.Interpreter.Interpreter.Run (System.Linq.Expressions.Interpreter.InterpretedFrame frame) [0x00015] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src/mono/external/corefx/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/Interpreter.cs:63 
  at System.Linq.Expressions.Interpreter.LightLambda.Run3[T0,T1,T2,TRet] (T0 arg0, T1 arg1, T2 arg2) [0x00038] in <8bc31b0df50a4d32b3f1d5af764165ad>:0 
  at TestApp.LoginPage+<onLoginClicked>d__1.MoveNext () [0x00205] in <42b3f78eef3b4fad8ca201e1a739e68b>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:152 
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.6.1.3/src/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1018 
  at UIKit.UIKitSynchronizationContext+<Post>c__AnonStorey0.<>m__0 () [0x00000] in /Users/builder/data/lanes/5665/f70a1348/source/xamarin-macios/src/UIKit/UIKitSynchronizationContext.cs:24 
  at Foundation.NSAsyncActionDispatcher.Apply () [0x00000] in /Users/builder/data/lanes/5665/f70a1348/source/xamarin-macios/src/Foundation/NSAction.cs:163 
  at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
  at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Users/builder/data/lanes/5665/f70a1348/source/xamarin-macios/src/UIKit/UIApplication.cs:79 
  at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Users/builder/data/lanes/5665/f70a1348/source/xamarin-macios/src/UIKit/UIApplication.cs:63 
  at TestApp.iOS.Application.Main (System.String[] args) [0x00000] in <52e34ea9026340479b8dc6a53c640f1e>:0

编辑: 我有一个有趣的发现。我在触摸一个按钮时调用 onLoginClicked 函数,然后调用 PostData 函数,该函数进行 REST 调用以将数据发送到服务器。每当调用 PostData 函数时,应用都会崩溃。

如果我将所有代码从 PostData 函数移动到 onLoginClicked 函数,它就可以工作了!

请在下面找到更多信息:

  • 我尝试清理并重建解决方案,但没有成功。
  • 在 PostData 方法的每一行都放置断点是没有意义的,因为应用程序仅在 Release模式下崩溃,但在 Debug模式下工作。
  • 应用程序在调用 PostData 函数的行的 onLoginClicked 方法中崩溃,即

    string responseData = await PostData(user, "auth/login");

  • 当我尝试在 PostData 函数中放置一些警报以查看结果时 它到达但发现它甚至没有击中第一个点 该方法中的行。这很奇怪。

代码:

async void onLoginClicked(object sender, System.EventArgs e)
{
    string error = "";

    if (txtEmail.Text == null || txtEmail.Text == "")
    {
        error += Constants.ERR_BLANK_EMAIL + "\r\n";
    }
    else if (txtEmail.Text.Length < 6)
    {
        error += Constants.ERR_EMAIL_LENGTH + "\r\n";
    }
    else if (!Common.isEmailValid(txtEmail.Text))
    {
        error += Constants.ERR_EMAIL_VALIDATION + "\r\n";
    }

    if (txtPassword.Text == null || txtPassword.Text == "")
    {
        error += Constants.ERR_BLANK_PASSWORD;
    }

    if (error != "")
    {
        lblError.Text = error;
        errorContainer.IsVisible = true;
        return;
    }
    else
    {
        errorContainer.IsVisible = false;
    }

    if (CrossConnectivity.Current.IsConnected)
    {
        var loadingPage = new LoadingPage();
        await Navigation.PushPopupAsync(loadingPage);

        var device_token = App.channelId;

        dynamic user = new System.Dynamic.ExpandoObject();

        user.email = txtEmail.Text;
        user.user_type = "b2b";
        user.device_token = device_token;
        user.password = txtPassword.Text;

        if (Device.RuntimePlatform == Device.iOS)
        {
            user.device_type = "ios";
        }else{
            user.device_type = "android";
        }

        string responseData = await PostData(user, "auth/login");
        dynamic responseObj = JObject.Parse(responseData);

        if (responseObj["error_code"].Value == 0)
        {
            var data = responseObj["data"];
            Constants.user = Common.GetUserObject(data.ToString());
            Helpers.Settings.Password = "" + txtPassword.Text;
            Helpers.Settings.UserId = "" + Constants.user.userId;
            Helpers.Settings.accessToken = ""+data.access_token; 
            Helpers.Settings.Email = "" + txtEmail.Text;
            var outletResp = responseObj["outlet_details"];
            var outlet_count = outletResp.Count;

            if(outlet_count>0)
            {
                Constants.outlets = new List<Outlet>();
                foreach(var store in outletResp){
                    Outlet shop = new Outlet();
                    shop.access_token = store["access_token"];
                    shop.email = store["email"];
                    shop.user_id = store["id"];
                    shop.master_id = store["master_id"];
                    shop.outlet_id = store["outlet_id"];
                    shop.post_code = store["post_code"];
                    shop.profile_pic = store["profile_pic"];
                    shop.retailer_id = store["retailer_id"];
                    shop.retailer_image = store["retailer_image"];
                    shop.store_name = store["store_name"];
                    shop.tutorial_pricing_tool = int.Parse(""+store["tutorial_pricing_tool"]);

                    Constants.outlets.Add(shop);
                }
            }

            var isPinSet = Helpers.Settings.PinSet;

            await Navigation.RemovePopupPageAsync(loadingPage);

            if (responseObj.data.pin==0 || !isPinSet){
                App.Current.MainPage = new NavigationPage(new SetPinPage(false));
            }
            else{
               App.Current.MainPage = new NavigationPage(new StoreListPage()); 
            }
        }
        else
        {
            await Navigation.RemovePopupPageAsync(loadingPage);

            if (responseObj["error_code"].Value == 1)
                lblError.Text = responseObj["error"];
            else
                lblError.Text = responseObj["message"];

            errorContainer.IsVisible = true;
        }
    }
    else
    {
        await DisplayAlert(Constants.APP_TITLE, "Please check your internet connection.", "OK");
    }
}

async public Task<string> PostData(System.Dynamic.ExpandoObject args, string actionUrl)
{
    string responseData = "";

    HttpClient client = new HttpClient();
    client.MaxResponseContentBufferSize = 256000;

    var param = Constants.JWT ? GetJWTToken(args, actionUrl) : JsonConvert.SerializeObject(args);
    var content = new StringContent(param, Encoding.UTF8, "application/json");
    client.DefaultRequestHeaders.Add("Authorization", param);

    client.DefaultRequestHeaders.Add("X-Device-Type", "android");
    client.DefaultRequestHeaders.Add("X-APP-Type", "b2b");
    client.DefaultRequestHeaders.Add("X-APP-Platform", "xamarin");

    HttpResponseMessage response = null;
    response = await client.PostAsync(Constants.BaseUrl + actionUrl, content);

    if (response.IsSuccessStatusCode)
    {
        response.EnsureSuccessStatusCode();
    }

    responseData = await response.Content.ReadAsStringAsync();

    if (Constants.JWT)
    {
        var resp = JObject.Parse(responseData);
        var respToken = resp["token"];
        var rtokenStr = respToken.ToObject<String>();
        var respPayloadStr = rtokenStr.Split('.');
        byte[] data = JWTLibrary.Converter.Base64UrlDecode(respPayloadStr[1]);
        responseData = JWTLibrary.Converter.GetStringFromBytes(data);
    }

    return responseData;
}

private string GetJWTToken(System.Dynamic.ExpandoObject args, string actionUrl)
{
    var dt = DateTime.Now;
    var ticks = dt.Ticks;
    var currentSec = ticks / TimeSpan.TicksPerSecond;
    var newEndTime = currentSec + 60;

    Object payload = new Dictionary<string, object>()
    {
        { "iat", currentSec },
        { "nbf", currentSec },
        { "exp", newEndTime },
        { "iss", actionUrl },
        { "jti", "" },
        { "bat_data", args }
    };

    var secret_key = "key";

    dynamic n_header = new System.Dynamic.ExpandoObject();
    n_header.typ = "jwt";
    n_header.alg = "HS256";

    byte[] headerBytes = JWTLibrary.Converter.GetBytesFromString(JsonConvert.SerializeObject(n_header));
    byte[] payloadBytes = JWTLibrary.Converter.GetBytesFromString(JsonConvert.SerializeObject(payload));

    var enc_header = JWTLibrary.Converter.Base64UrlEncode(headerBytes);
    var enc_payload = JWTLibrary.Converter.Base64UrlEncode(payloadBytes);

    string jwt_token = enc_header + "." + enc_payload;

    var sh_h256 = JWTLibrary.Converter.CreateToken(jwt_token, secret_key);
    var jwt_enc_signature = JWTLibrary.Converter.Base64UrlEncode(sh_h256);

    jwt_token = jwt_token + "." + jwt_enc_signature;

    return jwt_token;
}

最佳答案

恐怕问题是由 dynamic 关键字引起的。

The DynamicMethod class is a part of the set of runtime code generation features that reside with System.Reflection.Emit. However,System.Reflection.Emit API is not available in iOS.

详见Why can’t I use the “dynamic” C# keyword in Xamarin.iOS?

关于ios - Xamarin Forms App 在 iOS 上以 Release模式崩溃,但在 Debug模式下工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48383006/

相关文章:

objective-c - 在 xcodebuild 期间找不到 RestKit/RestKit.h' 文件错误

Xamarin Android 从自定义渲染器通过社交媒体分享链接/文本

c# - CancellationTokenSource.Cancel 抛出 ObjectDisposedException

licensing - Montouch 4.0.0 更新后找不到 Monotouch 激活应用程序?

ios - 用户友好的UIFont`fontNamesForFamilyName:`

ios - 从 Swift Controller 导航到另一个 ViewController 到 Objective C Controller

ios - 如何在iOS中找到整数的nsarray的四分位数

ios - iTunes Connect 提示我的 Xamarin Forms 应用程序 "Missing Purpose String in Info.plist"

c# - Xamarin iOS - Mapkit ArgumentNullException : Value cannot be null

xamarin - 升级到 Mono 4.8 后出现 DotNetZip 异常(FileNotFoundException : I18N)