【问题标题】:How does one create a project to create a Nuget package for Xamarin Forms supporting iOS, Android, and UWP?如何创建一个项目来为支持 iOS、Android 和 UWP 的 Xamarin Forms 创建 Nuget 包?
【发布时间】:2019-08-12 23:12:58
【问题描述】:

感觉世界上没有人这样做过。我找不到任何关于如何创建它的教程或帮助。我想做的是创建我自己的插件,比如说向 Xamarin 表单添加通知,它可以在 Android、iOS 和 UWP 上运行。我看到的每一次提及都会提到创建一个多平台库,但这仅适用于 VS for Mac,不包括 UWP。 VS2017 不包含多平台库模板。我希望它像所有其他 xamarin 插件一样工作,您可以将其从 nuget 下载到您的所有项目中,并且您可以访问平台实现和共享代码。

我在 stackoverflow 上看到了其他问题,但这些问题没有得到解答,或者链接已失效且无法在 VS2017 上运行。

如何创建可以在多个项目之间共享的 xamarin 表单库?我怎样才能把它变成一个 nuget 包,所以它是一个无脑安装并且它可以工作?越详细越好,因为它会帮助我看到谷歌搜索这个问题但没有找到答案的每个人。

请记住,这不是针对微软教程展示的 Visual Studio Mac,而是针对具有最新更新的 VS 2017 社区版。

编辑 1:

只是为了添加到下面的一些 cmets,我还尝试了 James 创建的这个插件,它甚至无法像在他的 youtube 视频中那样工作:https://www.youtube.com/watch?v=MSwH8NrtVCk&feature=youtu.be

生成的项目没有任何文件夹。

【问题讨论】:

  • .net 标准不满足这些要求吗?
  • 您可以使用 bait-and-switch 库方法或直接替换库方法(查看它们在 Xamarin.Essentials 中的操作方式:github.com/xamarin/Essentials)无论哪种方式,您都在创建一个共享 (或被替换的基本库).NetStd 库项目,然后是针对您所针对的每个平台的基于平台的库。
  • 你试过this tutorial from Microsoft吗?还是this one
  • @RogerLeblanc 第一个是 2015 年的,第二个是 VS for Mac 的,不支持 UWP。这看起来像我需要的,但又是 Mac:docs.microsoft.com/en-us/xamarin/cross-platform/…。 sushihangover 我下载了一些插件,但是当我加载解决方案时它们似乎没有平台实现,所以我看不到如何为表单或平台特定代码(如 iOS 上的 NSNumber)创建自定义控件。
  • @SolidSnake4444 您的问题引用了“通知”(即非可视平台相关的实现)。如果您正在查看 Xamarin.Forms 可以使用的可视跨平台控件,请查看:docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/…(一旦您了解“渲染器”,您可以创建一个多平台|项目解决方案,其中包含每个渲染器平台。

标签: c# android ios xamarin xamarin.forms


【解决方案1】:

这正是 MvvmCross、ReactiveUI 和其他框架所做的。因此,声称世界上没有人这样做是一种疯狂的想象。

一种方法是创建一个多目标库,请注意 Visual Studio for Mac 还不喜欢这些项目,并且在那里创建和开发这样的库会遇到问题。但是,如果您只在 Windows Visual Studio 2017 及更高版本上进行开发,则可以很好地支持此类项目。

您可以从在 VS 中创建一个 .NET Standard 库开始,这将为您提供一个项目,其中包含一个包含 Class1 的 .cs 文件,然后将其删除。

如果您编辑 .csproj 文件,您将在文件顶部看到一个 PropertyGroup,其中包含一个名为 TargetFramework 的属性。将其更改为 TargetFrameworks 并列出您想要定位的所有所需框架:

<PropertyGroup
    <TargetFrameworks>netstandard2.0;Xamarin.iOS10;MonoAndroid81;uap10.0.16299</TargetFrameworks>

如果您想在多目标库中获得轻松支持,我建议您为您的项目 SDK 切换到 MSBuildSDKExtras,因为它可以处理许多针对 Xamarin 平台的怪癖。它将为您的项目添加必要的属性以完成所有这些工作。

所以 .csproj 文件的第一行必须如下所示:

<Project Sdk="MSBuild.Sdk.Extras/1.6.68">

现在您需要指定您的平台特定代码所在的文件夹。我通常做的是创建一个带有androidiosuap 文件夹的platforms 文件夹并考虑其余代码独立于平台,驻留在common

<ItemGroup>
    <Compile Remove="platforms\**\*.cs" />
    <None Include="platforms\**\*.cs" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard')) ">
    <Compile Include="platforms\common\**\*.cs" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('Xamarin.iOS')) ">
    <Compile Include="platforms\ios\**\*.cs" />
    <Compile Include="platforms\common\**\*.cs" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('MonoAndroid')) ">
    <Compile Include="platforms\android\**\*.cs" />
    <Compile Include="platforms\common\**\*.cs" />
</ItemGroup>

<ItemGroup Condition=" $(TargetFramework.StartsWith('uap')) ">
    <Compile Include="platforms\uap\**\*.cs" />
    <Compile Include="platforms\common\**\*.cs" />
</ItemGroup>

为了从这个多目标库中很好地创建 NuGet 包,我通常在解决方案的根目录中添加一个 Directory.build.props 文件,我在其中指定包的属性:

<Project>
  <PropertyGroup>
    <Company>Cheesebaron</Company>
    <Copyright>Copyright © Cheesebaron</Copyright>
    <RepositoryUrl>https://github.com/cheeesebaron/cool-stuff</RepositoryUrl>
    <Authors>Cheesebaron</Authors>
    <Owners>Cheesebaron</Owners>
    <PackageReleaseNotes />
    <PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
    <PublishRepositoryUrl>true</PublishRepositoryUrl>
    <RepositoryType>git</RepositoryType>
    <Product>$(AssemblyName) ($(TargetFramework))</Product>
    <NeutralLanguage>en</NeutralLanguage>

    <LangVersion>latest</LangVersion>
    <NoWarn>$(NoWarn);1591;1701;1702;1705;VSX1000;NU1603</NoWarn>
    <GenerateDocumentationFile Condition=" '$(Configuration)' == 'Release' ">true</GenerateDocumentationFile>
    <GeneratePackageOnBuild Condition=" '$(Configuration)' == 'Release' and '$(IsTestProject)' != 'true'">true</GeneratePackageOnBuild>

    <Platform>AnyCPU</Platform>
    <DebugType>portable</DebugType>
    <AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
    <EmbedUntrackedSources>true</EmbedUntrackedSources>

    <IsTestProject>$(MSBuildProjectName.Contains('UnitTests'))</IsTestProject>
  </PropertyGroup>
</Project>

我还添加了一个Directory.build.targets 文件,用于定义不同平台的常量:

<Project>
  <PropertyGroup Condition="$(TargetFramework.StartsWith('netstandard'))">
    <DefineConstants>$(DefineConstants);NETSTANDARD;PORTABLE</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition="$(TargetFramework.StartsWith('Xamarin.iOS'))">
    <DefineConstants>$(DefineConstants);MONO;UIKIT;COCOA;IOS</DefineConstants>
  </PropertyGroup>
  <PropertyGroup Condition="$(TargetFramework.StartsWith('MonoAndroid'))">
    <DefineConstants>$(DefineConstants);MONO;ANDROID</DefineConstants>
    <MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
    <AndroidResgenClass>Resource</AndroidResgenClass>
    <AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
  </PropertyGroup>
</Project>

如果您的目标是 Android,您可能还需要添加:

<None Include="Resources\*.cs" />
<Compile Remove="Resources\*.cs" />

到 .csproj 文件中的第一个 ItemGroup 并添加如下内容:

<AndroidResource Include="Resources\**\*.xml" SubType="Designer" Generator="MSBuild:UpdateAndroidResources" />
<AndroidResource Include="Resources\**\*.axml" SubType="Designer" Generator="MSBuild:UpdateAndroidResources" />

发送至 Android ItemGroup 以正确更新 Android 资源。

在 Visual Studio 中添加文件可能有点棘手,并且通常会将它们添加到前几个文件的错误位置,直到您在所有平台特定文件夹中都有内容。但是,只要将文件正确放置在我们定义的结构中,您就不需要 .csproj 文件中的任何其他内容。

您可以在此处查看多目标库的示例:

https://github.com/MvvmCross/MvvmCross/blob/develop/MvvmCross/MvvmCross.csproj https://github.com/MvvmCross/MvvmCross/blob/develop/Directory.build.props https://github.com/MvvmCross/MvvmCross/blob/develop/Directory.build.targets

对于 ReactiveUI 也是如此:

https://github.com/reactiveui/ReactiveUI/blob/master/src/ReactiveUI/ReactiveUI.csproj

到目前为止,它不是很容易上手,但很好用。 对此的替代方案是 .NET Standard 库和添加诱饵和切换模式的平台特定库。

【讨论】:

  • 这是否允许您在 iOS 文件夹中键入代码并为 iOS 特定类完成代码,然后移动到 Android 文件夹并获得 Android 特定代码完成?我以前听说过诱饵和切换模式这个词,你有这个例子吗?多平台目标库是您提到的三个中最好的吗?
  • 是的。你的编辑器左上角会有一个下拉框,你也可以在其中切换目标框架。
  • 我已经尝试了上述方法,但我没有看到任何特定于平台的类,例如 iOS NSNumber 或具有自动完成功能。我复制并粘贴了上面的所有内容,除了 nuget 目录构建开始。我把 ** 留在了项目组中,假设它是一个包罗万象的东西。在 VS 顶部的播放运行按钮中,如果我点击右侧的箭头,我可以选择我想要的框架。如果我切换到 iOs 然后打开 iOS 文件夹中的 cs 文件,我无法访问 Xamarin.iOS。没有自动完成功能将 xamarin 显示为选项。在依赖项下,我确实看到了 Xamarin.iOS。如何访问像 NSNumber 这样的类?
  • 让我为您准备一个小例子,因为您显然做错了,不幸的是,使用我们现在拥有的工具很容易做到。
  • 我在这个 repo 中添加了一个更完整的示例:github.com/Cheesebaron/MultiTargetSample
猜你喜欢
  • 2016-10-13
  • 1970-01-01
  • 2023-04-04
  • 2012-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-06
相关资源
最近更新 更多