-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* [mbr] Add an apple sample Works on iOS simulator and Mac Catalyst * delete unused DeltaHelper code Now that System.Reflection.Metadata.AssemblyExtensions.ApplyUpdate is in the BCL officially, I don't need the reflection-based invoke code anymore
- Loading branch information
1 parent
9089931
commit 281be9e
Showing
9 changed files
with
324 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<OutputPath>bin</OutputPath> | ||
<TargetFramework>$(NetCoreAppToolCurrent)</TargetFramework> | ||
<MicrosoftNetCoreAppRuntimePackDir>$(ArtifactsBinDir)microsoft.netcore.app.runtime.$(TargetOS.ToLower())-$(TargetArchitecture)\$(Configuration)\runtimes\$(TargetOS.ToLower())-$(TargetArchitecture)\</MicrosoftNetCoreAppRuntimePackDir> | ||
<EnableTargetingPackDownload>false</EnableTargetingPackDownload> | ||
<RuntimeIdentifier>$(TargetOS.ToLower())-$(TargetArchitecture)</RuntimeIdentifier> | ||
<DefineConstants Condition="'$(ArchiveTests)' == 'true'">$(DefineConstants);CI_TEST</DefineConstants> | ||
<MonoForceInterpreter>true</MonoForceInterpreter> | ||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<Compile Include="Program.cs" /> | ||
<Compile Include="ChangeablePart.cs" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\DeltaHelper\DeltaHelper.csproj" /> | ||
</ItemGroup> | ||
|
||
<PropertyGroup> | ||
<DeltaScript>deltascript.json</DeltaScript> | ||
<DeltaCount>1</DeltaCount> | ||
</PropertyGroup> | ||
|
||
<PropertyGroup Condition="'$(TargetOS)' == 'MacCatalyst'"> | ||
<DevTeamProvisioning Condition="'$(TargetOS)' == 'MacCatalyst' and '$(DevTeamProvisioning)' == ''">-</DevTeamProvisioning> | ||
</PropertyGroup> | ||
|
||
<!-- Redirect 'dotnet publish' to in-tree runtime pack --> | ||
<Target Name="TrickRuntimePackLocation" AfterTargets="ProcessFrameworkReferences"> | ||
<ItemGroup> | ||
<RuntimePack> | ||
<PackageDirectory>$(ArtifactsBinDir)microsoft.netcore.app.runtime.$(RuntimeIdentifier)\$(Configuration)</PackageDirectory> | ||
</RuntimePack> | ||
</ItemGroup> | ||
<Message Text="Packaged ID: %(RuntimePack.PackageDirectory)" Importance="high" /> | ||
</Target> | ||
|
||
<Import Project="$(RepoTasksDir)AotCompilerTask\MonoAOTCompiler.props" /> | ||
<UsingTask TaskName="AppleAppBuilderTask" | ||
AssemblyFile="$(AppleAppBuilderTasksAssemblyPath)" /> | ||
|
||
<Target Name="BuildAppBundle" AfterTargets="CopyFilesToPublishDirectory"> | ||
<PropertyGroup> | ||
<AppDir>$(MSBuildThisFileDirectory)$(PublishDir)\app</AppDir> | ||
<IosSimulator Condition="'$(TargetsiOSSimulator)' == 'true'">iPhone 11</IosSimulator> | ||
<Optimized Condition="'$(Configuration)' == 'Release'">True</Optimized> | ||
<RunAOTCompilation Condition="('$(TargetsMacCatalyst)' == 'false' and '$(IosSimulator)' == '') or '$(ForceAOT)' == 'true'">true</RunAOTCompilation> | ||
</PropertyGroup> | ||
|
||
<Error Condition="'$(TargetOS)' == ''" Text="The TargetOS property must be set outside the project file" /> | ||
|
||
<RemoveDir Directories="$(AppDir)" /> | ||
|
||
<ItemGroup> | ||
<BundleAssemblies Condition="'$(RunAOTCompilation)' != 'true'" Include="$(MSBuildThisFileDirectory)$(PublishDir)\*.dll" /> | ||
</ItemGroup> | ||
|
||
<AppleAppBuilderTask | ||
TargetOS="$(TargetOS)" | ||
Arch="$(TargetArchitecture)" | ||
ProjectName="AppleDelta" | ||
MonoRuntimeHeaders="$(MicrosoftNetCoreAppRuntimePackDir)native\include\mono-2.0" | ||
Assemblies="@(BundleAssemblies)" | ||
NativeMainSource="$(MSBuildThisFileDirectory)\main.m" | ||
MainLibraryFileName="AppleDelta.dll" | ||
GenerateXcodeProject="True" | ||
BuildAppBundle="True" | ||
DevTeamProvisioning="$(DevTeamProvisioning)" | ||
OutputDirectory="$(AppDir)" | ||
Optimized="$(Optimized)" | ||
ForceAOT="$(ForceAOT)" | ||
ForceInterpreter="$(MonoForceInterpreter)" | ||
AppDir="$(MSBuildThisFileDirectory)$(PublishDir)"> | ||
<Output TaskParameter="AppBundlePath" PropertyName="AppBundlePath" /> | ||
<Output TaskParameter="XcodeProjectPath" PropertyName="XcodeProjectPath" /> | ||
</AppleAppBuilderTask> | ||
|
||
<Message Importance="High" Text="Xcode: $(XcodeProjectPath)"/> | ||
<Message Importance="High" Text="App: $(AppBundlePath)"/> | ||
|
||
<Exec Condition="'$(TargetOS)' == 'iOSSimulator'" Command="dotnet xharness apple run --app=$(AppBundlePath) --targets=ios-simulator-64 --output-directory=/tmp/out" /> | ||
|
||
<!-- run on MacCatalyst --> | ||
<Exec Condition="'$(TargetOS)' == 'MacCatalyst'" Command="dotnet xharness apple run --app=$(AppBundlePath) --targets=maccatalyst --output-directory=/tmp/out" /> | ||
|
||
</Target> | ||
|
||
<!-- Set RoslynILDiffFullPath property to the path of roslynildiff --> | ||
<Import Project="..\DeltaHelper.targets" /> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
using System; | ||
|
||
public class ChangeablePart | ||
{ | ||
public static int UpdateCounter (ref int counter) | ||
{ | ||
return ++counter; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
using System; | ||
|
||
public class ChangeablePart | ||
{ | ||
public static int UpdateCounter (ref int counter) | ||
{ | ||
return --counter; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
CONFIG=Debug | ||
MONO_ARCH=x64 | ||
DOTNET := ../../../../../dotnet.sh | ||
|
||
run-sim: | ||
$(DOTNET) publish -c $(CONFIG) /p:TargetOS=iOSSimulator /p:TargetArchitecture=$(MONO_ARCH) \ | ||
/p:UseLLVM=False /p:ForceAOT=False /p:MonoForceInterpreter=true | ||
|
||
run-catalyst: | ||
$(DOTNET) publish -c $(CONFIG) /p:TargetOS=MacCatalyst /p:TargetArchitecture=$(MONO_ARCH) \ | ||
/p:UseLLVM=False /p:ForceAOT=False /p:MonoForceInterpreter=true | ||
|
||
clean: | ||
rm -rf bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using System.Runtime.InteropServices; | ||
|
||
public static class Program | ||
{ | ||
// Defined in main.m | ||
[DllImport("__Internal")] | ||
private static extern void ios_set_text(string value); | ||
|
||
[DllImport("__Internal")] | ||
unsafe private static extern void ios_register_button_click(delegate* unmanaged<void> callback); | ||
|
||
[DllImport("__Internal")] | ||
unsafe private static extern void ios_register_applyupdate_click(delegate* unmanaged<void> callback); | ||
|
||
private static int counter = 0; | ||
|
||
// Called by native code, see main.m | ||
[UnmanagedCallersOnly] | ||
private static void OnButtonClick() | ||
{ | ||
ios_set_text("OnButtonClick! #" + ChangeablePart.UpdateCounter (ref counter)); | ||
} | ||
|
||
[UnmanagedCallersOnly] | ||
private static void OnApplyUpdateClick() | ||
{ | ||
deltaHelper.Update (typeof(ChangeablePart).Assembly); | ||
} | ||
|
||
static MonoDelta.DeltaHelper deltaHelper; | ||
|
||
public static async Task Main(string[] args) | ||
{ | ||
unsafe { | ||
// Register a managed callback (will be called by UIButton, see main.m) | ||
delegate* unmanaged<void> unmanagedPtr = &OnButtonClick; | ||
ios_register_button_click(unmanagedPtr); | ||
delegate* unmanaged<void> unmanagedPtr2 = &OnApplyUpdateClick; | ||
ios_register_applyupdate_click(unmanagedPtr2); | ||
} | ||
deltaHelper = MonoDelta.DeltaHelper.Make(); | ||
const string msg = "Hello World!\n.NET 5.0"; | ||
for (int i = 0; i < msg.Length; i++) | ||
{ | ||
// a kind of an animation | ||
ios_set_text(msg.Substring(0, i + 1)); | ||
await Task.Delay(100); | ||
} | ||
|
||
Console.WriteLine("Done!"); | ||
await Task.Delay(-1); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"changes": [ | ||
{"document": "ChangeablePart.cs", "update": "ChangeablePart_v1.cs"}, | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
#include <stdlib.h> | ||
|
||
#import <UIKit/UIKit.h> | ||
#import "runtime.h" | ||
|
||
@interface ViewController : UIViewController | ||
@end | ||
|
||
@interface AppDelegate : UIResponder <UIApplicationDelegate> | ||
@property (strong, nonatomic) UIWindow *window; | ||
@property (strong, nonatomic) ViewController *controller; | ||
@end | ||
|
||
@implementation AppDelegate | ||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { | ||
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; | ||
self.controller = [[ViewController alloc] initWithNibName:nil bundle:nil]; | ||
self.window.rootViewController = self.controller; | ||
[self.window makeKeyAndVisible]; | ||
return YES; | ||
} | ||
@end | ||
|
||
UILabel *label; | ||
void (*clickHandlerPtr)(void); | ||
void (*clickHandlerApplyUpdatePtr)(void); | ||
|
||
@implementation ViewController | ||
|
||
- (void)viewDidLoad { | ||
[super viewDidLoad]; | ||
|
||
label = [[UILabel alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; | ||
label.textColor = [UIColor greenColor]; | ||
label.font = [UIFont boldSystemFontOfSize: 30]; | ||
label.numberOfLines = 2; | ||
label.textAlignment = NSTextAlignmentCenter; | ||
label.text = @"Hello, wire me up!\n(dllimport ios_set_text)"; | ||
[self.view addSubview:label]; | ||
|
||
UIButton *button = [UIButton buttonWithType:UIButtonTypeInfoDark]; | ||
[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; | ||
[button setFrame:CGRectMake(50, 250, 200, 50)]; | ||
[button setTitle:@"Click me (wire me up)" forState:UIControlStateNormal]; | ||
[button setExclusiveTouch:YES]; | ||
[self.view addSubview:button]; | ||
|
||
UIButton *apply_button = [UIButton buttonWithType:UIButtonTypeInfoDark]; | ||
[apply_button addTarget:self action:@selector(applyUpdateButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; | ||
[apply_button setFrame:CGRectMake(50, 300, 200, 50)]; | ||
[apply_button setTitle:@"ApplyUpdate" forState:UIControlStateNormal]; | ||
[apply_button setExclusiveTouch:YES]; | ||
[self.view addSubview:apply_button]; | ||
|
||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ | ||
mono_ios_runtime_init (); | ||
}); | ||
} | ||
-(void) buttonClicked:(UIButton*)sender | ||
{ | ||
if (clickHandlerPtr) | ||
clickHandlerPtr(); | ||
} | ||
|
||
-(void) applyUpdateButtonClicked:(UIButton*)sender | ||
{ | ||
if (clickHandlerApplyUpdatePtr) | ||
clickHandlerApplyUpdatePtr(); | ||
} | ||
|
||
@end | ||
|
||
// called from C# sample | ||
void | ||
ios_register_button_click (void* ptr) | ||
{ | ||
clickHandlerPtr = ptr; | ||
} | ||
|
||
// called from C# sample | ||
void | ||
ios_register_applyupdate_click (void* ptr) | ||
{ | ||
clickHandlerApplyUpdatePtr = ptr; | ||
} | ||
|
||
// called from C# sample | ||
void | ||
ios_set_text (const char* value) | ||
{ | ||
NSString* nsstr = [NSString stringWithUTF8String:strdup(value)]; | ||
dispatch_async(dispatch_get_main_queue(), ^{ | ||
label.text = nsstr; | ||
}); | ||
} | ||
|
||
int main(int argc, char * argv[]) { | ||
@autoreleasepool { | ||
setenv("DOTNET_MODIFIABLE_ASSEMBLIES", "Debug", 1); | ||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); | ||
} | ||
} | ||
|