[msbuild] Set NSAllowArbitraryLoads when debugging watchOS apps. (#746)

* [msbuild] Move detection of network configuration to a separate task.

* [msbuild] Set NSAllowArbitraryLoads when debugging watchOS apps.

The only way to have reliable http connections from the watchOS 2 device
to the mac is to set NSAllowArbitraryLoads.

See also: https://forums.developer.apple.com/thread/6205
This commit is contained in:
Rolf Bjarne Kvinge 2016-09-02 14:30:15 +02:00 коммит произвёл Sebastien Pouliot
Родитель 1a064bcc8d
Коммит f2c4c191c6
8 изменённых файлов: 160 добавлений и 42 удалений

2
external/Xamarin.MacDev поставляемый

@ -1 +1 @@
Subproject commit 248017c6c95b205f6bdfbfec77fca98254fe7cf0
Subproject commit a71513695b0357b30c903039cd16bd1cd8609d0c

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

@ -31,6 +31,11 @@ namespace Xamarin.iOS.Tasks
[Required]
public string TargetFrameworkIdentifier { get; set; }
[Required]
public bool Debug { get; set; }
public string DebugIPAddresses { get; set; }
public string ResourceRules { get; set; }
public PlatformFramework Framework {
@ -54,6 +59,8 @@ namespace Xamarin.iOS.Tasks
Log.LogTaskProperty ("Architecture", Architecture);
Log.LogTaskProperty ("AssemblyName", AssemblyName);
Log.LogTaskProperty ("BundleIdentifier", BundleIdentifier);
Log.LogTaskProperty ("Debug", Debug);
Log.LogTaskProperty ("DebugIPAddresses", DebugIPAddresses);
Log.LogTaskProperty ("DefaultSdkVersion", DefaultSdkVersion);
Log.LogTaskProperty ("IsAppExtension", IsAppExtension);
Log.LogTaskProperty ("IsWatchApp", IsWatchApp);
@ -177,6 +184,9 @@ namespace Xamarin.iOS.Tasks
plist.SetIfNotPresent (ManifestKeys.MinimumOSVersion, minimumOSVersion.ToString ());
if (IsWatchExtension && Debug)
SetAppTransportSecurity (plist);
// Remove any Xamarin Studio specific keys
plist.Remove (ManifestKeys.XSLaunchImageAssets);
plist.Remove (ManifestKeys.XSAppIconAssets);
@ -225,6 +235,33 @@ namespace Xamarin.iOS.Tasks
}
}
void SetAppTransportSecurity (PDictionary plist)
{
// Debugging over http has a couple of gotchas:
// * We can't use https, because that requires a valid server certificate,
// which we can't ensure.
// It would also require a hostname for the mac, which it might not have either.
// * NSAppTransportSecurity/NSExceptionDomains does not allow exceptions based
// on IP address (only hostname).
// * Which means the only way to make sure watchOS allows connections from
// the app on device to the mac is to disable App Transport Security altogether.
// Good news: watchOS 3 will apparently not apply ATS when connecting
// directly to IP addresses, which means we won't have to do this at all
// (sometime in the future).
PDictionary ats;
if (!plist.TryGetValue (ManifestKeys.NSAppTransportSecurity, out ats))
plist.Add (ManifestKeys.NSAppTransportSecurity, ats = new PDictionary ());
if (ats.GetBoolean (ManifestKeys.NSAllowsArbitraryLoads)) {
Log.LogMessage (MessageImportance.Low, "All http loads are already allowed.");
} else {
Log.LogMessage (MessageImportance.Low, "Allowed arbitrary HTTP loads to support debugging.");
ats.SetBooleanOrRemove (ManifestKeys.NSAllowsArbitraryLoads, true);
}
}
void Validation (PDictionary plist)
{
var supportsIPhone = (supportedDevices & IPhoneDeviceType.IPhone) != 0

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

@ -22,7 +22,7 @@ namespace Xamarin.iOS.Tasks
[Required]
public bool DebugOverWiFi { get; set; }
public string DebuggerHosts { get; set; }
public string DebugIPAddresses { get; set; }
[Required]
public string DebuggerPort { get; set; }
@ -35,57 +35,30 @@ namespace Xamarin.iOS.Tasks
public override bool Execute ()
{
var path = Path.Combine (AppBundleDir, "MonoTouchDebugConfiguration.txt");
var ips = new List<IPAddress> ();
Log.LogTaskName ("CreateDebugConfiguration");
Log.LogTaskProperty ("AppBundleDir", AppBundleDir);
Log.LogTaskProperty ("DebugOverWiFi", DebugOverWiFi);
Log.LogTaskProperty ("DebuggerHosts", DebuggerHosts);
Log.LogTaskProperty ("DebugIPAddresses", DebugIPAddresses);
Log.LogTaskProperty ("DebuggerPort", DebuggerPort);
Log.LogTaskProperty ("SdkIsSimulator", SdkIsSimulator);
if (SdkIsSimulator) {
ips.Add (IPAddress.Loopback);
} else if (DebugOverWiFi) {
string[] hosts = null;
if (!string.IsNullOrEmpty (DebuggerHosts))
hosts = DebuggerHosts.Split (new [] { ';' }, StringSplitOptions.RemoveEmptyEntries);
if (hosts == null || hosts.Length == 0) {
try {
ips.AddRange (Dns.GetHostEntry (Dns.GetHostName ()).AddressList);
} catch {
Log.LogError ("Could not resolve host IPs for WiFi debugger settings");
return false;
}
} else {
foreach (var host in hosts) {
IPAddress ip;
if (IPAddress.TryParse (host, out ip))
ips.Add (ip);
}
}
if (ips == null || ips.Count == 0) {
Log.LogError ("This machine does not have any network adapters. This is required when debugging or profiling on device over WiFi.");
return false;
}
}
var ips = DebugIPAddresses?.Split (new char [] { ';' }, StringSplitOptions.RemoveEmptyEntries);
try {
using (var stream = new FileStream (path, FileMode.Create, FileAccess.Write)) {
using (var writer = new StreamWriter (stream)) {
var added = new HashSet<string> ();
foreach (var ip in ips) {
string str = ip.ToString ();
if (ips != null) {
foreach (var ip in ips) {
string str = ip.ToString ();
if (added.Contains (str))
continue;
if (added.Contains (str))
continue;
writer.WriteLine ("IP: {0}", str);
added.Add (str);
writer.WriteLine ("IP: {0}", str);
added.Add (str);
}
}
if (!DebugOverWiFi && !SdkIsSimulator)

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

@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Xamarin.MacDev.Tasks;
using Xamarin.MacDev;
namespace Xamarin.iOS.Tasks
{
public abstract class DetectDebugNetworkConfigurationBase : Task
{
#region Inputs
public string SessionId { get; set; }
[Required]
public bool DebugOverWiFi { get; set; }
public string DebuggerHosts { get; set; }
[Required]
public bool SdkIsSimulator { get; set; }
#endregion
#region Outputs
[Output]
public string DebugIPAddresses { get; set; }
#endregion
public override bool Execute ()
{
Log.LogTaskName ("DetectDebugNetworkConfiguration");
Log.LogTaskProperty ("DebugOverWiFi", DebugOverWiFi);
Log.LogTaskProperty ("DebuggerHosts", DebuggerHosts);
Log.LogTaskProperty ("SdkIsSimulator", SdkIsSimulator);
var ips = new List<string> ();
if (SdkIsSimulator) {
ips.Add (IPAddress.Loopback.ToString ());
} else if (DebugOverWiFi) {
string [] hosts = null;
if (!string.IsNullOrEmpty (DebuggerHosts))
hosts = DebuggerHosts.Split (new [] { ';' }, StringSplitOptions.RemoveEmptyEntries);
if (hosts == null || hosts.Length == 0) {
try {
ips.AddRange (Dns.GetHostEntry (Dns.GetHostName ()).AddressList.Select ((v) => v.ToString ()));
} catch {
Log.LogError ("Could not resolve host IPs for WiFi debugger settings");
return false;
}
} else {
foreach (var host in hosts) {
IPAddress ip;
if (IPAddress.TryParse (host, out ip))
ips.Add (ip.ToString ());
}
}
if (ips == null || ips.Count == 0) {
Log.LogError ("This machine does not have any network adapters. This is required when debugging or profiling on device over WiFi.");
return false;
}
}
DebugIPAddresses = string.Join (";", ips.ToArray ());
Log.LogTaskProperty ("DebugIPAddresses", DebugIPAddresses);
return !Log.HasLoggedErrors;
}
}
}

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

@ -51,6 +51,7 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved.
<UsingTask TaskName="Xamarin.iOS.Tasks.CreateDebugSettings" AssemblyFile="Xamarin.iOS.Tasks.dll" />
<UsingTask TaskName="Xamarin.iOS.Tasks.CreateDebugConfiguration" AssemblyFile="Xamarin.iOS.Tasks.dll" />
<UsingTask TaskName="Xamarin.iOS.Tasks.DetectBundleIdentifier" AssemblyFile="Xamarin.iOS.Tasks.dll" />
<UsingTask TaskName="Xamarin.iOS.Tasks.DetectDebugNetworkConfiguration" AssemblyFile="Xamarin.iOS.Tasks.dll" />
<UsingTask TaskName="Xamarin.iOS.Tasks.DetectSdkLocations" AssemblyFile="Xamarin.iOS.Tasks.dll" />
<UsingTask TaskName="Xamarin.iOS.Tasks.DetectSigningIdentity" AssemblyFile="Xamarin.iOS.Tasks.dll" />
<UsingTask TaskName="Xamarin.iOS.Tasks.EmbedMobileProvision" AssemblyFile="Xamarin.iOS.Tasks.dll" />
@ -594,7 +595,7 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved.
</PropertyGroup>
<Target Name="_CompileAppManifest"
DependsOnTargets="_DetectSdkLocations;_DetectAppManifest;_GenerateBundleName;_DetectSigningIdentity;_PrepareResourceRules;_ResolveWatchAppReferences"
DependsOnTargets="_DetectSdkLocations;_DetectAppManifest;_GenerateBundleName;_DetectSigningIdentity;_PrepareResourceRules;_ResolveWatchAppReferences;_DetectDebugNetworkConfiguration"
Inputs="$(_AppManifest);@(_PartialAppManifest)"
Outputs="$(_AppBundlePath)Info.plist" >
<CompileAppManifest
@ -606,6 +607,7 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved.
Architecture="$(MtouchArch)"
AssemblyName="$(AssemblyName)"
BundleIdentifier="$(_BundleIdentifier)"
Debug="$(MtouchDebug)"
DefaultSdkVersion="$(MtouchSdkVersion)"
IsAppExtension="$(IsAppExtension)"
IsWatchApp="$(IsWatchApp)"
@ -615,6 +617,7 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved.
TargetFrameworkIdentifier="$(TargetFrameworkIdentifier)"
SdkPlatform="$(_SdkPlatform)"
SdkIsSimulator="$(_SdkIsSimulator)"
DebugIPAddresses="$(_DebugIPAddresses)"
>
</CompileAppManifest>
@ -832,14 +835,14 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved.
</Target>
<Target Name="_CreateDebugConfiguration" Condition="'$(MtouchDebug)' == 'true' And '$(IsWatchApp)' == 'false'"
DependsOnTargets="_CopyResourcesToBundle"
DependsOnTargets="_CopyResourcesToBundle;_DetectDebugNetworkConfiguration"
Outputs="$(_AppBundlePath)MonoTouchDebugConfiguration.txt" >
<CreateDebugConfiguration
SessionId="$(BuildSessionId)"
Condition="'$(IsMacEnabled)' == 'true'"
AppBundleDir="$(AppBundleDir)"
DebugOverWiFi="$(IOSDebugOverWiFi)"
DebuggerHosts="$(IOSDebuggerHosts)"
DebugIPAddresses="$(_DebugIPAddresses)"
DebuggerPort="$(IOSDebuggerPort)"
SdkIsSimulator="$(_SdkIsSimulator)"
>
@ -1356,6 +1359,19 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved.
</DetectBundleIdentifier>
</Target>
<Target Name="_DetectDebugNetworkConfiguration">
<DetectDebugNetworkConfiguration
SessionId="$(BuildSessionId)"
Condition="'$(IsMacEnabled)' == 'true'"
DebugOverWiFi="$(IOSDebugOverWiFi)"
DebuggerHosts="$(IOSDebuggerHosts)"
SdkIsSimulator="$(_SdkIsSimulator)"
>
<Output TaskParameter="DebugIPAddresses" PropertyName="_DebugIPAddresses" />
</DetectDebugNetworkConfiguration>
</Target>
<Target Name="_CopyAppExtensionsToBundle" Condition="'$(IsAppExtension)' == 'false'" DependsOnTargets="_ResolveAppExtensionReferences">
<MakeDir SessionId="$(BuildSessionId)" Condition="'$(IsMacEnabled)' And '@(_ResolvedAppExtensionReferences)' != ''" Directories="$(_AppBundlePath)PlugIns" />

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

@ -88,6 +88,7 @@
<Compile Include="Tasks\CreateAssetPackTaskBase.cs" />
<Compile Include="Tasks\WriteAssetPackManifestTaskBase.cs" />
<Compile Include="Tasks\FindWatchOS2AppBundleTaskBase.cs" />
<Compile Include="Tasks\DetectDebugNetworkConfigurationTaskBase.cs" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />

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

@ -0,0 +1,6 @@
namespace Xamarin.iOS.Tasks
{
public class DetectDebugNetworkConfiguration : DetectDebugNetworkConfigurationBase
{
}
}

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

@ -70,6 +70,7 @@
<Compile Include="Tasks\CreateAssetPack.cs" />
<Compile Include="Tasks\WriteAssetPackManifest.cs" />
<Compile Include="Tasks\FindWatchOS2AppBundle.cs" />
<Compile Include="Tasks\DetectDebugNetworkConfiguration.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Xamarin.iOS.Tasks.Core\Xamarin.iOS.Tasks.Core.csproj">