如何创建一个项目来为支持iOS,Android和UWP的Xamarin Forms创建Nuget包? [英] How does one create a project to create a Nuget package for Xamarin Forms supporting iOS, Android, and UWP?

查看:73
本文介绍了如何创建一个项目来为支持iOS,Android和UWP的Xamarin Forms创建Nuget包?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

It feels like no one in the world has done this. I can't find any tutorials or help on how to create this. What I'm trying to do is create my own plugin, let's say to add notifications to Xamarin forms, that will work on Android, iOS, and UWP. Every mention of this I see mentions to create a multiplatform library but this is only available for VS for Mac and does NOT include UWP. VS2017 does not include a multiplatform library template. I want it to work like all the other xamarin plugins where you download it from nuget into all your projects and you have access to platform implementations and shared code.

我在stackoverflow上看到其他问题,但他们没有得到回答或链接已失效并且无法在VS2017上运行.

I see other questions on stackoverflow that ask this but they are not answered or have links that are dead and don't work on VS2017.

如何创建可以在多个项目之间共享的xamarin表单库?我如何将其制作成一个nuget软件包,这样它可以轻松安装,并且可以正常工作?越详细越好,因为它将帮助我看到谷歌搜索此问题但没有找到答案的每个人.

How can I create a xamarin forms library that can be shared between multiple projects? How can I make this into a nuget package so it is one brainless install and it just works? The more detailed the better as it will help everyone that I saw googling this issue and found no answer.

请记住,这不适用于像Microsoft教程所示的Visual Studio Mac,但不适用于具有最新更新的VS 2017社区版.

Remember this is NOT for visual studio Mac like the microsoft tutorials show, but for VS 2017 community edition with the latest updates.

仅在下面添加一些评论,我还尝试了James创建的这个插件,甚至无法像在他的youtube视频中那样工作:

Just to add to some of the comments below, I also tried this plugin that James created and that even doesn't work the way it does in his youtube video: https://www.youtube.com/watch?v=MSwH8NrtVCk&feature=youtu.be

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

The resulting project doesn't have any folders.

推荐答案

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

This is exactly what MvvmCross, ReactiveUI and other frameworks do. So claiming no one in the world has done this is some kind of wild imagination.

一种方法是创建一个多目标库,只需注意Visual Studio for Mac还不喜欢那些项目,并且在那里创建和开发这样的库会遇到问题.但是,如果仅在Windows Visual Studio 2017上进行开发,并且较新的版本就很好地支持此类项目.

One way to do it is to create a Multi-Target library, just be aware that Visual Studio for Mac doesn't like those projects yet and you will have issues creating and developing such a library there. However, if you only develop on Windows Visual Studio 2017 and newer supports these kind of projects very well.

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

You can start off by creating a .NET Standard library in VS, which will give you a project with a single .cs file containing Class1, go a head and remove that.

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

If you edit the .csproj file you will see a PropertyGroup in the top of the file containing a property called TargetFramework. Change that to TargetFrameworks and list all the desired frameworks you want to target:

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

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

If you want easy support in Multi-Target libraries, I advise you to switch to MSBuildSDKExtras for your project SDK, as it will handle a lot of the quirks that comes with targeting Xamarin platforms. It will add necessary properties to your project to make all of this work.

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

So first line of the .csproj file will have to look like:

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

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

Now you need to specify in which folders your platform specific code is in. What I usually do is to create a platforms folder with android, ios and uap folders and consider the rest of the code platform independent and residing in 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文件,在其中我为Packages指定属性:

To nicely create NuGet packages from this Multi-Target library, I usually add a Directory.build.props file in the root of the solution where I specify properties for the Packages:

<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文件,该文件定义了不同平台的常量:

Also I add a Directory.build.targets file defining the constants for the different platforms:

<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,则可能还需要添加:

If you are targeting Android, you will probably also need to add:

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

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

To the first ItemGroup in your .csproj file and add something like:

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

向Android ItemGroup正确更新Android资源.

To the Android ItemGroup to properly update Android Resources.

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

Adding files in Visual Studio can be a bit tricky and it will often add them in the wrong place for the first couple of files until you have something in all of the platform specific folders. But you shouldn't need anything else in the .csproj file as long as the files are placed correctly in the structure we've defined.

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

You can see examples of Multi-Target libraries here:

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

对于ReactiveUI同样如此:

And similarly for ReactiveUI:

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

到目前为止,入门并不容易,但是可以使用. 替代方法是.NET Standard库和特定于平台的库,它们添加了诱饵和切换模式.

As of now it is not super easy to get started, but is fine to work with. Alternatives to this are .NET Standard libraries and platform specific libraries adding the Bait-and-switch pattern.

这篇关于如何创建一个项目来为支持iOS,Android和UWP的Xamarin Forms创建Nuget包?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆