Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[msbuild] Stop supporting watchOS 1 apps. #9542

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Make.config
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ MIN_IOS_SDK_VERSION=7.0
MIN_OSX_SDK_VERSION=10.9
MIN_WATCHOS_SDK_VERSION=2.0
MIN_WATCHOS64_32_SDK_VERSION=5.1
MIN_WATCH_OS_VERSION=1.0
MIN_WATCH_OS_VERSION=2.0
MIN_TVOS_SDK_VERSION=9.0

# The min simulator version available in the Xcode we're using
Expand Down
1 change: 0 additions & 1 deletion Versions-ios.plist.in
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@
</array>
<key>watchOS</key>
<array>
<string>1.0</string>
<string>2.0</string>
<string>2.1</string>
<string>2.2</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,83 +15,7 @@ Copyright (C) 2015-2016 Xamarin. All rights reserved.
-->

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="Xamarin.iOS.Tasks.ResolveNativeWatchApp" AssemblyFile="Xamarin.iOS.Tasks.dll" />

<Import Project="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).Before.targets"
Condition="Exists('$(MSBuildThisFileDirectory)$(MSBuildThisFileName).Before.targets')"/>

<PropertyGroup>
<IsWatchApp>True</IsWatchApp>
<IsWatch2App>False</IsWatch2App>
</PropertyGroup>

<Import Project="$(MSBuildThisFileDirectory)Xamarin.iOS.Common.targets" />

<Import Project="$(MSBuildThisFileDirectory)Xamarin.iOS.WatchApp.Common.props"
Condition="'$(_XamarinWatchAppCommonPropsHasBeenImported)' != 'true'" />

<Import Project="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).Before.targets"
Condition="Exists('$(MSBuildThisFileDirectory)$(MSBuildThisFileName).Before.targets')"/>

<!-- Override GetTargetPath, Build, and Rebuild -->
<Target Name="GetBundleTargetPath" DependsOnTargets="_GetWatchAppBundlePath;$(GetTargetPathDependsOn)" Outputs="@(_WatchAppBundlePath)" />
<Target Name="Build" Condition="'$(_InvalidConfigurationWarning)' != 'true'" DependsOnTargets="_GetWatchAppBundlePath;$(BuildDependsOn)" Outputs="@(_WatchAppBundlePath)" />
<Target Name="Rebuild" Condition="'$(_InvalidConfigurationWarning)' != 'true'" DependsOnTargets="_GetWatchAppBundlePath;$(RebuildDependsOn)" Outputs="@(_WatchAppBundlePath)" />

<Target Name="_ResolveNativeWatchApp" DependsOnTargets="_DetectSdkLocations;_GenerateBundleName;_ComputeTargetFrameworkMoniker">
<ResolveNativeWatchApp
Condition="'$(IsMacEnabled)' == 'true'"
SessionId="$(BuildSessionId)"
SdkVersion="$(MtouchSdkVersion)"
SdkIsSimulator="$(_SdkIsSimulator)"
TargetFrameworkMoniker="$(_ComputedTargetFrameworkMoniker)"
>
<Output TaskParameter="NativeWatchApp" PropertyName="_NativeWatchApp" />
</ResolveNativeWatchApp>
<Target Name="Build">
<Error Text="Xamarin.iOS 14+ does not support watchOS 1 apps. Please migrate your project to watchOS 2+." />
</Target>

<PropertyGroup>
<_CompileToNativeDependsOn>
$(_CompileToNativeDependsOn);
_ResolveNativeWatchApp
</_CompileToNativeDependsOn>
</PropertyGroup>

<Target Name="_CompileToNative" DependsOnTargets="$(_CompileToNativeDependsOn)" >
<Ditto
SessionId="$(BuildSessionId)"
Condition="'$(IsMacEnabled)'"
ToolExe="$(DittoExe)"
ToolPath="$(DittoPath)"
Source="$(_NativeWatchApp)"
Destination="$(_AppBundlePath)$(AssemblyName)"
/>

<!-- This task must always run, because Apple's toolchain determines if a watch app
must be installed or not depending on the timestamp of the main executable (this means
that if any other file is modified, we must at least touch the main executable as well).
-->
<Touch SessionId="$(BuildSessionId)" Condition="'$(IsMacEnabled)'" Files="$(_AppBundlePath)$(AssemblyName)"/>

<MakeDir SessionId="$(BuildSessionId)" Condition="'$(IsMacEnabled)' == 'true'" Directories="$(_AppBundlePath)_WatchKitStub" />

<Ditto
SessionId="$(BuildSessionId)"
Condition="'$(IsMacEnabled)'"
ToolExe="$(DittoExe)"
ToolPath="$(DittoPath)"
Source="$(_NativeWatchApp)"
Destination="$(_AppBundlePath)_WatchKitStub\WK"
/>

<RemoveDir SessionId="$(BuildSessionId)" Condition="'$(IsMacEnabled)' == 'true'" Directories="$(AppBundleDir).dSYM" />
</Target>

<Target Name="CopyFilesToOutputDirectory" />
<Target Name="CoreCompile" />
<Target Name="CreateIpa"/>

<Import Project="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).After.targets"
Condition="Exists('$(MSBuildThisFileDirectory)$(MSBuildThisFileName).After.targets')"/>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -11,115 +11,20 @@ namespace Xamarin.iOS.Tasks {
[TestFixture ("iPhoneSimulator")]
public class WatchKit : ExtensionTestBase {

bool isXcode10OrLater = Configuration.XcodeVersion.Major >= 10;

public WatchKit (string platform) : base(platform)
{
}

[Test]
public void BasicTest ()
{
this.BuildExtension ("MyWatchApp", "MyWatchKitExtension", Platform, "Debug", expectedErrorCount: isXcode10OrLater ? 1 : 0, additionalAsserts: (ProjectPaths mtouchPaths) =>
this.BuildExtension ("MyWatchApp", "MyWatchKitExtension", Platform, "Debug", expectedErrorCount: 1, additionalAsserts: (ProjectPaths mtouchPaths) =>
{
Assert.IsTrue (Directory.Exists (Path.Combine (mtouchPaths.AppBundlePath, "PlugIns", "MyWatchKitExtension.appex")), "appex");
Assert.IsFalse (Directory.Exists (Path.Combine (mtouchPaths.AppBundlePath, "PlugIns", "MyWatchKitExtension.appex", "Frameworks")), "frameworks");
});

if (isXcode10OrLater)
Assert.AreEqual ("Xcode 10 does not support watchOS 1 apps. Either upgrade to watchOS 2 apps, or use an older version of Xcode.", Engine.Logger.ErrorEvents[0].Message, "WK 1 error message");
}

[Test]
public void InvalidBundleIdTest ()
{
if (isXcode10OrLater)
Assert.Ignore ("WK 1 apps are not supported when running with Xcode 10+.");

var mtouchPaths = SetupProjectPaths ("MyWatchApp", platform: Platform);
using (var xiproj = XIProject.Clone (mtouchPaths.ProjectPath, "MyWatchKitExtension", "MyWatchKitApp")) {
mtouchPaths = SetupProjectPaths ("MyWatchApp", "MyWatchApp", xiproj.ProjectDirectory, platform: Platform);

var appInfoPath = Path.Combine (mtouchPaths.ProjectPath, "Info.plist");
var appInfoContents = File.ReadAllText (appInfoPath);
if (!appInfoContents.Contains ("<string>com.xamarin.MyWatchApp</string>"))
Assert.Fail ("Info.plist did not contain '<string>com.xamarin.MyWatchApp</string>'");
File.WriteAllText (appInfoPath, appInfoContents.Replace ("<string>com.xamarin.MyWatchApp</string>", "<string>com.xamarin.MyWatchAppX</string>"));

var proj = SetupProject (Engine, mtouchPaths.ProjectCSProjPath);
Engine.ProjectCollection.SetGlobalProperty ("Platform", Platform);
AppBundlePath = mtouchPaths ["app_bundlepath"];
RunTarget (proj, "Build", 2);
Assert.AreEqual ("The App Extension 'WatchExtension' has an invalid CFBundleIdentifier (com.xamarin.MyWatchApp.WatchExtension), it does not begin with the main app bundle's CFBundleIdentifier (com.xamarin.MyWatchAppX).", Engine.Logger.ErrorEvents [0].Message, "#1");
Assert.AreEqual ("The Watch App 'WatchApp' has an invalid WKCompanionAppBundleIdentifier value ('com.xamarin.MyWatchApp'), it does not match the main app bundle's CFBundleIdentifier ('com.xamarin.MyWatchAppX').", Engine.Logger.ErrorEvents [1].Message, "#2");
}
}

[Test]
public void CreateIpa ()
{
if (isXcode10OrLater)
Assert.Ignore ("WK 1 apps are not supported when running with Xcode 10+.");

if (Platform == "iPhoneSimulator")
return; // this is a device-only test.

const string hostAppName = "MyWatchApp";
// string extensionName = "MyWatchKitExtension";
const string configuration = "Release";

var mtouchPaths = SetupProjectPaths (hostAppName, "../", true, Platform, configuration);
var proj = SetupProject (Engine, mtouchPaths.ProjectCSProjPath);

AppBundlePath = mtouchPaths.AppBundlePath;

Engine.ProjectCollection.SetGlobalProperty ("Platform", Platform);
Engine.ProjectCollection.SetGlobalProperty ("BuildIpa", "true");
Engine.ProjectCollection.SetGlobalProperty ("IpaIncludeArtwork", "true");
Engine.ProjectCollection.SetGlobalProperty ("CodesignProvision", "Automatic"); // Provisioning profile
Engine.ProjectCollection.SetGlobalProperty ("CodesignKey", "iPhone Developer");
Engine.ProjectCollection.SetGlobalProperty ("Configuration", configuration);

RunTarget (proj, "Clean");
Assert.IsFalse (Directory.Exists (AppBundlePath), "{1}: App bundle exists after cleanup: {0} ", AppBundlePath, Platform);

proj = SetupProject (Engine, mtouchPaths.ProjectCSProjPath);
RunTarget (proj, "Build");

var plist = PDictionary.FromFile (Path.Combine (AppBundlePath, "Info.plist"));
Assert.IsTrue (plist.ContainsKey ("CFBundleExecutable"));
Assert.IsTrue (plist.ContainsKey ("CFBundleVersion"));
Assert.IsNotEmpty (((PString)plist["CFBundleExecutable"]).Value);
Assert.IsNotEmpty (((PString)plist["CFBundleVersion"]).Value);

var ipaPath = Path.Combine (mtouchPaths.ProjectBinPath, hostAppName + ".ipa");
var payloadPath = "Payload/";
var watchkitSupportPath = "WatchKitSupport/";

Assert.IsTrue (File.Exists (ipaPath), "IPA package does not exist: {0}", ipaPath);

var startInfo = new ProcessStartInfo ("/usr/bin/zipinfo", "-1 \"" + ipaPath + "\"");
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
var process = new Process ();
process.StartInfo = startInfo;
process.Start ();
var output = process.StandardOutput.ReadToEnd ();
process.WaitForExit ();

var lines = output.Split (new char [] { '\n' }, StringSplitOptions.RemoveEmptyEntries);

Assert.Contains (payloadPath, lines, payloadPath + " does not exist");
Assert.Contains (watchkitSupportPath, lines, watchkitSupportPath + " does not exist");

string wkPath = "WatchKitSupport/WK";
Assert.Contains (wkPath, lines, wkPath + " does not exist");

var ipaIncludeArtwork = proj.GetPropertyValue ("IpaIncludeArtwork");
Assert.IsTrue (output.Contains ("iTunesMetadata.plist"), string.Format ("The ipa should contain at least one iTunesMetadata.plist file if we are using an AppStore config and IpaIncludeArtwork is true. IpaIncludeArtwork: {0}", ipaIncludeArtwork));

RunTarget (proj, "Clean");
Assert.IsFalse (File.Exists (ipaPath), "IPA package still exists after Clean: {0}", ipaPath);
Assert.AreEqual ("Xamarin.iOS 14+ does not support watchOS 1 apps. Please migrate your project to watchOS 2+.", Engine.Logger.ErrorEvents[0].Message, "WK 1 error message");
}
}
}