1

I'm trying to build a single NuGet package that can be installed in Xamarin.Android, Xamarin.iOS, Xamarin.UWP and Xamarin.Forms (.NET Standard) projects. I can't use .NET Standard since I need to have a custom Activity for my Android project, custom AppDelegate for my iOS project, and a custom MainPage for my UWP project. In the initiators I want to use the ServiceCollection as DI provider.

In the docs they still mention the Portable Class Library (explicitly mentioned legacy, doesn't exist anymore in VS), or Manually Creating Packages (can't figure out what to do here), and then you also have websites mentioning the Xamarin.Forms Plugin, which also doesn't exist anymore.

I already made a solution with all 4 projects, but I can't figure out how I can create a single NuGet package for all 4 projects (all 3 target platforms).

Does anyone have an idea how we can build a multi-target NuGet package containing code for Android, iOS, and UWP, just like the Xamarin.Forms NuGet package?

I've also seen discussions like this: How does one create a project to create a Nuget package for Xamarin Forms supporting iOS, Android, and UWP?, but I'm not sure if this is still relevant, since the build.props and build.targets no longer exist in the MvvmCross repo.

Pieterjan
  • 2,738
  • 4
  • 28
  • 55

2 Answers2

1

On starting point is https://github.com/onovotny/MSBuildSdkExtras

A year ago, I made a sample (and collected some documentation and references), which might be inspiring for this subject: https://github.com/ZeProgFactory/MSBuildSdkExtrasTest

and https://github.com/ZeProgFactory/MediaPlayer is using it

And definitively, you should look at the repositories of James Montemagno's components at https://github.com/jamesmontemagno

With these references you should be able to start. But all of these had a mayor difference with your approach:

  • they are using one project (via MSBuildSdkExtras),
  • which is builded for all the platforms
  • and, finally, the binaries are assembled in one NuGet.

Perhaps you may take only this last step. Anyway, this approach is at least an option. Hope this helps …

Michael
  • 77
  • 1
  • 8
0

I've pushed a working version to https://github.com/MintPlayer/MintPlayer.MVVM

csproj-file

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

  <!-- You must have the Android 8.0 SDK installed through the Android SDK manager -->

  <PropertyGroup>
    <AssemblyName>MintPlayer.MVVM</AssemblyName>
    <RootNamespace>MintPlayer.MVVM</RootNamespace>
    <TargetFrameworks>netstandard2.0;Xamarin.iOS10;MonoAndroid80;uap10.0.16299</TargetFrameworks>
    <_WriteTelemetryProperties>false</_WriteTelemetryProperties>
    <Authors>Pieterjan De Clippel</Authors>
    <Company>MintPlayer</Company>
    <Product>MintPlayer.MVVM</Product>
    <IncludeSymbols>true</IncludeSymbols>
    <SymbolPackageFormat>snupkg</SymbolPackageFormat>
    <Description>This package allows you to implement ViewModel Navigation and Dependency Injection in a Xamarin.Forms project</Description>
    <Version>1.0.0</Version>
    <Copyright />
    <PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
    <PackageProjectUrl>https://github.com/MintPlayer/MintPlayer.MVVM</PackageProjectUrl>
    <RepositoryUrl>https://github.com/MintPlayer/MintPlayer.MVVM</RepositoryUrl>
    <PackageTags>Xamarin.Forms, Viewmodel navigation, Dependency Injection</PackageTags>
    <PackageReleaseNotes>This package is still under construction</PackageReleaseNotes>
  </PropertyGroup>

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

  <ItemGroup Condition=" $(TargetFramework.StartsWith('uap')) ">
    <Compile Include="Platforms\UAP\**\*.cs" />
    <Compile Include="Platforms\Common\**\*.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" />
    
    <AndroidResource Include="Resources\**\*.xml" SubType="Designer" Generator="MSBuild:UpdateAndroidResources" />
    <AndroidResource Include="Resources\**\*.axml" SubType="Designer" Generator="MSBuild:UpdateAndroidResources" />
  </ItemGroup>

  <ItemGroup>
    <None Remove="Platforms\Common\MintPlayerMvvmExtensions.cs" />
    <None Remove="Platforms\Common\NavigationService.cs" />
    <None Remove="Platforms\Common\Platform.cs" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.6" />
    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.6" />

    <!--<PackageReference Include="Xamarin.Forms" Version="4.5.0.495" />-->
    <PackageReference Include="Xamarin.Forms" Version="3.1.0.697729" />
  </ItemGroup>

</Project>

Directory.build.props

<Project>
  <PropertyGroup>
    <Company>MintPlayer</Company>
    <Copyright>Copyright © MintPlayer</Copyright>
    <RepositoryUrl>https://github.com/MintPlayer/MintPlayer.MVVM</RepositoryUrl>
    <Authors>Pieterjan De Clippel</Authors>
    <Owners>MintPlayer</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>

You must add the following to your .sln file

Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7004E39A-BAF2-4F2F-B505-CC3DEC393CB6}"
    ProjectSection(SolutionItems) = preProject
        Directory.build.props = Directory.build.props
        Directory.build.targets = Directory.build.targets
    EndProjectSection
EndProject
Pieterjan
  • 2,738
  • 4
  • 28
  • 55