Target different platforms on Windows

This commit is contained in:
Martijn van Dijk 2018-03-23 15:29:56 +01:00
Родитель 0a0f4b8beb
Коммит 0f1ee074d6
9 изменённых файлов: 338 добавлений и 159 удалений

Просмотреть файл

@ -17,6 +17,7 @@
<TransformFile Include="Transforms\Metadata.xml" />
<Compile Include="Additions\LottieComposition.cs" />
<Compile Include="Additions\LottieAnimationView.cs" />
<None Include="readme.txt" pack="true" PackagePath="." />
</ItemGroup>
<Import Project="$(MSBuildSDKExtrasTargets)" Condition="Exists('$(MSBuildSDKExtrasTargets)')" />

17
Lottie.Android/readme.txt Normal file
Просмотреть файл

@ -0,0 +1,17 @@
---------------------------------
Lottie
---------------------------------
Lottie is a mobile library for Android and iOS that parses Adobe After Effects animations exported as json with Bodymovin and renders them natively on mobile!
Using Lottie on Xamarin.Android:
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/animation_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:lottie_fileName="hello-world.json"
app:lottie_loop="true"
app:lottie_autoPlay="true" />
Star on Github if this project helps you: https://github.com/martijn00/LottieXamarin

Просмотреть файл

@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;uap10.0.16299;Xamarin.iOS10;Xamarin.Mac20;MonoAndroid80</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">netstandard2.0;Xamarin.iOS10;MonoAndroid80;uap10.0.16299</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netstandard2.0;Xamarin.iOS10;Xamarin.Mac20;MonoAndroid80</TargetFrameworks>
<AssemblyName>Lottie.Forms</AssemblyName>
<RootNamespace>Lottie.Forms</RootNamespace>
<Description>Render After Effects animations natively on Android, iOS, MacOS, TVOs and UWP</Description>

Просмотреть файл

@ -2,4 +2,21 @@
Lottie
---------------------------------
Lottie is a mobile library for Android and iOS that parses Adobe After Effects animations exported as json with Bodymovin and renders them natively on mobile!
Using Lottie on Xamarin.Forms:
<forms:AnimationView
x:Name="animationView"
Grid.Row="1"
Animation="LottieLogo1.json"
Loop="false"
AutoPlay="false"
OnFinish="Handle_OnFinish"
PlaybackStartedCommand="{Binding PlayingCommand}"
PlaybackFinishedCommand="{Binding FinishedCommand}"
ClickedCommand="{Binding ClickedCommand}"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand" />
Star on Github if this project helps you: https://github.com/martijn00/LottieXamarin

Просмотреть файл

@ -18,6 +18,7 @@
<Compile Include="libLottie.linkwith.cs">
<DependentUpon>libLottie.a</DependentUpon>
</Compile>
<None Include="readme.txt" pack="true" PackagePath="." />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('Xamarin.iOS')) ">

18
Lottie.iOS/readme.txt Normal file
Просмотреть файл

@ -0,0 +1,18 @@
---------------------------------
Lottie
---------------------------------
Lottie is a mobile library for Android and iOS that parses Adobe After Effects animations exported as json with Bodymovin and renders them natively on mobile!
Using Lottie on Xamarin.iOS:
LOTAnimationView animation = LOTAnimationView.AnimationNamed("LottieLogo1");
this.View.AddSubview(animation);
animation.PlayWithCompletion((animationFinished) => {
// Do Something
});
//You can also use the awaitable version
var animationFinished = await animation.PlayAsync();
Star on Github if this project helps you: https://github.com/martijn00/LottieXamarin

Просмотреть файл

@ -353,7 +353,7 @@ If you would like to add more JSON files and screenshot tests, feel free to do s
## Issues or feature requests?
File github issues for anything that is unexpectedly broken. If an After Effects file is not working, please attach it to your issue. Debugging without the original file is much more difficult.
# To build the source code
# To build the source code from command line
* msbuild Lottie.iOS.csproj /t:restore
* msbuild Lottie.iOS.csproj /p:Configuration=Release
* msbuild Lottie.sln /t:restore
* msbuild Lottie.sln /p:Configuration=Release

Просмотреть файл

@ -1,57 +1,31 @@
# configuration for "master" branch
-
branches:
only:
- master
version: 1.0.0.{build}
image: Visual Studio 2017 RC
- /release\/.*/
version: 1.0.{build}
image: Visual Studio 2017
environment:
ANDROID_HOME: "C:\\android-sdk-windows"
NUGET_SOURCE: https://www.nuget.org/api/v2/package
NUGET_APIKEY:
secure: Kse62H9lWHIwjsqpi2ih1efUnHc5R6VfIzu1Nfr/CXcJSKPkH8EGElCIxvP43/Oh
init:
- cd \
- appveyor DownloadFile http://dl.google.com/android/android-sdk_r24.4.1-windows.zip
- 7z x android-sdk_r24.4.1-windows.zip > nul
- cd "C:\projects\LottieXamarin"
install:
- echo y | "%ANDROID_HOME%\tools\android.bat" update sdk -u -a -t tools
- echo y | "%ANDROID_HOME%\tools\android.bat" update sdk -u -a -t platform-tools
- echo y | "%ANDROID_HOME%\tools\android.bat" update sdk -u -a -t build-tools-24.0.2
- echo y | "%ANDROID_HOME%\tools\android.bat" update sdk -u -a -t android-24
- echo y | "%ANDROID_HOME%\tools\android.bat" update sdk -u -a -t extra-google-m2repository
- echo y | "%ANDROID_HOME%\tools\android.bat" update sdk -u -a -t extra-android-m2repository
build_script:
- ps: .\build.ps1
test:
assemblies:
- '**/*.Tests.dll'
test: off
cache:
- packages -> **\packages.config
-
branches:
only:
- develop
version: 1.0.0.{build}
image: Visual Studio 2017 RC
version: 1.0.{build}
image: Visual Studio 2017
environment:
ANDROID_HOME: "C:\\android-sdk-windows"
NUGET_SOURCE: https://www.myget.org/F/martijn00/api/v2/package
NUGET_SOURCE: https://www.myget.org/F/mvvmcross/api/v2/package
NUGET_APIKEY:
secure: 0PNC9eZWAinI1KkE9usbhPAwF1wudL5GJi6lJn9Ylb67M7SE17LIXBoMHuRKJaLE
init:
- cd \
- appveyor DownloadFile http://dl.google.com/android/android-sdk_r24.4.1-windows.zip
- 7z x android-sdk_r24.4.1-windows.zip > nul
- cd "C:\projects\LottieXamarin"
install:
- echo y | "%ANDROID_HOME%\tools\android.bat" update sdk -u -a -t tools
- echo y | "%ANDROID_HOME%\tools\android.bat" update sdk -u -a -t platform-tools
- echo y | "%ANDROID_HOME%\tools\android.bat" update sdk -u -a -t build-tools-24.0.2
- echo y | "%ANDROID_HOME%\tools\android.bat" update sdk -u -a -t android-24
- echo y | "%ANDROID_HOME%\tools\android.bat" update sdk -u -a -t extra-google-m2repository
- echo y | "%ANDROID_HOME%\tools\android.bat" update sdk -u -a -t extra-android-m2repository
build_script:
- ps: .\build.ps1
test:
assemblies:
- '**/*.Tests.dll'
test: off
cache:
- packages -> **\packages.config

Просмотреть файл

@ -1,153 +1,303 @@
#tool "nuget:?package=GitVersion.CommandLine"
#tool "nuget:?package=gitlink"
#tool nuget:?package=GitVersion.CommandLine
#tool nuget:?package=vswhere
#addin nuget:?package=Cake.Figlet
#addin nuget:?package=Cake.Incubator&version=1.7.1
#addin nuget:?package=Cake.Git&version=0.16.1
#addin nuget:?package=Polly
var sln = new FilePath("Lottie.sln");
var outputDir = new DirectoryPath("artifacts");
var nuspecDir = new DirectoryPath("nuspec");
using Polly;
var sln = new FilePath("./Lottie.sln");
var outputDir = new DirectoryPath("./artifacts");
var nuspecDir = new DirectoryPath("./nuspec");
var target = Argument("target", "Default");
var local = BuildSystem.IsLocalBuild;
var isDevelopBranch = StringComparer.OrdinalIgnoreCase.Equals("develop", AppVeyor.Environment.Repository.Branch);
var isReleaseBranch = StringComparer.OrdinalIgnoreCase.Equals("master", AppVeyor.Environment.Repository.Branch);
var isTagged = AppVeyor.Environment.Repository.Tag.IsTag;
var configuration = Argument("configuration", "Release");
var isRunningOnAppVeyor = AppVeyor.IsRunningOnAppVeyor;
var isPullRequest = AppVeyor.Environment.PullRequest.IsPullRequest;
var isRepository = StringComparer.OrdinalIgnoreCase.Equals("martijn00/LottieXamarin", AppVeyor.Environment.Repository.Name);
GitVersion versionInfo = null;
Setup(context => {
versionInfo = context.GitVersion(new GitVersionSettings {
UpdateAssemblyInfo = true,
OutputType = GitVersionOutput.Json
});
if (isRunningOnAppVeyor)
{
var buildNumber = AppVeyor.Environment.Build.Number;
AppVeyor.UpdateBuildVersion(versionInfo.InformationalVersion
+ "-" + buildNumber);
}
var cakeVersion = typeof(ICakeContext).Assembly.GetName().Version.ToString();
Information(Figlet("Lottie"));
Information("Building version {0}, ({1}, {2}) using version {3} of Cake.",
versionInfo.SemVer,
configuration,
target,
cakeVersion);
Debug("Will push NuGet packages {0}",
ShouldPushNugetPackages(versionInfo.BranchName));
});
Task("Clean").Does(() =>
{
CleanDirectories("./**/bin");
CleanDirectories("./**/obj");
CleanDirectories(outputDir.FullPath);
CleanDirectories(outputDir.FullPath);
EnsureDirectoryExists(outputDir);
});
GitVersion versionInfo = null;
Task("Version").Does(() => {
GitVersion(new GitVersionSettings {
UpdateAssemblyInfo = true,
OutputType = GitVersionOutput.BuildServer
});
versionInfo = GitVersion(new GitVersionSettings{ OutputType = GitVersionOutput.Json });
Information("VI:\t{0}", versionInfo.FullSemVer);
});
Task("UpdateAppVeyorBuildNumber")
.IsDependentOn("Version")
.WithCriteria(() => isRunningOnAppVeyor)
.Does(() =>
FilePath msBuildPath;
Task("ResolveBuildTools")
.WithCriteria(() => IsRunningOnWindows())
.Does(() =>
{
AppVeyor.UpdateBuildVersion(versionInfo.FullBuildMetaData);
var vsLatest = VSWhereLatest();
msBuildPath = (vsLatest == null)
? null
: vsLatest.CombineWithFilePath("./MSBuild/15.0/Bin/MSBuild.exe");
});
Task("Restore").Does(() => {
NuGetRestore(sln);
Task("Restore")
.IsDependentOn("ResolveBuildTools")
.Does(() => {
MSBuild(sln, settings => settings.WithTarget("Restore"));
});
Task("PatchBuildProps")
.Does(() =>
{
var buildProp = new FilePath("./Directory.build.props");
XmlPoke(buildProp, "//Project/PropertyGroup/Version", versionInfo.SemVer);
});
Task("Build")
.IsDependentOn("Clean")
.IsDependentOn("UpdateAppVeyorBuildNumber")
.IsDependentOn("Restore")
.Does(() => {
DotNetBuild(sln,
settings => settings.SetConfiguration("Release")
.WithProperty("DebugSymbols", "true")
.WithProperty("DebugType", "Full")
.WithTarget("Build"));
.IsDependentOn("ResolveBuildTools")
.IsDependentOn("Clean")
.IsDependentOn("PatchBuildProps")
.IsDependentOn("Restore")
.Does(() => {
var settings = new MSBuildSettings
{
Configuration = configuration,
ToolPath = msBuildPath,
Verbosity = Verbosity.Minimal,
ArgumentCustomization = args => args.Append("/m")
};
settings = settings
.WithProperty("DebugSymbols", "True")
.WithProperty("DebugType", "Embedded")
.WithProperty("Version", versionInfo.SemVer)
.WithProperty("PackageVersion", versionInfo.SemVer)
.WithProperty("InformationalVersion", versionInfo.InformationalVersion)
.WithProperty("NoPackageAnalysis", "True");
MSBuild(sln, settings);
});
Task("GitLink")
.IsDependentOn("Build")
//pdbstr.exe and costura are not xplat currently
.WithCriteria(() => IsRunningOnWindows())
.Does(() =>
Task("UnitTest")
.IsDependentOn("Build")
.Does(() =>
{
GitLink(sln.GetDirectory(),
new GitLinkSettings {
RepositoryUrl = "https://github.com/martijn00/LottieXamarin",
ArgumentCustomization = args => args.Append("-ignore Example.iOS,Example.Forms,Example.Forms.iOS,Example.Forms.Android")
});
});
EnsureDirectoryExists(outputDir + "/Tests/");
Task("Package")
.IsDependentOn("GitLink")
.Does(() =>
{
var nugetSettings = new NuGetPackSettings {
Authors = new [] { "Martijn00" },
Owners = new [] { "Martijn00" },
IconUrl = new Uri("https://raw.githubusercontent.com/martijn00/LottieXamarin/master/icon_lottie.png"),
ProjectUrl = new Uri("https://github.com/martijn00/LottieXamarin"),
LicenseUrl = new Uri("https://github.com/martijn00/LottieXamarin/blob/master/LICENSE"),
Copyright = "Copyright (c) Martijn00",
RequireLicenseAcceptance = false,
Version = versionInfo.NuGetVersion,
Symbols = false,
NoPackageAnalysis = true,
OutputDirectory = outputDir,
Verbosity = NuGetVerbosity.Detailed,
BasePath = "./nuspec"
};
var testPaths = GetFiles("./UnitTests/*.UnitTest/*.UnitTest.csproj");
var testsFailed = false;
foreach(var project in testPaths)
{
var projectName = project.GetFilenameWithoutExtension();
var testXml = new FilePath(outputDir + "/Tests/" + projectName + ".xml").MakeAbsolute(Context.Environment);
try
{
DotNetCoreTool(project,
"xunit", "-fxversion 2.0.0 --no-build -parallel none -configuration " +
configuration + " -xml \"" + testXml.FullPath + "\"");
}
catch
{
testsFailed = true;
}
}
EnsureDirectoryExists(outputDir);
if (isRunningOnAppVeyor)
{
foreach(var testResult in GetFiles(outputDir + "/Tests/*.xml"))
AppVeyor.UploadTestResults(testResult, AppVeyorTestResultsType.XUnit);
}
var nuspecs = new List<string> {
"Com.Airbnb.Android.Lottie.nuspec",
"Com.Airbnb.iOS.Lottie.nuspec",
"Com.Airbnb.Xamarin.Forms.Lottie.nuspec"
};
foreach(var nuspec in nuspecs)
{
NuGetPack(nuspecDir + "/" + nuspec, nugetSettings);
}
if (testsFailed)
throw new Exception("Tests failed :(");
});
Task("PublishPackages")
.IsDependentOn("Package")
.WithCriteria(() => !local)
.WithCriteria(() => !isPullRequest)
.WithCriteria(() => isRepository)
.WithCriteria(() => isDevelopBranch || isReleaseBranch)
.WithCriteria(() => !BuildSystem.IsLocalBuild)
.WithCriteria(() => IsRepository("martijn00/LottieXamarin"))
.WithCriteria(() => ShouldPushNugetPackages(versionInfo.BranchName))
.Does (() =>
{
if (isReleaseBranch && !isTagged)
// Resolve the API key.
var nugetKeySource = GetNugetKeyAndSource();
var apiKey = nugetKeySource.Item1;
var source = nugetKeySource.Item2;
var nugetFiles = GetFiles("Lottie*/**/bin/" + configuration + "/**/*.nupkg");
var policy = Policy
.Handle<Exception>()
.WaitAndRetry(5, retryAttempt =>
TimeSpan.FromSeconds(Math.Pow(1.5, retryAttempt)));
foreach(var nugetFile in nugetFiles)
{
Information("Packages will not be published as this release has not been tagged.");
return;
policy.Execute(() =>
NuGetPush(nugetFile, new NuGetPushSettings {
Source = source,
ApiKey = apiKey
})
);
}
// Resolve the API key.
var apiKey = EnvironmentVariable("NUGET_APIKEY");
if (string.IsNullOrEmpty(apiKey))
{
throw new Exception("The NUGET_APIKEY environment variable is not defined.");
}
var source = EnvironmentVariable("NUGET_SOURCE");
if (string.IsNullOrEmpty(source))
{
throw new Exception("The NUGET_SOURCE environment variable is not defined.");
}
var nugetFiles = GetFiles(outputDir + "/*.nupkg");
foreach(var nugetFile in nugetFiles)
{
NuGetPush(nugetFile, new NuGetPushSettings {
Source = source,
ApiKey = apiKey
});
}
});
Task("UploadAppVeyorArtifact")
.WithCriteria(() => isRunningOnAppVeyor)
.Does(() => {
Information("Artifacts Dir: {0}", outputDir.FullPath);
var uploadSettings = new AppVeyorUploadArtifactsSettings();
var artifacts = GetFiles("Lottie*/**/bin/" + configuration + "/**/*.nupkg")
+ GetFiles(outputDir.FullPath + "/**/*");
foreach(var file in artifacts) {
Information("Uploading {0}", file.FullPath);
if (file.GetExtension() == "nupkg")
uploadSettings.ArtifactType = AppVeyorUploadArtifactType.NuGetPackage;
else
uploadSettings.ArtifactType = AppVeyorUploadArtifactType.Auto;
AppVeyor.UploadArtifact(file.FullPath, uploadSettings);
}
});
Task("Default")
.IsDependentOn("PublishPackages")
.Does(() => {
});
.IsDependentOn("Build")
.IsDependentOn("UnitTest")
.IsDependentOn("PublishPackages")
.IsDependentOn("UploadAppVeyorArtifact")
.Does(() =>
{
});
RunTarget(target);
bool ShouldPushNugetPackages(string branchName)
{
if (StringComparer.OrdinalIgnoreCase.Equals(branchName, "develop"))
return true;
return IsMasterOrReleases(branchName) && IsTagged().Item1;
}
bool IsMasterOrReleases(string branchName)
{
if (StringComparer.OrdinalIgnoreCase.Equals(branchName, "master"))
return true;
if (branchName.StartsWith("release/", StringComparison.OrdinalIgnoreCase) ||
branchName.StartsWith("releases/", StringComparison.OrdinalIgnoreCase))
return true;
return false;
}
bool IsRepository(string repoName)
{
if (isRunningOnAppVeyor)
{
var buildEnvRepoName = AppVeyor.Environment.Repository.Name;
Information("Checking repo name: {0} against build repo name: {1}", repoName, buildEnvRepoName);
return StringComparer.OrdinalIgnoreCase.Equals(repoName, buildEnvRepoName);
}
else
{
try
{
var path = MakeAbsolute(sln).GetDirectory().FullPath;
using (var repo = new LibGit2Sharp.Repository(path))
{
var origin = repo.Network.Remotes.FirstOrDefault(
r => r.Name.ToLowerInvariant() == "origin");
return origin.Url.ToLowerInvariant() ==
"https://github.com/" + repoName.ToLowerInvariant();
}
}
catch(Exception ex)
{
Information("Failed to lookup repository: {0}", ex);
return false;
}
}
}
Tuple<bool, string> IsTagged()
{
var path = MakeAbsolute(sln).GetDirectory().FullPath;
using (var repo = new LibGit2Sharp.Repository(path))
{
var head = repo.Head;
var headSha = head.Tip.Sha;
var tag = repo.Tags.FirstOrDefault(t => t.Target.Sha == headSha);
if (tag == null)
{
Debug("HEAD is not tagged");
return Tuple.Create<bool, string>(false, null);
}
Debug("HEAD is tagged: {0}", tag.FriendlyName);
return Tuple.Create<bool, string>(true, tag.FriendlyName);
}
}
Tuple<string, string> GetNugetKeyAndSource()
{
var apiKeyKey = string.Empty;
var sourceKey = string.Empty;
if (isRunningOnAppVeyor)
{
apiKeyKey = "NUGET_APIKEY";
sourceKey = "NUGET_SOURCE";
}
else
{
if (StringComparer.OrdinalIgnoreCase.Equals(versionInfo.BranchName, "develop"))
{
apiKeyKey = "NUGET_APIKEY_DEVELOP";
sourceKey = "NUGET_SOURCE_DEVELOP";
}
else if (IsMasterOrReleases(versionInfo.BranchName))
{
apiKeyKey = "NUGET_APIKEY_MASTER";
sourceKey = "NUGET_SOURCE_MASTER";
}
}
var apiKey = EnvironmentVariable(apiKeyKey);
if (string.IsNullOrEmpty(apiKey))
throw new Exception(string.Format("The {0} environment variable is not defined.", apiKeyKey));
var source = EnvironmentVariable(sourceKey);
if (string.IsNullOrEmpty(source))
throw new Exception(string.Format("The {0} environment variable is not defined.", sourceKey));
return Tuple.Create(apiKey, source);
}