Added Hot Restart support into the SDK (#12293)

- Added Hot Restart support for net6
- Added Hot Restart content into the Windows iOS pack

Co-authored-by: emaf <ema@xamarin.com>
This commit is contained in:
Mauro Agnoletti 2021-08-05 04:19:51 -03:00 коммит произвёл GitHub
Родитель 2507d92588
Коммит 9dbf451d39
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
39 изменённых файлов: 1683 добавлений и 15 удалений

2
external/macios-binaries поставляемый

@ -1 +1 @@
Subproject commit fd29206d98dedbcc08b992916afa2fac1718bf55
Subproject commit b7c6c1c971f94e81d934e112278cd882741918d0

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

@ -1,5 +1,6 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MessagingVersion>1.3.26</MessagingVersion>
<MessagingVersion>1.3.27</MessagingVersion>
<HotRestartVersion>1.0.69</HotRestartVersion>
</PropertyGroup>
</Project>

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

@ -84,6 +84,10 @@
<Delete Files="$(IntermediateOutputPath)ilrepack.txt" Condition="'$(ExitCode)' != '0'" />
<Touch AlwaysCreate="true" Files="$(IntermediateOutputPath)ilrepack.txt" Condition="'$(ExitCode)' == '0'" />
<Error Text="$(ILRepackOutput)" Condition="'$(ExitCode)' != '0' And '$(ContinueOnError)' != 'true'" />
<Delete Files="@(MergedAssemblies -&gt; '$(MSBuildProjectDirectory)\$(OutputPath)%(Filename)%(Extension)')" Condition="Exists('$(MSBuildProjectDirectory)\$(OutputPath)%(Filename)%(Extension)')" />
<ItemGroup>
<MergedAssembliesToRemove Include="@(MergedAssemblies)" />
<MergedAssembliesToRemove Remove="@(ReferenceToPreserve)" />
</ItemGroup>
<Delete Files="@(MergedAssembliesToRemove -&gt; '$(MSBuildProjectDirectory)\$(OutputPath)%(Filename)%(Extension)')" Condition="Exists('$(MSBuildProjectDirectory)\$(OutputPath)%(Filename)%(Extension)')" />
</Target>
</Project>

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

@ -23,6 +23,7 @@ MSBUILD_TASK_ASSEMBLIES =
ALL_SOURCES:= $(shell git ls-files | sed 's/ /\\ /g') $(wildcard $(XAMARIN_MACDEV_PATH)/Xamarin.MacDev/*.cs) $(wildcard $(XAMARIN_MACDEV_PATH)/Xamarin.MacDev/*.csproj)
CONFIG = Debug
TARGETFRAMEWORK = netstandard2.0
WINDOWSRUNTIMEIDENTIFIER = win
##
## XI definitions
@ -38,8 +39,8 @@ IOS_TARGETS = \
IOS_WINDOWS_TARGETS = \
$(wildcard Xamarin.iOS.Tasks.Windows/Xamarin.*.props) \
$(wildcard Xamarin.iOS.Tasks.Windows/Xamarin.*.targets) \
$(wildcard Xamarin.iOS.Tasks.Windows/bin/$(CONFIG)/$(TARGETFRAMEWORK)/Xamarin.*.props) \
$(wildcard Xamarin.iOS.Tasks.Windows/bin/$(CONFIG)/$(TARGETFRAMEWORK)/Xamarin.*.targets) \
$(wildcard Xamarin.iOS.Tasks.Windows/bin/$(CONFIG)/$(TARGETFRAMEWORK)/$(WINDOWSRUNTIMEIDENTIFIER)/Xamarin.*.props) \
$(wildcard Xamarin.iOS.Tasks.Windows/bin/$(CONFIG)/$(TARGETFRAMEWORK)/$(WINDOWSRUNTIMEIDENTIFIER)/Xamarin.*.targets) \
IOS_BINDING_TARGETS = $(wildcard Xamarin.ObjcBinding.Tasks/*.targets)
@ -48,6 +49,8 @@ TRANSLATED_ASSEMBLIES = $(foreach locale,$(LOCALIZATION_LANGUAGES),$(locale)/Xam
LOCALIZATION_ASSEMBLIES = Xamarin.Localization.MSBuild
IOS_TASK_ASSEMBLIES = Xamarin.iOS.Tasks $(LOCALIZATION_ASSEMBLIES)
IOS_WINDOWS_TASK_ASSEMBLIES = Xamarin.iOS.Tasks.Windows
IOS_WINDOWS_DEPENDENCIES = Xamarin.iOS.Windows.Client iSign.Core ws2_32 System.Diagnostics.Tracer BouncyCastle.Crypto System.Buffers System.Memory System.Numerics.Vectors System.Runtime.CompilerServices.Unsafe System.Security.Cryptography.ProtectedData System.Security.Cryptography.Pkcs Microsoft.Win32.Registry System.Security.AccessControl System.Security.Principal.Windows
IOS_WINDOWS_MOBILEDEVICE_TOOLS = iMobileDevice-net bz2 getopt ideviceactivation idevicebackup idevicebackup2 idevicecrashreport idevicedate idevicedebug idevicedebugserverproxy idevicediagnostics ideviceenterrecovery ideviceimagemounter ideviceinfo ideviceinstaller idevicename idevicenotificationproxy idevicepair ideviceprovision idevicerestore idevicescreenshot idevicesyslog idevice_id imobiledevice-net-lighthouse imobiledevice ios_webkit_debug_proxy iproxy irecovery irecovery libcharset libcurl LIBEAY32 libiconv libusb-1.0 libusb0 libxml2 lzma pcre pcreposix plist plistutil plist_cmp plist_test pthreadVC3 readline SSLEAY32 usbmuxd usbmuxd vcruntime140 zip zlib1
IOS_DIRECTORIES = \
$(IOS_DESTDIR)$(MONOTOUCH_PREFIX)/lib/mono/Xamarin.iOS \
@ -473,12 +476,25 @@ MSBUILD_DIRECTORIES += $(DOTNET_DIRECTORIES)
ifdef ENABLE_DOTNET
MSBUILD_PRODUCTS += $(DOTNET_TARGETS)
DOTNET_IOS_WINDOWS_OUTPUT_FILES = $(foreach dll,$(IOS_WINDOWS_TASK_ASSEMBLIES),$(dll).dll $(dll).pdb) Broker.zip Build.zip
DOTNET_IOS_WINDOWS_FILES = $(IOS_WINDOWS_TARGETS) $(foreach file,$(DOTNET_IOS_WINDOWS_OUTPUT_FILES),Xamarin.iOS.Tasks.Windows/bin/$(CONFIG)/$(TARGETFRAMEWORK)/$(file))
DOTNET_IOS_WINDOWS_OUTPUT_FILES = \
$(foreach dll,$(IOS_WINDOWS_TASK_ASSEMBLIES),$(dll).*) \
$(foreach dll,$(IOS_WINDOWS_DEPENDENCIES),$(dll).*) \
Broker.zip \
Build.zip \
Xamarin.PreBuilt.iOS.app.zip
DOTNET_IOS_WINDOWS_FILES = $(IOS_WINDOWS_TARGETS) $(foreach file,$(DOTNET_IOS_WINDOWS_OUTPUT_FILES),Xamarin.iOS.Tasks.Windows/bin/$(CONFIG)/$(TARGETFRAMEWORK)/$(WINDOWSRUNTIMEIDENTIFIER)/$(file))
DOTNET_IOS_WINDOWS_MOBILEDEVICE_TOOLS_X86 = $(foreach file,$(IOS_WINDOWS_MOBILEDEVICE_TOOLS),Xamarin.iOS.Tasks.Windows/bin/$(CONFIG)/$(TARGETFRAMEWORK)/$(WINDOWSRUNTIMEIDENTIFIER)/imobiledevice-x86/$(file).*)
DOTNET_IOS_WINDOWS_MOBILEDEVICE_TOOLS_X64 = $(foreach file,$(IOS_WINDOWS_MOBILEDEVICE_TOOLS),Xamarin.iOS.Tasks.Windows/bin/$(CONFIG)/$(TARGETFRAMEWORK)/$(WINDOWSRUNTIMEIDENTIFIER)/imobiledevice-x64/$(file).*)
# Ensures Xamarin.iOS.Tasks.Windows is built and copies the output files to the Sdk Windows pack
.dotnet-windows: .build-stamp | $(DOTNET_DESTDIR)/$(IOS_WINDOWS_NUGET).Sdk/tools/msbuild/iOS
.copy-windows-files: .build-stamp
$(Q) mkdir -p $(DOTNET_DESTDIR)/$(IOS_WINDOWS_NUGET).Sdk/tools/msbuild/iOS
$(Q) $(CP) $(DOTNET_IOS_WINDOWS_FILES) $(DOTNET_DESTDIR)/$(IOS_WINDOWS_NUGET).Sdk/tools/msbuild/iOS/
$(Q) mkdir -p $(DOTNET_DESTDIR)/$(IOS_WINDOWS_NUGET).Sdk/tools/msbuild/iOS/imobiledevice-x86
$(Q) $(CP) $(DOTNET_IOS_WINDOWS_MOBILEDEVICE_TOOLS_X86) $(DOTNET_DESTDIR)/$(IOS_WINDOWS_NUGET).Sdk/tools/msbuild/iOS/imobiledevice-x86/
$(Q) mkdir -p $(DOTNET_DESTDIR)/$(IOS_WINDOWS_NUGET).Sdk/tools/msbuild/iOS/imobiledevice-x64
$(Q) $(CP) $(DOTNET_IOS_WINDOWS_MOBILEDEVICE_TOOLS_X64) $(DOTNET_DESTDIR)/$(IOS_WINDOWS_NUGET).Sdk/tools/msbuild/iOS/imobiledevice-x64/
.dotnet-windows: .build-stamp .copy-windows-files
all-local:: .dotnet-windows
dotnet:: .dotnet-windows

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

@ -0,0 +1,117 @@
{
"images": [
{
"scale": "2x",
"size": "20x20",
"idiom": "iphone",
"filename": "Icon40.png"
},
{
"scale": "3x",
"size": "20x20",
"idiom": "iphone",
"filename": "Icon60.png"
},
{
"scale": "2x",
"size": "29x29",
"idiom": "iphone",
"filename": "Icon58.png"
},
{
"scale": "3x",
"size": "29x29",
"idiom": "iphone",
"filename": "Icon87.png"
},
{
"scale": "2x",
"size": "40x40",
"idiom": "iphone",
"filename": "Icon80.png"
},
{
"scale": "3x",
"size": "40x40",
"idiom": "iphone",
"filename": "Icon120.png"
},
{
"scale": "2x",
"size": "60x60",
"idiom": "iphone",
"filename": "Icon120.png"
},
{
"scale": "3x",
"size": "60x60",
"idiom": "iphone",
"filename": "Icon180.png"
},
{
"scale": "1x",
"size": "20x20",
"idiom": "ipad",
"filename": "Icon20.png"
},
{
"scale": "2x",
"size": "20x20",
"idiom": "ipad",
"filename": "Icon40.png"
},
{
"scale": "1x",
"size": "29x29",
"idiom": "ipad",
"filename": "Icon29.png"
},
{
"scale": "2x",
"size": "29x29",
"idiom": "ipad",
"filename": "Icon58.png"
},
{
"scale": "1x",
"size": "40x40",
"idiom": "ipad",
"filename": "Icon40.png"
},
{
"scale": "2x",
"size": "40x40",
"idiom": "ipad",
"filename": "Icon80.png"
},
{
"scale": "1x",
"size": "76x76",
"idiom": "ipad",
"filename": "Icon76.png"
},
{
"scale": "2x",
"size": "76x76",
"idiom": "ipad",
"filename": "Icon152.png"
},
{
"scale": "2x",
"size": "83.5x83.5",
"idiom": "ipad",
"filename": "Icon167.png"
},
{
"scale": "1x",
"size": "1024x1024",
"idiom": "ios-marketing",
"filename": "Icon1024.png"
}
],
"properties": {},
"info": {
"version": 1,
"author": "xcode"
}
}

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 69 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.6 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.6 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.1 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.3 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 845 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.5 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.3 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.7 KiB

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

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
</dict>
</plist>

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

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>MinimumOSVersion</key>
<string>10.0</string>
<key>CFBundleDisplayName</key>
<string>Xamarin.PreBuilt</string>
<key>CFBundleIdentifier</key>
<string>com.xamarin.Xamarin-PreBuilt</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>CFBundleName</key>
<string>Xamarin.PreBuilt</string>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/AppIcon.appiconset</string>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
<key>UIFileSharingEnabled</key>
<true/>
</dict>
</plist>

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

@ -0,0 +1,38 @@
using Foundation;
using ObjCRuntime;
using System;
using System.Runtime.InteropServices;
using UIKit;
namespace Xamarin.PreBuilt.iOS
{
public class Applications
{
static void Main(string[] args)
=> Xamarin.iOS.HotRestart.Application.Run(args, (string frameworkPath) => Dlfcn.dlopen(frameworkPath, 0), () => TerminateApplication());
static void TerminateApplication()
{
Console.WriteLine("Closing the running application to re-launch...");
Console.WriteLine("Trying Exit Option 1...");
Exit(0);
Console.WriteLine("Option 1 failed. Trying Exit Option 2...");
NSThread.Exit();
Console.WriteLine("Option 2 failed. Trying Exit Option 3...");
TerminateWithSuccess();
Console.WriteLine("Option 3 failed. Trying Exit Option 4...");
throw new Xamarin.iOS.HotRestart.KillApplicationException();
}
[DllImport("__Internal", EntryPoint = "exit")]
static extern void Exit(int status);
static void TerminateWithSuccess()
{
var selector = new Selector("terminateWithSuccess");
UIApplication.SharedApplication.PerformSelector(selector, UIApplication.SharedApplication, 0);
}
}
}

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 8.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.1 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 8.2 KiB

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

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6245" systemVersion="13F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="X5k-f2-b5h">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6238"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="gAE-YM-kbH">
<objects>
<viewController id="X5k-f2-b5h" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Y8P-hJ-Z43"/>
<viewControllerLayoutGuide type="bottom" id="9ZL-r4-8FZ"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="yd7-JS-zBw">
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="center" misplaced="YES" image="HotRestart-LaunchIcon.png" translatesAutoresizingMaskIntoConstraints="NO" id="23">
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
<rect key="contentStretch" x="0.0" y="0.0" width="0.0" height="0.0"/>
</imageView>
</subviews>
<color key="backgroundColor" red="0.20392156862745098" green="0.59607843137254901" blue="0.85882352941176465" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstItem="23" firstAttribute="centerY" secondItem="yd7-JS-zBw" secondAttribute="centerY" priority="1" id="39"/>
<constraint firstItem="23" firstAttribute="centerX" secondItem="yd7-JS-zBw" secondAttribute="centerX" priority="1" id="41"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="XAI-xm-WK6" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="349" y="339"/>
</scene>
</scenes>
</document>

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

@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-ios</TargetFramework>
<RuntimeIdentifier>ios-arm64</RuntimeIdentifier>
<OutputType>Exe</OutputType>
</PropertyGroup>
<PropertyGroup>
<ProvisioningType>automatic</ProvisioningType>
<DebugType>portable</DebugType>
<_LinkMode>None</_LinkMode>
<UseInterpreter>true</UseInterpreter>
<MtouchExtraArgs>--registrar:dynamic</MtouchExtraArgs>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Xamarin.iOS.HotRestart.Application" Version="1.1.2" />
</ItemGroup>
<ItemGroup>
<BundleResource Include="Resources\HotRestart-LaunchIcon-568h%402x.png" />
<BundleResource Include="Resources\HotRestart-LaunchIcon.png" />
<BundleResource Include="Resources\HotRestart-LaunchIcon%402x.png" />
</ItemGroup>
<!-- For debug only, copies files from a AdditionalFiles directory into the bundle (i.e. an app to be interpreted) -->
<!-- <Target Name="ResolveAdditionalReferences">
<ItemGroup>
<AdditionalFiles Include="AdditionalReferences\**\*.*" Exclude="AdditionalReferences\Xamarin.Forms.Core.dll" />
</ItemGroup>
</Target>
<Target Name="CopyAdditionalReferences" DependsOnTargets="ResolveAdditionalReferences" AfterTargets="_CalculateCodesignAppBundleInputs" Inputs="@(AdditionalFiles)" Outputs="@(AdditionalFiles -> '$(_AppBundlePath)$(_AppBundleName).content\%(RecursiveDir)%(Filename)%(Extension)')">
<Copy SourceFiles="@(AdditionalFiles)" DestinationFiles="@(AdditionalFiles -> '$(_AppBundlePath)$(_AppBundleName).content\%(RecursiveDir)%(Filename)%(Extension)')" />
</Target> -->
</Project>

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

@ -0,0 +1,81 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29411.138
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.PreBuilt.iOS", "Xamarin.PreBuilt.iOS\Xamarin.PreBuilt.iOS.csproj", "{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
Ad-Hoc|iPhone = Ad-Hoc|iPhone
Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator
AppStore|Any CPU = AppStore|Any CPU
AppStore|iPhone = AppStore|iPhone
AppStore|iPhoneSimulator = AppStore|iPhoneSimulator
Debug|Any CPU = Debug|Any CPU
Debug|iPhone = Debug|iPhone
Debug|iPhoneSimulator = Debug|iPhoneSimulator
Release|Any CPU = Release|Any CPU
Release|iPhone = Release|iPhone
Release|iPhoneSimulator = Release|iPhoneSimulator
UI Test|Any CPU = UI Test|Any CPU
UI Test|iPhone = UI Test|iPhone
UI Test|iPhoneSimulator = UI Test|iPhoneSimulator
UITEST|Any CPU = UITEST|Any CPU
UI-Test|Any CPU = UI-Test|Any CPU
UITEST|iPhone = UITEST|iPhone
UI-Test|iPhone = UI-Test|iPhone
UITEST|iPhoneSimulator = UITEST|iPhoneSimulator
UI-Test|iPhoneSimulator = UI-Test|iPhoneSimulator
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.Ad-Hoc|Any CPU.ActiveCfg = Release|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.Ad-Hoc|Any CPU.Build.0 = Release|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.Ad-Hoc|iPhone.ActiveCfg = Debug|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.Ad-Hoc|iPhone.Build.0 = Debug|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.AppStore|Any CPU.ActiveCfg = Release|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.AppStore|Any CPU.Build.0 = Release|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.AppStore|iPhone.ActiveCfg = Debug|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.AppStore|iPhone.Build.0 = Debug|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.AppStore|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.AppStore|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.Debug|iPhone.ActiveCfg = Debug|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.Debug|iPhone.Build.0 = Debug|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.Release|Any CPU.Build.0 = Release|iPhoneSimulator
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.Release|iPhone.ActiveCfg = Release|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.Release|iPhone.Build.0 = Release|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.UI Test|Any CPU.ActiveCfg = Release|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.UI Test|Any CPU.Build.0 = Release|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.UI Test|iPhone.ActiveCfg = Debug|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.UI Test|iPhone.Build.0 = Debug|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.UI Test|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.UI Test|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.UITEST|Any CPU.ActiveCfg = Release|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.UITEST|Any CPU.Build.0 = Release|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.UI-Test|Any CPU.ActiveCfg = Release|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.UI-Test|Any CPU.Build.0 = Release|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.UITEST|iPhone.ActiveCfg = Debug|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.UITEST|iPhone.Build.0 = Debug|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.UI-Test|iPhone.ActiveCfg = Debug|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.UI-Test|iPhone.Build.0 = Debug|iPhone
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.UITEST|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.UITEST|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.UI-Test|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{CA6E0AA8-7FF0-45DA-BFC9-DBC2B4FB55C0}.UI-Test|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4F35FA41-BF70-4770-ADFD-D7F760F511B1}
EndGlobalSection
EndGlobal

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

@ -64,5 +64,35 @@ namespace Xamarin.iOS.Tasks.Windows.Properties {
return ResourceManager.GetString("LocalUnzip_Unzipping", resourceCulture);
}
}
internal static string CollectDynamicFrameworks_InvalidFramework {
get {
return ResourceManager.GetString("CollectDynamicFrameworks_InvalidFramework", resourceCulture);
}
}
internal static string LocalCodesign_MissingPasswordFile {
get {
return ResourceManager.GetString("LocalCodesign_MissingPasswordFile", resourceCulture);
}
}
internal static string LocalCodesign_MissingTerminal {
get {
return ResourceManager.GetString("LocalCodesign_MissingTerminal", resourceCulture);
}
}
internal static string LocalCodesign_ToolArguments {
get {
return ResourceManager.GetString("LocalCodesign_ToolArguments", resourceCulture);
}
}
internal static string CompileAppManifest_MissinInfoPList {
get {
return ResourceManager.GetString("CompileAppManifest_MissinInfoPList", resourceCulture);
}
}
}
}

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

@ -21,4 +21,23 @@
<data name="LocalUnzip_Unzipping" xml:space="preserve">
<value>Unzipping {0}...</value>
</data>
<data name="CollectDynamicFrameworks_InvalidFramework" xml:space="preserve">
<value>Skipping invalid framework {0}. Reason: {1}</value>
<comment>0: framework name; 1: why the framework was skipped</comment>
</data>
<data name="LocalCodesign_MissingPasswordFile" xml:space="preserve">
<value>Could not find the password for the selected Signing Identity, please create a new Certificate from Tools -&gt; Options -&gt; Apple Accounts -&gt; View Team Details.</value>
</data>
<data name="LocalCodesign_MissingTerminal" xml:space="preserve">
<value>Could not find the winiostermial executable {0}</value>
<comment>0: path to the terminal</comment>
</data>
<data name="LocalCodesign_ToolArguments" xml:space="preserve">
<value>Started signing tool with arguments: {0}</value>
<comment>0: arguments</comment>
</data>
<data name="CompileAppManifest_MissinInfoPList" xml:space="preserve">
<value>Info.plist file does not exist under {0}, please rebuild your project</value>
<comment>0: path</comment>
</data>
</root>

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

@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Xamarin.iOS.Tasks.Windows.Properties;
using Xamarin.iOS.Windows;
namespace Xamarin.iOS.HotRestart.Tasks {
public class Codesign : Task, ICancelableTask {
CancellationTokenSource cancellationSource;
#region Inputs
[Required]
public string AppBundlePath { get; set; }
[Required]
public string BundleIdentifier { get; set; }
[Required]
public string CodeSigningPath { get; set; }
[Required]
public string ProvisioningProfilePath { get; set; }
#endregion
public override bool Execute ()
{
try {
var hotRestartClient = new HotRestartClient ();
var plistArgs = new Dictionary<string, string>
{
{ "CFBundleIdentifier", BundleIdentifier }
};
var password = hotRestartClient.CertificatesManager.GetCertificatePassword (certificatePath: CodeSigningPath);
if (password == null) {
throw new Exception (Resources.LocalCodesign_MissingPasswordFile);
}
hotRestartClient.Sign (AppBundlePath, ProvisioningProfilePath, CodeSigningPath, password, plistArgs);
} catch (WindowsiOSException ex) {
var message = GetFullExceptionMesage (ex);
Log.LogError (null, ex.ErrorCode, null, null, 0, 0, 0, 0, message);
} catch (Exception ex) {
Log.LogErrorFromException (ex);
}
return !Log.HasLoggedErrors;
}
public void Cancel () => cancellationSource?.Cancel ();
string GetFullExceptionMesage (Exception ex)
{
var messageBuilder = new StringBuilder ();
return GetFullExceptionMesage (ex, messageBuilder);
}
string GetFullExceptionMesage (Exception ex, StringBuilder messageBuilder)
{
messageBuilder.AppendLine (ex.Message);
if (ex.InnerException != null) {
return GetFullExceptionMesage (ex.InnerException, messageBuilder);
} else {
return messageBuilder.ToString ();
}
}
}
}

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

@ -0,0 +1,62 @@
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Xamarin.iOS.Tasks.Windows.Properties;
using Xamarin.iOS.Windows;
namespace Xamarin.iOS.HotRestart.Tasks {
public class CollectDynamicFrameworks : Task {
#region Inputs
[Required]
public ITaskItem [] Frameworks { get; set; }
#endregion
#region Outputs
[Output]
public ITaskItem [] DynamicFrameworks { get; set; }
#endregion
public override bool Execute ()
{
var frameworks = new List<ITaskItem> ();
var hotRestartClient = new HotRestartClient ();
foreach (var framework in Frameworks.Where (f => Path.GetExtension (f.ItemSpec.TrimEnd ('\\')) == ".framework")) {
framework.ItemSpec = framework.ItemSpec.TrimEnd ('\\');
if (frameworks.Any (x => x.ItemSpec == framework.ItemSpec)) {
continue;
}
var frameworkDirName = Path.GetFileName (framework.ItemSpec);
try {
var frameworkPath = Path.Combine (framework.ItemSpec, Path.GetFileNameWithoutExtension (frameworkDirName));
hotRestartClient.LoadDynamicFramework (frameworkPath);
} catch (AppleInvalidFrameworkException frameworkEx) {
Log.LogMessage (MessageImportance.Normal, Resources.CollectDynamicFrameworks_InvalidFramework, Path.GetFileName (framework.ItemSpec), frameworkEx.Message);
continue;
} catch (Exception ex) {
Log.LogErrorFromException (ex);
break;
}
framework.SetMetadata ("FrameworkDir", $@"{frameworkDirName}\");
frameworks.Add (framework);
}
DynamicFrameworks = frameworks.ToArray ();
return !Log.HasLoggedErrors;
}
}
}

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

@ -0,0 +1,75 @@
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System;
using System.IO;
using System.Linq;
using Xamarin.iOS.Tasks.Windows.Properties;
using Xamarin.MacDev;
namespace Xamarin.iOS.HotRestart.Tasks
{
public class CompileAppManifest : Task
{
static readonly string[] IgnorePlistKeys = {
"XSAppIconAssets",
"CFBundleIconName",
"XSLaunchImageAssets",
"UIMainStoryboardFile",
"UIFileSharingEnabled",
"UILaunchStoryboardName",
"UIMainStoryboardFile~ipad",
"UIMainStoryboardFile~iphone",
"CFBundleIdentifier",
"CFBundleExecutable"
};
#region Inputs
[Required]
public string AppBundlePath { get; set; }
[Required]
public string AppManifestPath { get; set; }
#endregion
public override bool Execute()
{
try
{
var preBuiltInfoPlistPath = Path.Combine(AppBundlePath, "Info.plist");
if (!File.Exists(preBuiltInfoPlistPath))
{
throw new Exception(string.Format(Resources.CompileAppManifest_MissinInfoPList, preBuiltInfoPlistPath));
}
var infoPlist = PDictionary.FromFile(AppManifestPath);
var preBuiltInfoPlist = PDictionary.FromFile(preBuiltInfoPlistPath);
foreach (var item in infoPlist)
{
if (!IgnorePlistKeys.Contains(item.Key))
{
if (preBuiltInfoPlist.ContainsKey(item.Key))
{
preBuiltInfoPlist.Remove(item.Key);
}
preBuiltInfoPlist.Add(item.Key, item.Value.Clone());
}
}
preBuiltInfoPlist.Save(preBuiltInfoPlistPath, binary: true);
return true;
}
catch (Exception ex)
{
Log.LogErrorFromException(ex);
return false;
}
}
}
}

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

@ -0,0 +1,542 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Xamarin.iOS.Windows;
using Xamarin.MacDev;
namespace Xamarin.iOS.HotRestart.Tasks {
public class DetectSigningIdentity : Task {
static readonly string ProvisioningPath = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData), "Xamarin", "iOS", "Provisioning");
static readonly string ProfilesPath = Path.Combine (ProvisioningPath, "Profiles");
static readonly string CertificatesPath = Path.Combine (ProvisioningPath, "Certificates");
const string AutomaticProvision = "Automatic";
const string AutomaticAdHocProvision = "Automatic:AdHoc";
const string AutomaticAppStoreProvision = "Automatic:AppStore";
const string AutomaticInHouseProvision = "Automatic:InHouse";
protected string PlatformName => "iOS";
protected string ApplicationIdentifierKey => "application-identifier";
protected string [] DevelopmentPrefixes => IPhoneCertificate.DevelopmentPrefixes;
protected string [] AppStoreDistributionPrefixes => IPhoneCertificate.DistributionPrefixes;
string provisioningProfileName;
string codesignCommonName;
IHotRestartClient hotRestartClient;
#region Inputs
// Single-project property that determines whether other single-project properties should have any effect
public bool GenerateApplicationManifest { get; set; }
// Single-project property that maps to CFBundleIdentifier
public string ApplicationId { get; set; }
// Single-project property that maps to CFBundleDisplayName
public string ApplicationTitle { get; set; }
[Required]
public string AppManifest { get; set; }
public string SigningKey { get; set; }
public string ProvisioningProfile { get; set; }
#endregion
#region Outputs
[Output]
public string DetectedCodeSigningPath { get; set; }
[Output]
public string DetectedProvisioningProfilePath { get; set; }
[Output]
public string DetectedProvisioningProfileId { get; set; }
[Output]
public string DetectedAppId { get; set; }
[Output]
public string DetectedBundleId { get; set; }
[Output]
public string DetectedAppDisplayName { get; set; }
#endregion
public override bool Execute ()
{
PDictionary plist;
IList<MobileProvision> profiles;
IList<X509Certificate2> certs;
List<CodeSignIdentity> pairs;
var type = GetProvisioningDistributionType ();
var platform = MobileProvisionPlatform.iOS;
var identity = new CodeSignIdentity ();
hotRestartClient = new HotRestartClient ();
try {
plist = PDictionary.FromFile (AppManifest);
} catch (Exception ex) {
Log.LogError (null, null, null, AppManifest, 0, 0, 0, 0, "Error loading '{0}': {1}", AppManifest, ex.Message);
return false;
}
identity.BundleId = plist.GetCFBundleIdentifier ();
if (string.IsNullOrEmpty (identity.BundleId)) {
if (GenerateApplicationManifest && !string.IsNullOrEmpty (ApplicationId)) {
identity.BundleId = ApplicationId;
} else {
Log.LogError (null, null, null, AppManifest, 0, 0, 0, 0, "{0} does not define CFBundleIdentifier", AppManifest);
return false;
}
}
DetectedBundleId = identity.BundleId;
var appDisplayName = plist.GetCFBundleDisplayName ();
if (string.IsNullOrEmpty (appDisplayName)) {
if (GenerateApplicationManifest && !string.IsNullOrEmpty (ApplicationTitle)) {
appDisplayName = ApplicationTitle;
}
}
DetectedAppDisplayName = appDisplayName;
if (!TryGetSigningCertificates (out certs, false))
return false;
Log.LogMessage (MessageImportance.Low, "Available certificates:");
foreach (var cert in certs)
Log.LogMessage (MessageImportance.Low, " {0}", GetCertificateCommonName (cert));
if (!IsAutoCodeSignProfile (ProvisioningProfile)) {
identity.Profile = MobileProvisionIndex.GetMobileProvision (platform, ProvisioningProfile);
if (identity.Profile == null) {
Log.LogError ("The specified " + PlatformName + " provisioning profile '{0}' could not be found. Please enable Automatic Provisioning from the iOS Bundle Signing page.", ProvisioningProfile);
return false;
}
var profile = identity.Profile; // capture ref for lambda
if (certs.Count > 0) {
identity.SigningKey = certs.FirstOrDefault (c => profile.DeveloperCertificates.Any (p => p.Thumbprint == c.Thumbprint));
if (identity.SigningKey == null) {
Log.LogError ("No " + PlatformName + " signing identities match the specified provisioning profile '{0}'.", ProvisioningProfile);
return false;
}
}
identity.AppId = ConstructValidAppId (identity.Profile, identity.BundleId);
if (identity.AppId == null) {
Log.LogError (null, null, null, AppManifest, 0, 0, 0, 0, "Project bundle identifier '{0}' does not match specified provisioning profile '{1}'. Please enable Automatic Provisioning from the iOS Bundle Signing page.", identity.BundleId, ProvisioningProfile);
return false;
}
if (identity.SigningKey != null) {
codesignCommonName = GetCertificateCommonName (identity.SigningKey);
DetectedCodeSigningPath = Path.Combine (CertificatesPath, $"{identity.SigningKey.SerialNumber}.p12");
}
provisioningProfileName = identity.Profile.Name;
DetectedAppId = identity.AppId;
DetectedProvisioningProfileId = identity.Profile.Uuid;
DetectedProvisioningProfilePath = Path.Combine (ProfilesPath, $"{DetectedProvisioningProfileId}.mobileprovision");
ReportDetectedCodesignInfo ();
return !Log.HasLoggedErrors;
}
if ((profiles = GetProvisioningProfiles (platform, type, identity, certs)) == null)
return false;
if ((pairs = GetCodeSignIdentityPairs (profiles, certs)) == null)
return false;
identity = GetBestMatch (pairs, identity);
if (identity.Profile != null && identity.AppId != null) {
codesignCommonName = identity.SigningKey != null ? GetCertificateCommonName (identity.SigningKey) : null;
provisioningProfileName = identity.Profile.Name;
DetectedAppId = identity.AppId;
DetectedCodeSigningPath = identity.SigningKey != null ? Path.Combine (CertificatesPath, $"{identity.SigningKey.SerialNumber}.p12") : string.Empty;
DetectedProvisioningProfileId = identity.Profile.Uuid;
DetectedProvisioningProfilePath = Path.Combine (ProfilesPath, $"{DetectedProvisioningProfileId}.mobileprovision");
ReportDetectedCodesignInfo ();
} else {
if (identity.SigningKey != null) {
Log.LogError ("Bundle identifier '{0}' does not match any installed provisioning profile for selected signing identity '{0}'. Please enable Automatic Provisioning from the iOS Bundle Signing page.", identity.BundleId, identity.SigningKey);
} else {
Log.LogError ("Bundle identifier '{0}' does not match any installed provisioning profile. Please enable Automatic Provisioning from the iOS Bundle Signing page.", identity.BundleId);
}
}
return !Log.HasLoggedErrors;
}
static bool IsAutoCodeSignProfile (string value)
{
if (string.IsNullOrEmpty (value))
return true;
switch (value) {
case AutomaticAppStoreProvision:
case AutomaticAdHocProvision:
case AutomaticInHouseProvision:
case AutomaticProvision:
return true;
default:
return false;
}
}
string ConstructValidAppId (MobileProvision provision, string bundleId)
{
int matchLength;
return ConstructValidAppId (provision, bundleId, out matchLength);
}
string ConstructValidAppId (MobileProvision provision, string bundleId, out int matchLength)
{
if (!provision.Entitlements.ContainsKey (ApplicationIdentifierKey)) {
matchLength = 0;
return null;
}
return ConstructValidAppId (
provision.ApplicationIdentifierPrefix [0] + "." + bundleId,
((PString) provision.Entitlements [ApplicationIdentifierKey]).Value,
out matchLength
);
}
static string ConstructValidAppId (string appid, string allowed, out int matchLength)
{
// The user can't have a wildcard ID as their actual app id
if (appid.Contains ("*")) {
matchLength = 0;
return null;
}
// Next check if we have an exact match
if (allowed == appid) {
matchLength = allowed.Length;
return appid;
}
// Finally if the profile is a wildcard, ensure that the appid matches it for everything before the '*'
int star = allowed.IndexOf ('*');
if (star != -1 && star + 1 == allowed.Length && appid.Length >= star && appid.StartsWith (allowed.Substring (0, star), StringComparison.Ordinal)) {
matchLength = star;
return appid;
}
// It does not match
matchLength = 0;
return null;
}
void ReportDetectedCodesignInfo ()
{
Log.LogMessage (MessageImportance.High, "Detected signing identity:");
if (codesignCommonName != null)
Log.LogMessage (MessageImportance.High, " Code Signing Key: \"{0}\" ({1})", codesignCommonName, DetectedCodeSigningPath);
if (provisioningProfileName != null)
Log.LogMessage (MessageImportance.High, " Provisioning Profile: \"{0}\" ({1})", provisioningProfileName, DetectedProvisioningProfilePath);
}
static bool MatchesAny (string name, string [] names)
{
for (int i = 0; i < names.Length; i++) {
if (name == names [i])
return true;
}
return false;
}
static bool StartsWithAny (string name, string [] prefixes)
{
foreach (var prefix in prefixes) {
if (name.StartsWith (prefix, StringComparison.Ordinal))
return true;
}
return false;
}
bool TryGetSigningCertificates (out IList<X509Certificate2> certs, string [] prefixes, bool allowZeroCerts)
{
var now = DateTime.Now;
certs = new List<X509Certificate2> ();
foreach (var certificate in GetAllCertificates ()) {
var cname = GetCertificateCommonName (certificate);
if (!StartsWithAny (cname, prefixes)) {
Log.LogMessage (MessageImportance.Low, "The certificate '{0}' does not match any of the prefixes '{1}'.", cname, string.Join ("', '", prefixes));
continue;
}
if (now >= certificate.NotAfter) {
Log.LogMessage (MessageImportance.Low, "The certificate '{0}' has expired ({1})", cname, certificate.NotAfter);
continue;
}
certs.Add (certificate);
}
if (certs.Count == 0 && !allowZeroCerts) {
var message = "No valid " + PlatformName + " code signing keys found in keychain. Please enable Automatic Provisioning from the iOS Bundle Signing page.";
Log.LogError (message);
return false;
}
return true;
}
bool TryGetSigningCertificates (out IList<X509Certificate2> certs, string name)
{
var now = DateTime.Now;
certs = new List<X509Certificate2> ();
foreach (var certificate in GetAllCertificates ()) {
var cname = GetCertificateCommonName (certificate);
if (!name.Equals (certificate.Thumbprint, StringComparison.OrdinalIgnoreCase) && name != cname) {
Log.LogMessage (MessageImportance.Low, "The certificate '{0}' does not match '{1}'.", cname, name);
continue;
}
if (now >= certificate.NotAfter) {
Log.LogMessage (MessageImportance.Low, "The certificate '{0}' has expired ({1})", cname, certificate.NotAfter);
continue;
}
certs.Add (certificate);
}
if (certs.Count == 0) {
Log.LogError (PlatformName + " code signing key '{0}' not found in keychain.", SigningKey);
return false;
}
return true;
}
bool TryGetSigningCertificates (out IList<X509Certificate2> certs, bool allowZeroCerts)
{
try {
if (string.IsNullOrEmpty (SigningKey) || MatchesAny (SigningKey, DevelopmentPrefixes)) {
// Note: we treat an empty signing key as "developer automatic".
if (!TryGetSigningCertificates (out certs, DevelopmentPrefixes, allowZeroCerts))
return false;
} else if (MatchesAny (SigningKey, AppStoreDistributionPrefixes)) {
if (!TryGetSigningCertificates (out certs, AppStoreDistributionPrefixes, false))
return false;
} else {
// The user has specified an exact name to match...
if (!TryGetSigningCertificates (out certs, SigningKey))
return false;
}
return true;
} catch (Exception ex) {
Log.LogError ("{0}", ex.Message);
certs = null;
return false;
}
}
IList<MobileProvision> GetProvisioningProfiles (MobileProvisionPlatform platform, MobileProvisionDistributionType type, CodeSignIdentity identity, IList<X509Certificate2> certs)
{
var failures = new List<string> ();
IList<MobileProvision> profiles;
if (identity.BundleId != null) {
if (certs.Count > 0)
profiles = MobileProvisionIndex.GetMobileProvisions (platform, identity.BundleId, type, certs, unique: true, failures: failures);
else
profiles = MobileProvisionIndex.GetMobileProvisions (platform, identity.BundleId, type, unique: true, failures: failures);
} else if (certs.Count > 0) {
profiles = MobileProvisionIndex.GetMobileProvisions (platform, type, certs, unique: true, failures: failures);
} else {
profiles = MobileProvisionIndex.GetMobileProvisions (platform, type, unique: true, failures: failures);
}
if (profiles.Count == 0) {
foreach (var f in failures)
Log.LogMessage (MessageImportance.Low, "{0}", f);
Log.LogError ($"Could not find any available provisioning profiles for {PlatformName}. Please enable Automatic Provisioning from the iOS Bundle Signing page.");
return null;
}
Log.LogMessage (MessageImportance.Low, "Available profiles:");
foreach (var p in profiles)
Log.LogMessage (MessageImportance.Low, " {0}", p.Name);
return profiles;
}
List<CodeSignIdentity> GetCodeSignIdentityPairs (IList<MobileProvision> profiles, IList<X509Certificate2> certs)
{
List<CodeSignIdentity> pairs;
if (certs.Count > 0) {
pairs = (from p in profiles
from c in certs
where p.DeveloperCertificates.Any (d => {
var rv = d.Thumbprint == c.Thumbprint;
if (!rv)
Log.LogMessage (MessageImportance.Low, "'{0}' doesn't match '{1}'.", d.Thumbprint, c.Thumbprint);
return rv;
})
select new CodeSignIdentity { SigningKey = c, Profile = p }).ToList ();
if (pairs.Count == 0) {
Log.LogError ("No installed provisioning profiles match the installed " + PlatformName + " signing identities. Please enable Automatic Provisioning from the iOS Bundle Signing page.");
return null;
}
} else {
pairs = (from p in profiles select new CodeSignIdentity { Profile = p }).ToList ();
}
return pairs;
}
CodeSignIdentity GetBestMatch (List<CodeSignIdentity> pairs, CodeSignIdentity identity)
{
var matches = new List<CodeSignIdentity> ();
int bestMatchLength = 0;
int matchLength;
// find matching provisioning profiles with compatible appid, keeping only those with the longest matching (wildcard) ids
Log.LogMessage (MessageImportance.Low, "Finding matching provisioning profiles with compatible AppID, keeping only those with the longest matching (wildcard) IDs.");
foreach (var pair in pairs) {
var appid = ConstructValidAppId (pair.Profile, identity.BundleId, out matchLength);
if (appid != null) {
if (matchLength >= bestMatchLength) {
if (matchLength > bestMatchLength) {
bestMatchLength = matchLength;
foreach (var previousMatch in matches)
Log.LogMessage (MessageImportance.Low, "AppID: {0} was ruled out because we found a better match: {1}.", previousMatch.AppId, appid);
matches.Clear ();
}
var match = identity.Clone ();
match.SigningKey = pair.SigningKey;
match.Profile = pair.Profile;
match.AppId = appid;
matches.Add (match);
} else {
string currentMatches = "";
foreach (var match in matches)
currentMatches += $"{match}; ";
Log.LogMessage (MessageImportance.Low, "AppID: {0} was ruled out because we already found better matches: {1}.", appid, currentMatches);
}
}
}
if (matches.Count == 0) {
Log.LogWarning (null, null, null, AppManifest, 0, 0, 0, 0, "No installed provisioning profiles match the bundle identifier.");
return identity;
}
if (matches.Count > 1) {
var spaces = new string (' ', 3);
Log.LogMessage (MessageImportance.Normal, "Multiple provisioning profiles match the bundle identifier; using the first match.");
matches.Sort (new SigningIdentityComparer ());
for (int i = 0; i < matches.Count; i++) {
Log.LogMessage (MessageImportance.Normal, "{0,3}. Provisioning Profile: \"{1}\" ({2})", i + 1, matches [i].Profile.Name, matches [i].Profile.Uuid);
if (matches [i].SigningKey != null)
Log.LogMessage (MessageImportance.Normal, "{0} Signing Identity: \"{1}\"", spaces, GetCertificateCommonName (matches [i].SigningKey));
}
}
return matches [0];
}
MobileProvisionDistributionType GetProvisioningDistributionType ()
{
if (ProvisioningProfile == AutomaticAppStoreProvision)
return MobileProvisionDistributionType.AppStore;
else if (ProvisioningProfile == AutomaticInHouseProvision)
return MobileProvisionDistributionType.InHouse;
else if (ProvisioningProfile == AutomaticAdHocProvision)
return MobileProvisionDistributionType.AdHoc;
return MobileProvisionDistributionType.Any;
}
IEnumerable<X509Certificate2> GetAllCertificates () => hotRestartClient.CertificatesManager.GetInstalledCertificates ();
string GetCertificateCommonName (X509Certificate2 certificate) => hotRestartClient.CertificatesManager.GetCertificateCommonName (certificate.SerialNumber);
class CodeSignIdentity {
public X509Certificate2 SigningKey { get; set; }
public MobileProvision Profile { get; set; }
public string BundleId { get; set; }
public string AppId { get; set; }
public CodeSignIdentity Clone ()
{
return new CodeSignIdentity {
SigningKey = SigningKey,
Profile = Profile,
BundleId = BundleId,
AppId = AppId
};
}
}
class SigningIdentityComparer : IComparer<CodeSignIdentity> {
public int Compare (CodeSignIdentity x, CodeSignIdentity y)
{
// reverse sort by provisioning profile creation date
return y.Profile.CreationDate.CompareTo (x.Profile.CreationDate);
}
}
}
}

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

@ -0,0 +1,45 @@
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System.IO;
using System.IO.Compression;
using Xamarin.iOS.Windows;
namespace Xamarin.iOS.HotRestart.Tasks {
public class PrepareAppBundle : Task {
#region Inputs
[Required]
public string AppBundleName { get; set; }
[Required]
public string SessionId { get; set; }
[Required]
public bool ShouldExtract { get; set; }
#endregion
#region Outputs
[Output]
public string AppBundlePath { get; set; }
#endregion
public override bool Execute ()
{
AppBundlePath = HotRestartContext.Default.GetAppBundlePath (AppBundleName, SessionId.Substring (0, 8));
if (!Directory.Exists (AppBundlePath) && ShouldExtract) {
var preBuiltAppBundlePath = Path.Combine (
Path.GetDirectoryName (typeof (PrepareAppBundle).Assembly.Location),
"Xamarin.PreBuilt.iOS.app.zip");
ZipFile.ExtractToDirectory (preBuiltAppBundlePath, AppBundlePath);
File.WriteAllText (Path.Combine (AppBundlePath, "Extracted"), string.Empty);
}
return true;
}
}
}

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

@ -0,0 +1,79 @@
using Ionic.Zip;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Mono.Cecil;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Xamarin.iOS.HotRestart.Tasks {
public class UnpackFrameworks : Task {
#region Inputs
[Required]
public ITaskItem [] ReferencedAssemblies { get; set; }
[Required]
public string IntermediateOutputPath { get; set; }
#endregion
#region Outputs
[Output]
public ITaskItem [] Frameworks { get; set; }
#endregion
public override bool Execute ()
{
var frameworks = new List<ITaskItem> ();
Directory.CreateDirectory (Path.Combine (IntermediateOutputPath, "Frameworks"));
foreach (var assemblyPath in ReferencedAssemblies.Distinct ().Where (x => !IsFrameworkItem (x))) {
var assembly = AssemblyDefinition.ReadAssembly (assemblyPath.ItemSpec);
// We should only get the embedded resources that ends with .framework
var embeddedFrameworks = assembly.MainModule.Resources.Where (x => Path.GetExtension (x.Name) == ".framework");
foreach (var resource in embeddedFrameworks) {
var embeddedFramework = resource as EmbeddedResource;
if (embeddedFramework == null)
continue;
var frameworkPath = Path.Combine (IntermediateOutputPath, "Frameworks", embeddedFramework.Name);
var frameworkZipPath = frameworkPath + ".zip";
// The frameworks are embedded as zip files
using (var fileStream = File.OpenWrite (frameworkZipPath)) {
embeddedFramework.GetResourceStream ().CopyTo (fileStream);
}
// Unzip the framework
using (var zipFile = ZipFile.Read (frameworkZipPath)) {
zipFile.ExtractAll (frameworkPath, ExtractExistingFileAction.OverwriteSilently);
}
File.Delete (frameworkZipPath);
var taskItem = new TaskItem (frameworkPath);
frameworks.Add (taskItem);
}
}
Frameworks = frameworks.ToArray ();
return true;
}
bool IsFrameworkItem (ITaskItem item)
{
return (bool.TryParse (item.GetMetadata ("FrameworkFile"), out var isFrameworkFile) && isFrameworkFile) ||
item.GetMetadata ("ResolvedFrom") == "{TargetFrameworkDirectory}" ||
item.GetMetadata ("ResolvedFrom") == "ImplicitlyExpandDesignTimeFacades";
}
}
}

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

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!-- Use single-project MSBuild properties to generate the application manifest by default -->
<GenerateApplicationManifest Condition="'$(GenerateApplicationManifest)' == ''">true</GenerateApplicationManifest>
<HotRestartSignedAppOutputDir>$(TEMP)\Xamarin\HotRestart\Signing\$(_AppBundleName)$(AppBundleExtension)\out\</HotRestartSignedAppOutputDir>
<HotRestartPayloadDir>$(HotRestartSignedAppOutputDir)Payload\</HotRestartPayloadDir>
<HotRestartSignedAppDir>$(HotRestartPayloadDir)$(_AppBundleName).app\</HotRestartSignedAppDir>
<HotRestartContentDir>$(HotRestartSignedAppOutputDir)$(_AppBundleName).content\</HotRestartContentDir>
<HotRestartAppContentDir>$(HotRestartSignedAppDir)$(_AppBundleName).content\</HotRestartAppContentDir>
<HotRestartContentStampDir>$(HotRestartSignedAppOutputDir)$(_AppBundleName).stamp\</HotRestartContentStampDir>
<HotRestartIPAPath>$(HotRestartSignedAppOutputDir)$(_AppBundleName).ipa</HotRestartIPAPath>
<UnpackHotRestartFrameworks Condition="'$(UnpackHotRestartFrameworks)' == ''">true</UnpackHotRestartFrameworks>
<_IsHotRestartDefined>$([System.Text.RegularExpressions.Regex]::IsMatch('$(DefineConstants.Trim())', '(^|;)HOTRESTART($|;)'))</_IsHotRestartDefined>
<DefineConstants Condition="!$(_IsHotRestartDefined) And '$(IsHotRestartBuild)' == 'true'">HOTRESTART;$(DefineConstants)</DefineConstants>
</PropertyGroup>
</Project>

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

@ -0,0 +1,340 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="Xamarin.iOS.Tasks.CompileEntitlements" AssemblyFile="Xamarin.iOS.Tasks.dll" />
<UsingTask TaskName="Xamarin.iOS.Tasks.UnpackLibraryResources" AssemblyFile="Xamarin.iOS.Tasks.dll" />
<UsingTask TaskName="Xamarin.iOS.HotRestart.Tasks.Codesign" AssemblyFile="Xamarin.iOS.Tasks.Windows.dll" />
<UsingTask TaskName="Xamarin.iOS.HotRestart.Tasks.CollectDynamicFrameworks" AssemblyFile="Xamarin.iOS.Tasks.Windows.dll" />
<UsingTask TaskName="Xamarin.iOS.HotRestart.Tasks.CompileAppManifest" AssemblyFile="Xamarin.iOS.Tasks.Windows.dll" />
<UsingTask TaskName="Xamarin.iOS.HotRestart.Tasks.DetectSigningIdentity" AssemblyFile="Xamarin.iOS.Tasks.Windows.dll" />
<UsingTask TaskName="Xamarin.iOS.HotRestart.Tasks.PrepareAppBundle" AssemblyFile="Xamarin.iOS.Tasks.Windows.dll" />
<UsingTask TaskName="Xamarin.iOS.HotRestart.Tasks.UnpackFrameworks" AssemblyFile="Xamarin.iOS.Tasks.Windows.dll" />
<Import Project="Xamarin.iOS.HotRestart.props" />
<Import Project="$(MSBuildThisFileDirectory)Xamarin.Messaging.Build.targets" Condition="Exists('$(MSBuildThisFileDirectory)Xamarin.Messaging.Build.targets') And '$(MessagingBuildTargetsImported)' != 'true'" />
<Import Project="$(MSBuildThisFileDirectory)Xamarin.Messaging.Apple.targets" Condition="Exists('$(MSBuildThisFileDirectory)Xamarin.Messaging.Apple.targets') And '$(MessagingAppleTargetsImported)' != 'true'" />
<Target Name="_DetectHotRestartSigningIdentity" AfterTargets="_DetectAppManifest"
Condition="'$(_CanOutputAppBundle)' == 'true' And '$(IsHotRestartBuild)' == 'true' And '$(IsHotRestartEnvironmentReady)' == 'true'" >
<HotRestart.Tasks.DetectSigningIdentity
GenerateApplicationManifest="$(GenerateApplicationManifest)"
ApplicationId="$(ApplicationId)"
ApplicationTitle="$(ApplicationTitle)"
AppManifest="$(_AppManifest)"
ProvisioningProfile="$(CodesignProvision)"
SigningKey="$(CodesignKey)">
<Output TaskParameter="DetectedAppId" PropertyName="_AppIdentifier" />
<Output TaskParameter="DetectedBundleId" PropertyName="_BundleIdentifier" />
<Output TaskParameter="DetectedAppDisplayName" PropertyName="_AppDisplayName" />
<Output TaskParameter="DetectedCodeSigningPath" PropertyName="_CodeSigningPath" />
<Output TaskParameter="DetectedProvisioningProfileId" PropertyName="_ProvisioningProfileId" />
<Output TaskParameter="DetectedProvisioningProfilePath" PropertyName="_ProvisioningProfilePath" />
</HotRestart.Tasks.DetectSigningIdentity>
</Target>
<Target Name="_CollectHotRestartBundleResources" Condition="'$(IsHotRestartBuild)' == 'true'">
<CollectBundleResources
OptimizePropertyLists="$(OptimizePropertyLists)"
OptimizePNGs="$(OptimizePNGs)"
BundleResources="@(Content);@(BundleResource)"
ProjectDir="$(MSBuildProjectDirectory)"
ResourcePrefix="$(IPhoneResourcePrefix)">
<Output TaskParameter="BundleResourcesWithLogicalNames" ItemName="_HotRestartBundleResourceWithLogicalName"/>
</CollectBundleResources>
</Target>
<Target Name="_UnpackHotRestartLibraryResources" DependsOnTargets="_CollectHotRestartBundleResources"
Condition="'$(_CanOutputAppBundle)' == 'true' And '$(IsHotRestartBuild)' == 'true'" >
<UnpackLibraryResources
Prefix="monotouch"
NoOverwrite="@(_HotRestartBundleResourceWithLogicalName)"
IntermediateOutputPath="$(DeviceSpecificIntermediateOutputPath)"
TargetFrameworkDirectory="$(TargetFrameworkDirectory)"
ReferencedLibraries="@(ReferencePath);@(ReferenceDependencyPaths);@(_ReferencesFromNuGetPackages)">
<Output TaskParameter="BundleResourcesWithLogicalNames" ItemName="_HotRestartBundleResourceWithLogicalName" />
</UnpackLibraryResources>
</Target>
<!-- Gets the list of assemblies that may contain frameworks -->
<Target Name="_CollectHotRestartFrameworkAssemblies" Condition="'$(_CanOutputAppBundle)' == 'true' And '$(IsHotRestartBuild)' == 'true'">
<ItemGroup>
<AssembliesWithFrameworks Condition="'%(Extension)' == '.dll'" Include="@(ReferenceCopyLocalPaths)" Exclude="@(ReferenceSatellitePaths)"/>
</ItemGroup>
</Target>
<Target Name="_UnpackHotRestartFrameworkAssemblies"
Condition="'$(_CanOutputAppBundle)' == 'true' And '$(IsHotRestartBuild)' == 'true' And '$(UnpackHotRestartFrameworks)' == 'true'"
Inputs="@(AssembliesWithFrameworks)"
Outputs="@(AssembliesWithFrameworks -> '$(DeviceSpecificIntermediateOutputPath)UnpackedFrameworks\%(Filename)%(Extension).stamp')" >
<UnpackFrameworks
ReferencedAssemblies="@(AssembliesWithFrameworks)"
IntermediateOutputPath="$(DeviceSpecificIntermediateOutputPath)">
<Output TaskParameter="Frameworks" ItemName="_UnpackedFramework" />
</UnpackFrameworks>
<MakeDir Directories="$(DeviceSpecificIntermediateOutputPath)UnpackedFrameworks"/>
<Touch AlwaysCreate="true" Files="@(AssembliesWithFrameworks -> '$(DeviceSpecificIntermediateOutputPath)UnpackedFrameworks\%(Filename)%(Extension).stamp')" >
<Output TaskParameter="TouchedFiles" ItemName="FileWrites" />
</Touch>
</Target>
<Target Name="_CollectHotRestartFrameworks" >
<ItemGroup>
<_HotRestartFrameworks Include="@(None -> '%(RootDir)%(Directory)')" Condition="$([System.String]::new('%(Directory)').EndsWith('.framework\'))" KeepDuplicates="false" />
<_HotRestartFrameworks Include="@(_UnpackedFramework);@(NativeReference)" KeepDuplicates="false" />
<_HotRestartFrameworkExecutables Include="@(_HotRestartFrameworks -> '%(FullPath)\%(Filename)')"
Outputs="$(DeviceSpecificIntermediateOutputPath)DynamicFrameworks\%(Filename)%(Extension).stamp" KeepDuplicates="false" />
</ItemGroup>
</Target>
<PropertyGroup>
<_CollectHotRestartDynamicFrameworksDependsOn>
_CollectHotRestartFrameworkAssemblies;
_UnpackHotRestartFrameworkAssemblies;
_CollectHotRestartFrameworks;
</_CollectHotRestartDynamicFrameworksDependsOn>
</PropertyGroup>
<Target Name="_CollectHotRestartDynamicFrameworks" DependsOnTargets="$(_CollectHotRestartDynamicFrameworksDependsOn)"
Condition="'$(_CanOutputAppBundle)' == 'true' And '$(IsHotRestartBuild)' == 'true'"
Inputs="@(_HotRestartFrameworkExecutables)"
Outputs="@(_HotRestartFrameworkExecutables -> '%(Outputs)')" >
<CollectDynamicFrameworks
Frameworks="@(_HotRestartFrameworks)" >
<Output TaskParameter="DynamicFrameworks" ItemName="_DynamicFrameworks" />
</CollectDynamicFrameworks>
<MakeDir Directories="$(DeviceSpecificIntermediateOutputPath)DynamicFrameworks"/>
<Touch AlwaysCreate="true" Files="@(_HotRestartFrameworks -> '$(DeviceSpecificIntermediateOutputPath)DynamicFrameworks\%(Filename)%(Extension).stamp')" >
<Output TaskParameter="TouchedFiles" ItemName="FileWrites" />
</Touch>
<ItemGroup>
<_HotRestartFrameworkFiles Include="%(_DynamicFrameworks.FullPath)\**\*.*" Condition="'%(_DynamicFrameworks.FullPath)' != ''" KeepDuplicates="false" >
<FrameworkDir>%(FrameworkDir)</FrameworkDir>
</_HotRestartFrameworkFiles>
</ItemGroup>
</Target>
<PropertyGroup>
<_CreateHotRestartCachedBundleDependsOn>
_PrepareHotRestartAppBundle;
_CompileHotRestartAppManifest;
_CompileHotRestartEntitlements;
</_CreateHotRestartCachedBundleDependsOn>
</PropertyGroup>
<Target Name="_CreateHotRestartCachedBundle" DependsOnTargets="$(_CreateHotRestartCachedBundleDependsOn)" />
<!-- Creates HotRestart app bundle and collects files to copy -->
<Target Name="_PrepareHotRestartAppBundle" DependsOnTargets="_GenerateBuildSessionId"
Condition="'$(_CanOutputAppBundle)' == 'true' And '$(IsAppExtension)' == 'false' And '$(IsHotRestartBuild)' == 'true'">
<!--Create app bundle dir and get its path-->
<PrepareAppBundle
AppBundleName="$(_AppBundleName)"
SessionId="$(BuildSessionId)"
ShouldExtract="true">
<Output TaskParameter="AppBundlePath" PropertyName="HotRestartAppBundlePath" />
</PrepareAppBundle>
<!-- Delete the build signature to force XMA do a full build next time -->
<Delete Files="$(BuildSignatureFile)" Condition="Exists('$(BuildSignatureFile)')" />
<ItemGroup>
<_FilesToHotRestartBundle Include="$(HotRestartAppBundlePath)\Extracted" />
<_FilesToHotRestartContent Include="@(MainAssembly);" >
<DestinationSubDirectory></DestinationSubDirectory>
</_FilesToHotRestartContent>
<_FilesToHotRestartContent Include="@(_FilesToHotRestartContent -> '%(RootDir)%(Directory)%(Filename).pdb')"
Condition="Exists('%(RootDir)%(Directory)%(Filename).pdb')" />
<!-- TODO: We stopped filtering assemblies until we fix the net6 build -->
<!-- <_FilesToHotRestartContent Include="@(ReferenceCopyLocalPaths -> Distinct())" Condition="Exists('$(HotRestartAppBundlePath)\%(Filename)%(Extension)') == 'false'"/> -->
<_FilesToHotRestartContent Include="@(ReferenceCopyLocalPaths -> Distinct())"/>
</ItemGroup>
</Target>
<Target Name="_CompileHotRestartAppManifest"
Condition="'$(_CanOutputAppBundle)' == 'true' And '$(IsHotRestartBuild)' == 'true'"
Inputs="$(_AppManifest);$(HotRestartAppBundlePath)\Extracted"
Outputs="$(HotRestartSignedAppDir)$(_AppManifest);$(HotRestartSignedAppDir)Extracted">
<HotRestart.Tasks.CompileAppManifest
AppBundlePath="$(HotRestartAppBundlePath)"
AppManifestPath="$(_AppManifest)" />
</Target>
<Target Name="_CompileHotRestartEntitlements"
Condition="'$(_CanOutputAppBundle)' == 'true' And '$(IsHotRestartBuild)' == 'true'"
Inputs="$(CodesignEntitlements);$(_ProvisioningProfilePath);$(HotRestartAppBundlePath)\Extracted"
Outputs="$(HotRestartSignedAppDir)archived-expanded-entitlements.xcent;$(HotRestartSignedAppDir)Extracted">
<CompileEntitlements
AppBundleDir="$(HotRestartAppBundlePath)"
AppIdentifier="$(_AppIdentifier)"
BundleIdentifier="$(_BundleIdentifier)"
Entitlements="$(CodesignEntitlements)"
CompiledEntitlements="$(DeviceSpecificIntermediateOutputPath)Entitlements.xcent"
IsAppExtension="$(IsAppExtension)"
ProvisioningProfile="$(_ProvisioningProfileId)"
SdkIsSimulator="False"
SdkPlatform="iPhoneOS"
SdkVersion="12.2"
SdkDevPath=" "
TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)" />
</Target>
<Target Name="_CopyFilesToHotRestartBundle"
Condition="'$(_CanOutputAppBundle)' == 'true' And '$(IsAppExtension)' == 'false' And '$(IsHotRestartBuild)' == 'true'"
DependsOnTargets="_CreateHotRestartCachedBundle;_UnpackHotRestartLibraryResources"
Inputs="@(_HotRestartBundleResourceWithLogicalName);@(_FilesToHotRestartBundle)"
Outputs="@(_HotRestartBundleResourceWithLogicalName -> '$(HotRestartSignedAppDir)%(LogicalName)');
@(_FilesToHotRestartBundle -> '$(HotRestartSignedAppDir)%(Filename)%(Extension)')">
<!-- Copy Bundle resources -->
<Copy SourceFiles="@(_HotRestartBundleResourceWithLogicalName)"
DestinationFiles="@(_HotRestartBundleResourceWithLogicalName -> '$(HotRestartSignedAppDir)\%(LogicalName)')"
SkipUnchangedFiles="true"
Condition="'@(_HotRestartBundleResourceWithLogicalName)' != ''">
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
</Copy>
<Copy SourceFiles="@(_FilesToHotRestartBundle)"
DestinationFiles="@(_FilesToHotRestartBundle -> '$(HotRestartSignedAppDir)\%(Filename)%(Extension)')"
SkipUnchangedFiles="true"
Condition="'@(_FilesToHotRestartBundle)' != ''">
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
</Copy>
<MakeDir Directories="$(HotRestartContentStampDir)"/>
<Touch AlwaysCreate="true" Files="$(HotRestartContentStampDir)$(_AppBundleName).stamp" />
</Target>
<Target Name="_CopyFilesToHotRestartContent"
Condition="'$(_CanOutputAppBundle)' == 'true' And '$(IsAppExtension)' == 'false' And '$(IsHotRestartBuild)' == 'true'"
DependsOnTargets="_CreateHotRestartCachedBundle"
Inputs="@(_FilesToHotRestartContent)"
Outputs="@(_FilesToHotRestartContent -> '$(HotRestartContentDir)%(DestinationSubDirectory)%(FileName)%(Extension)');
@(_FilesToHotRestartContent -> '$(HotRestartAppContentDir)%(DestinationSubDirectory)%(FileName)%(Extension)')">
<MakeDir Directories="$(HotRestartContentDir)"/>
<MakeDir Directories="$(HotRestartAppContentDir)"/>
<!-- Copy assemblies and debug symbols into incremental Content folder -->
<Copy SourceFiles="@(_FilesToHotRestartContent)"
DestinationFiles="@(_FilesToHotRestartContent -> '$(HotRestartContentDir)%(DestinationSubDirectory)%(FileName)%(Extension)')"
SkipUnchangedFiles="true"
Condition="'@(_FilesToHotRestartContent)' != ''">
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
</Copy>
<!-- Copy assemblies and debug symbols into app bundle's content folder -->
<Copy SourceFiles="@(_FilesToHotRestartContent)"
DestinationFiles="@(_FilesToHotRestartContent -> '$(HotRestartAppContentDir)%(DestinationSubDirectory)%(FileName)%(Extension)')"
SkipUnchangedFiles="true"
Condition="'@(_FilesToHotRestartContent)' != ''">
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
</Copy>
<MakeDir Directories="$(HotRestartContentStampDir)"/>
<MakeDir Directories="@(_FilesToHotRestartContent -> '$(HotRestartContentStampDir)%(DestinationSubDirectory)')"/>
<Touch AlwaysCreate="true" Files="@(_FilesToHotRestartContent -> '$(HotRestartContentStampDir)%(DestinationSubDirectory)%(FileName)%(Extension).stamp')" />
<Touch AlwaysCreate="true" Files="@(_FilesToHotRestartContent -> '$(HotRestartContentStampDir)$(AssemblyName).hotrestartapp.stamp')" />
<Touch AlwaysCreate="true" Files="@(_FilesToHotRestartContent -> '$(HotRestartContentDir)$(AssemblyName).hotrestartapp')" />
<Touch AlwaysCreate="true" Files="@(_FilesToHotRestartContent -> '$(HotRestartAppContentDir)$(AssemblyName).hotrestartapp')" />
</Target>
<Target Name="_CopyFrameworksToHotRestartBundle"
Condition="'$(_CanOutputAppBundle)' == 'true' And '$(IsAppExtension)' == 'false' And '$(IsHotRestartBuild)' == 'true'"
DependsOnTargets="_CreateHotRestartCachedBundle;_CollectHotRestartDynamicFrameworks"
Inputs="@(_HotRestartFrameworkFiles)"
Outputs="@(_HotRestartFrameworkFiles -> '$(HotRestartSignedAppDir)Frameworks\%(FrameworkDir)%(RecursiveDir)%(Filename)%(Extension)')">
<!-- Copy frameworks -->
<Copy SourceFiles="@(_HotRestartFrameworkFiles)"
DestinationFiles="@(_HotRestartFrameworkFiles -> '$(HotRestartAppBundlePath)\Frameworks\%(FrameworkDir)%(RecursiveDir)%(Filename)%(Extension)')"
SkipUnchangedFiles="true"
Condition="'@(_HotRestartFrameworkFiles)' != ''">
<Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
</Copy>
</Target>
<Target Name="_CollectCodeSignHotRestartInputs">
<ItemGroup>
<_CodeSignHotRestartInputs Include="$(_AppManifest)" Outputs="$(HotRestartSignedAppDir)$(_AppManifest)" />
<_CodeSignHotRestartInputs Include="$(CodesignEntitlements)" Outputs="$(HotRestartSignedAppDir)$(CodesignEntitlements)" />
<_CodeSignHotRestartInputs Include="$(_ProvisioningProfilePath)" Outputs="$(HotRestartSignedAppDir)embedded.mobileprovision" />
<_CodeSignHotRestartInputs Include="@(_HotRestartFrameworkFiles)" Outputs="$(HotRestartAppBundlePath)\Frameworks\%(_HotRestartFrameworkFiles.FrameworkDir)%(RecursiveDir)%(Filename)%(Extension)" />
<_CodeSignHotRestartInputs Include="$(HotRestartAppBundlePath)\Extracted" Outputs="$(HotRestartSignedAppDir)Extracted" />
</ItemGroup>
</Target>
<PropertyGroup>
<_CreateHotRestartOutputBundleDependsOn>
_CodesignHotRestartAppBundle;
_CopyFilesToHotRestartBundle;
_CopyFilesToHotRestartContent;
</_CreateHotRestartOutputBundleDependsOn>
</PropertyGroup>
<Target Name="_CreateHotRestartOutputBundle" Condition="'$(IsHotRestartEnvironmentReady)' == 'true'" DependsOnTargets="$(_CreateHotRestartOutputBundleDependsOn)"
AfterTargets="_CodesignAppBundle" />
<Target Name="_CodesignHotRestartAppBundle"
Condition="'$(_CanOutputAppBundle)' == 'true' And '$(IsAppExtension)' == 'false' And '$(IsHotRestartBuild)' == 'true'"
DependsOnTargets="_CreateHotRestartCachedBundle;_CopyFrameworksToHotRestartBundle;_CollectCodeSignHotRestartInputs"
Inputs="@(_CodeSignHotRestartInputs)"
Outputs="@(_CodeSignHotRestartInputs -> '%(Outputs)')">
<HotRestart.Tasks.Codesign
AppBundlePath="$(HotRestartAppBundlePath)"
BundleIdentifier="$(_BundleIdentifier)"
CodeSigningPath="$(_CodeSigningPath)"
ProvisioningProfilePath="$(_ProvisioningProfilePath)" />
</Target>
<PropertyGroup>
<CleanDependsOn>
$(CleanDependsOn);
_CleanHotRestartBundle
</CleanDependsOn>
</PropertyGroup>
<Target Name="_CleanHotRestartBundle" DependsOnTargets="_GenerateBuildSessionId" >
<!-- Gets the bundle path -->
<PrepareAppBundle
Condition="'$(IsHotRestartBuild)' == 'true'"
AppBundleName="$(_AppBundleName)"
SessionId="$(BuildSessionId)"
ShouldExtract="false">
<Output TaskParameter="AppBundlePath" PropertyName="HotRestartAppBundlePath" />
</PrepareAppBundle>
<RemoveDir Directories="$(HotRestartAppBundlePath)" />
<RemoveDir Directories="$(HotRestartSignedAppOutputDir)" />
<RemoveDir Directories="$(DeviceSpecificIntermediateOutputPath)UnpackedFrameworks" />
<RemoveDir Directories="$(DeviceSpecificIntermediateOutputPath)DynamicFrameworks" />
</Target>
</Project>

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

@ -4,12 +4,15 @@
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<MergeSystemAssemblies>false</MergeSystemAssemblies>
<RuntimeIdentifier>win</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DotNetZip" Version="1.14.0" />
<PackageReference Include="Mono.Cecil" Version="0.11.4" />
<PackageReference Include="Xamarin.Messaging.Build.Client" Version="$(MessagingVersion)" IncludeAssets="contentFiles" />
<PackageReference Include="Xamarin.Messaging.Core" Version="$(MessagingVersion)" IncludeAssets="build" />
<PackageReference Include="Xamarin.Messaging.Server" Version="$(MessagingVersion)" IncludeAssets="contentFiles" />
<PackageReference Include="Xamarin.iOS.HotRestart.Client" Version="$(HotRestartVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Messaging\Xamarin.Messaging.Build\Xamarin.Messaging.Build.csproj">
@ -17,6 +20,7 @@
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
<IsAgent>True</IsAgent>
</ProjectReference>
<ProjectReference Include="..\..\external\Xamarin.MacDev\Xamarin.MacDev\Xamarin.MacDev.csproj" />
</ItemGroup>
<ItemGroup>
<None Include="*.props">
@ -25,6 +29,10 @@
<None Include="*.targets">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\..\external\macios-binaries\HotRestart\Xamarin.PreBuilt.iOS.app.zip">
<Link>Xamarin.PreBuilt.iOS.app.zip</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="Tasks\" />
@ -47,18 +55,16 @@
<Target Name="CopyRuntimeAssemblies" BeforeTargets="ILRepack">
<ItemGroup>
<ReferenceCopyLocalToRemove Include="@(ReferenceCopyLocalPaths)" Condition="'%(FileName)' == 'System.Text.Encoding.CodePages'" />
<ReferenceCopyLocalPaths Remove="@(ReferenceCopyLocalToRemove)" />
<ReferencePathToRemove Include="@(ReferencePath)" Condition="'%(FileName)' == 'System.Text.Encoding.CodePages'" />
<ReferencePath Remove="@(ReferencePathToRemove)" />
<ReferencePathToAdd Include="@(RuntimeTargetsCopyLocalItems)" Condition="'%(RuntimeIdentifier)' == 'win' And '%(FileName)' == 'System.Text.Encoding.CodePages'" />
<ReferencePath Include="@(ReferencePathToAdd)">
<DestinationSubDirectory />
</ReferencePath>
<ReferenceToPreserve Include="@(ReferencePath)" Condition="'%(FileName)' == 'System.Diagnostics.Tracer'" />
<ReferenceToPreserve Include="@(ReferencePath)" Condition="'%(FileName)' == 'System.Security.Cryptography.ProtectedData'" />
<ReferenceToPreserve Include="@(ReferencePath)" Condition="'%(FileName)' == 'System.Security.Cryptography.Pkcs'" />
</ItemGroup>
</Target>
</Project>

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

@ -27,5 +27,5 @@ Copyright (C) 2011-2013 Xamarin. All rights reserved.
<RemoveDir SessionId="$(BuildSessionId)" Condition="'$(MtouchTargetsEnabled)' == 'true'" Directories="$(OutputPath);$(IntermediateOutputPath)" RemoveAppDir="$(RemoveAppDir)" ContinueOnError="true" />
</Target>
<Import Project="$(MSBuildThisFileDirectory)Xamarin.iOS.Local.targets" Condition="Exists('$(MSBuildThisFileDirectory)Xamarin.iOS.Local.targets')" />
<Import Project="$(MSBuildThisFileDirectory)Xamarin.iOS.HotRestart.targets" Condition="Exists('$(MSBuildThisFileDirectory)Xamarin.iOS.HotRestart.targets')" />
</Project>