如何在iOS项目中将类引用到Xamarin中的主项目

时间:2018-11-21 22:31:42

标签: c# xamarin xamarin.forms xamarin.ios auth0

我正在创建一个应用程序,其中的登录将使用auth0处理。但是由于可用的Auth0 NuGet软件包,我不得不为Android和iOS创建单独的登录页面。因此,在expr()类中,我现在必须为df <- data.frame(x = rnorm(10), y = rnorm(10), z = rnorm(10)) replace_df <- list(x = data.frame(x = 1:10), y = data.frame(y = 11:20), z = data.frame(z = 21:30)) my_func <- function(string) { return( replace_df[[string]][[string]] ) } df %>% mutate_at(vars(x, y, z), funs(my_func(expr(.)))) 引用app.xaml.cs,但是由于xamarin找不到类Login_iOS,我遇到了一个错误。我很确定这是因为我没有正确地引用它,而且似乎找不到正确引用它的方法。下面的屏幕截图应该可以帮助我解释我的情况。

App.xaml.cs Login_iOS

2 个答案:

答案 0 :(得分:1)

Shawn指出,使用IoC(控制反转)是一种方法,但请理解,IoC是从与平台无关的库项目(如.NET Standard项目)中调用特定于平台的代码的一种方法的名称。 。您必须决定要使用的IoC库,还是要使用某些跨平台框架(例如MvvmCross甚至是Xamarin.Forms Dependency Service)内置的IoC功能(这不是真正的IoC容器,而是更多的服务定位器,但确实可以使您从.NET Standard或PCL库项目中调用平台特定的代码,这最终是您想要做的事情。

也就是说,您的核心Xamarin.Forms代码还有另一个选择,那就是使用Shared Library project类型。到目前为止,.NET Standard是更常见的选项,当您遵循Xamarin.Forms(和Xamarin.Forms!= Xamarin参见下面的(1))入门文档时,建议使用该选项。创建Xamarin时可以选择此选项。表单解决方案:

enter image description here

使用核心Xamarin.Forms代码的共享库项目类型,您将可以访问平台特定项目中引用的所有内容,因此您将可以访问Xamarin.iOS和Xamarin中的所有内容。 Android项目直接。不需要IoC或依赖项服务。

关于使用共享库项目还是.NET Standard项目是否是最佳方法一直存在很多争论。每种都有优点和缺点。简而言之,使用.NET Standard项目强制您使用IoC从库项目中调用平台特定的代码,并使用自定义渲染器访问UI控件的平台特定的属性,而“共享库”项目则使您可以完全访问所有类以及特定于平台的项目可用的库,因此不需要依赖注入...但是使用共享项目时,由于您可以在同一共享项目中同时拥有Xamarin.Android特定和Xamarin.iOS特定的代码,因此您需要使用编译器指令(#if#endif),以便仅在构建iOS项目时才编译iOS特定代码,而仅在编译Android项目时才编译Android特定代码。否则可能会导致编译和/或运行时问题。这是一段简单的代码,向您展示如何使用编译器指令隔离iOS和Android特定的代码。这个简单的示例将创建一个按钮,在点击该按钮时将显示一个警报。 iOS和Android上如何显示警报不同,因此我们需要在按钮单击事件处理程序中隔离那些代码位,以便正确的代码在正确的平台上运行。

首先在“项目选项”中定义编译器符号。右键单击Android项目,然后选择 Project Options ,然后选择左侧的 Compiler 。然后在 Define Symbols 字段中,添加 ANDROID; ,例如:

enter image description here

然后对iOS项目执行相同的操作(但显然要输入 IOS ):

enter image description here

值得注意的是,这是一个与配置有关的设置,因此您需要为将用于构建项目的所有配置添加这些符号。

接下来在MainPage.xaml中创建按钮:

<Button Text="Show me an alert!" 
        HorizontalOptions="Center" 
        VerticalOptions="CenterAndExpand" 
        Clicked="Handle_Clicked" />

然后在MainPage.xaml.cs文件后面的代码中:

    void Handle_Clicked(object sender, System.EventArgs e)
    {
#if ANDROID
        Toast.MakeText(MainActivity.Context, "I'm an Android Toast!", ToastLength.Long).Show();
#endif
#if IOS
        var alert = new UIAlertView("I'm an iOS Alert!", "I'm deprecated. but using here because I do not have easy access to my view controller at this time", null, "OK", null);
        alert.Show();
#endif
    }

您还将需要在using语句周围使用编译器指令:

#if ANDROID
    using Android.Widget;
    using SharedSample.Droid;
#endif
#if IOS
    using UIKit;
#endif

因此,希望现在您可以更好地了解如何制作跨平台应用程序,以及有关共享代码和使用平台特定代码的一些挑战。综上所述,您仍然无法向Xamarin.Forms MainPage属性添加本机iOS页面(或本机Android页面),因为iOS页面不是Xamarin.Form页面(MainPage只能接受Xamarin的子类.Forms页面),但这应该向您展示如何从共享代码中调用平台特定的代码。

哦,现在我在您的屏幕快照中看到您已将Xamarin.Forms XAML页面添加到iOS项目中了?不,这不是解决您问题的方法。我会严重建议您注册Xamarin University。您不仅需要代码片段,还需要更好地理解跨平台开发,而我的简短介绍还不足以使您从我所看到的内容中获益。

您知道什么,我想这里有一个OAuth library for Xamarin Forms,所以也许您可以进行这项工作,因为它应该为您完成所有平台特定的工作。 Nuget页面:https://www.nuget.org/packages/Xamarin.Auth/ Github页面:https://github.com/xamarin/Xamarin.Auth 文件:https://docs.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/authentication/oauth

祝你好运!

(1)Xamarin是被Microsoft收购的公司。 Xamarin制作了SDK,允许使用C#和.NET框架制作适用于iOS,Mac和Android的应用程序。 Xamarin.iOS SDK用于制作iOS应用,Xamarin.Mac用于Mac应用,Xamarin.Android用于Android应用。所有人都使用Mono,它是.NET的开放源代码端口(因为.NET当时仅在Windows和其他Microsoft平台上运行...尽管现在有跨平台的.NET Core ...但是那是另一个主题)。 后来Xamarin引入了Xamarin.Forms,这是一个跨平台的UI(用户界面)库,允许使用通用代码和/或XAML创建UI。在Xamarin.Forms之前,必须在特定于平台的项目中创建每个平台的UI,即,iOS的UI将在Xamarin.iOS项目中,Android的UI将在Xamarin.Android项目中,等等。可以调用驻留在一个共享库项目中的后端代码(即Web请求,模型等),从而允许在不同平台应用程序项目之间共享大约80%的总代码。使用Xamarin.Forms,对于一个简单的应用程序,可以100%共享代码。 Xamarin.Forms仍然使用Xamarin.iOS和Xamarin.Android项目以及Windows上的UWP项目来启动UI,但是Xamarin.Forms使用渲染器将Xamarin.Forms UI控件渲染为平台特定的控件,即Xam.Forms中的Button在iOS上呈现为UIButton,在Android上呈现为Android Button。但是Xamarin.Forms仅允许您访问本机控件的核心通用属性,因此,如果您需要访问特定的本机属性或功能,则必须使用自定义渲染器(在本机平台上修改UI控件并有权访问本机控件的属性)和/或依赖项服务(以运行核心Xam.Forms库项目中的平台特定代码)。

答案 1 :(得分:0)

您的基础项目无法引用平台特定的项目。如果可以这样做,您将回到在错误平台上使用特定于平台的库的状态。

相反,您需要在基础项目中创建一个类或接口,每个平台特定项目都可以扩展该类或接口。这样,您可以在项目之间传递该基类,而无需了解正在使用的任何平台特定的库。

对于这种情况,我建议使用IoC(控制反转)模式。它为您抽象了参考处理,并简化了各种服务的注册。看一下this article,它正在解决完全相同的情况。

我希望这会有所帮助!