如何将 class 从 iOS 项目引用到 xamarin 中的主项目

How to reference class from iOS project to the main project in xamarin

我正在创建一个应用程序,其中将使用 auth0 处理登录。但是由于可用的 Auth0 NuGet 包,我不得不为 android 和 iOS 创建单独的登录页面。所以在 app.xaml.cs class 中,我现在必须为 case Device.iOS: MainPage = new Login_iOS⁩(); 引用 Login_iOS 但是我遇到了一个错误,因为 xamarin 找不到 class Login_iOS。我很确定这是因为我没有正确引用它,而且我似乎找不到正确引用它的方法。下面的截图应该可以帮助我解释我的情况。

您的基础项目无法引用特定于平台的项目。如果你能做到这一点,你就会回到在错误的平台上使用平台特定库的困境。

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

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

希望对您有所帮助!

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

也就是说,您的核心 Xamarin.Forms 代码还有另一种选择,那就是使用 Shared Library project 类型。 .NET Standard 是迄今为止更常见的选项,当您按照 Xamarin.Forms 的入门文档(和 Xamarin.Forms != Xamarin 请参阅下面的 (1))时,您可以 select 这在您创建 Xamarin.Forms 解决方案时:

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

关于使用共享库项目还是 .NET Standard 项目是最佳选择一直存在很多争论。各有利弊。简而言之,使用 .NET Standard 项目会强制您使用 IoC 从库项目中调用特定于平台的代码,并使用自定义渲染器访问 UI 控件的特定于平台的属性,而共享库项目为您提供完全访问权限对于平台特定项目可用的所有 类 和库,不需要依赖注入...但是在使用共享项目时,因为您可以同时拥有 Xamarin.Android 特定和 Xamarin.iOS同一共享项目中的特定代码,您需要使用编译器指令(#if#endif),以便 iOS 特定代码仅在构建 iOS 项目和 Android具体代码只在编译Android项目时编译。不这样做会导致编译 and/or 运行 时间问题。下面是一段简单的代码,向您展示如何使用编译器指令来隔离 iOS 和 Android 特定代码。这个简单的示例将创建一个按钮,当点击该按钮时将显示一个警报。 iOS 和 Android 之间如何显示警报是不同的,因此我们需要在按钮单击事件处理程序中隔离这些代码,以便在正确的平台上显示正确的代码 运行。

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

然后对iOS项目做同样的事情(但明显输入IOS):

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

接下来在 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

希望您现在能更好地理解如何制作跨平台应用程序以及共享代码和使用平台特定代码的一些挑战。尽管如此,您仍然无法将原生 iOS 页面(或原生 Android 页面)添加到 Xamarin.Forms MainPage 属性,因为 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 是一家被微软收购的公司。 Xamarin 制作的 SDK 允许使用 C# 和 .NET 框架为 iOS、Mac 和 Android 制作应用程序。 Xamarin.iOS SDK is used for making iOS apps, Xamarin.Mac for Mac apps, and Xamarin.Android for Android apps. All use Mono 这是 .NET 的开源端口(因为 .NET 仅 运行 在 Windows 和当时的其他 Microsoft 平台上......尽管现在有 .NET Core 是交叉的-平台...但这是另一个话题)。 后来 Xamarin 引入了 Xamarin.Forms,这是一个跨平台 UI(用户界面)库,允许在通用代码 and/or XAML 中创建 UI。在 Xamarin.Forms 之前,每个平台的 UI 必须在特定于平台的项目中创建,即 iOS 的 UI 将在 Xamarin.iOS 项目中, UI 对于 Android 将在 Xamarin.Android 项目等中,但都可以调用驻留在一个共享库项目中的后端代码(即网络请求、模型等),允许在不同平台应用程序项目之间共享大约 80% 的总代码。使用 Xamarin.Forms,对于一个简单的应用程序,100% 的代码共享是可能的。 Xamarin.Forms 仍然使用 Xamarin.iOS 和 Xamarin.Android 项目,以及 Windows 上的 UWP 项目来启动 UI,但是 Xamarin.Forms 使用渲染器将​​ Xamarin.Forms UI 控件渲染为平台特定控件,即 Xam.Forms 中的按钮渲染为 iOS 上的 UI 按钮和 Android Android 上的按钮。但是 Xamarin.Forms 只允许您访问原生控件的核心公共属性,因此如果您需要访问特定的原生属性或功能,您必须使用自定义渲染器(修改原生上的 UI 控件平台并可以访问本机控件的属性)and/or 依赖服务(来自核心 Xam.Forms 库项目的 运行 平台特定代码)。