Distributing binding to native framework

I've developed a framework which is distributed in compiled form for iOS, and is not free, meaning the framework download requires a login. I've created a Xamarin binding to this and want to distribute the binding (but not the framework) on nuget.

So I'd like to create a binding that does not include the framework, and a nuget package that references the zip that the framework is contained in on my server and protected with HTTP authentication. Is this possible? If so, how can I create a binding without including the framework, and how can I add the dependency to nuget?

Best Answer

  • nrbrooknrbrook
    edited November 2018 Accepted Answer

    I have achieved this, but it was quite a challenge. I will at some point fully documented what I did. The basic steps are:

    • Remove the Native Reference to your framework from your binding project so it is not included in the assembly (dll)
    • Add a dependency to Xamarin.Build.Download
    • Add a build folder to your project and create a file (your assembly id).targets
    • Add the following to that file, editing as required
    <?xml version="1.0" encoding="UTF-8"?>
    <Project ToolsVersion="4.0" xmlns="hxxp://schemas.microsoft.com/developer/msbuild/2003">
        <PropertyGroup>
            <_YourVersion>3.3.2</_YourVersion>
            <_YourIncludeName>Something-$(_YourVersion)</_YourIncludeName>
        </PropertyGroup>
      <ItemGroup Condition="'$(OutputType)'!='Library' And '$(TargetFrameworkIdentifier)'=='Xamarin.iOS' And '$(YourUser)'!='' And '$(YourPass)'!=''">
        <XamarinBuildDownload Include="$(_YourIncludeName)">
          <Url>hxxp://your-website.com/download?user=$(YourUser)&amp;pass=$(YourPass)&amp;v=$(_YourVersion)</Url>
          <Kind>Zip</Kind>
        </XamarinBuildDownload>
        <NativeReference Include="$(XamarinBuildDownloadDir)$(_YourIncludeName)\Your.framework">
          <Kind>Framework</Kind>
          <ForceLoad>True</ForceLoad>
          <Frameworks>CoreBluetooth</Frameworks>
        </NativeReference>
      </ItemGroup>
      <Target Name="_WarnMissingUser"
        BeforeTargets="_UnpackLibraryResources" Condition="'$(YourUser)'==''">
        <Warning Text="Please add YourUser property to your project"/>
      </Target>
      <Target Name="_WarnMissingPass"
        BeforeTargets="_UnpackLibraryResources" Condition="'$(YourPass)'==''">
        <Warning Text="Please add YourPass property to your project"/>
      </Target>
    </Project>
    
    • Be sure to add this folder to your nupkg by adding in your nuspec
    <files>
        <!-- Include everything in \build -->
        <file src="build\**" target="build" />
    </files>
    
    • Your end users have to add this to their project, filling in the credentials
    <PropertyGroup Label="UserMacros">
        <YourUser></YourUser>
        <YourPass></YourPass>
    </PropertyGroup>
    
    • Wherever I have used 'Your' you should replace with your own relevant word e.g. product or company name.
    • Your web server must verify the credentials and provide the file. Remember that passwords are being stored and transferred in plain text here. Our passwords are not required to be very secure as they are only for downloading the framework. You may want to use a revocable token instead of user/password.

    Our framework using this is available on nuget AirTurn.iOS.AirTurnInterface (silly forum rules won't let me post a link)

Answers

  • nrbrooknrbrook Member
    edited November 2018 Accepted Answer

    I have achieved this, but it was quite a challenge. I will at some point fully documented what I did. The basic steps are:

    • Remove the Native Reference to your framework from your binding project so it is not included in the assembly (dll)
    • Add a dependency to Xamarin.Build.Download
    • Add a build folder to your project and create a file (your assembly id).targets
    • Add the following to that file, editing as required
    <?xml version="1.0" encoding="UTF-8"?>
    <Project ToolsVersion="4.0" xmlns="hxxp://schemas.microsoft.com/developer/msbuild/2003">
        <PropertyGroup>
            <_YourVersion>3.3.2</_YourVersion>
            <_YourIncludeName>Something-$(_YourVersion)</_YourIncludeName>
        </PropertyGroup>
      <ItemGroup Condition="'$(OutputType)'!='Library' And '$(TargetFrameworkIdentifier)'=='Xamarin.iOS' And '$(YourUser)'!='' And '$(YourPass)'!=''">
        <XamarinBuildDownload Include="$(_YourIncludeName)">
          <Url>hxxp://your-website.com/download?user=$(YourUser)&amp;pass=$(YourPass)&amp;v=$(_YourVersion)</Url>
          <Kind>Zip</Kind>
        </XamarinBuildDownload>
        <NativeReference Include="$(XamarinBuildDownloadDir)$(_YourIncludeName)\Your.framework">
          <Kind>Framework</Kind>
          <ForceLoad>True</ForceLoad>
          <Frameworks>CoreBluetooth</Frameworks>
        </NativeReference>
      </ItemGroup>
      <Target Name="_WarnMissingUser"
        BeforeTargets="_UnpackLibraryResources" Condition="'$(YourUser)'==''">
        <Warning Text="Please add YourUser property to your project"/>
      </Target>
      <Target Name="_WarnMissingPass"
        BeforeTargets="_UnpackLibraryResources" Condition="'$(YourPass)'==''">
        <Warning Text="Please add YourPass property to your project"/>
      </Target>
    </Project>
    
    • Be sure to add this folder to your nupkg by adding in your nuspec
    <files>
        <!-- Include everything in \build -->
        <file src="build\**" target="build" />
    </files>
    
    • Your end users have to add this to their project, filling in the credentials
    <PropertyGroup Label="UserMacros">
        <YourUser></YourUser>
        <YourPass></YourPass>
    </PropertyGroup>
    
    • Wherever I have used 'Your' you should replace with your own relevant word e.g. product or company name.
    • Your web server must verify the credentials and provide the file. Remember that passwords are being stored and transferred in plain text here. Our passwords are not required to be very secure as they are only for downloading the framework. You may want to use a revocable token instead of user/password.

    Our framework using this is available on nuget AirTurn.iOS.AirTurnInterface (silly forum rules won't let me post a link)

Sign In or Register to comment.