-
Notifications
You must be signed in to change notification settings - Fork 5.1k
[mono] Add iOS app sample using mono runtime #3931
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
Merged
Merged
Changes from all commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
2945ca0
Initial port of iOS sample
a8a7887
Remove dependency on dotnet.sh and MonoAotCompiler
5455b45
Remove reference to in-tree runtime pack
7d20c40
Modify path to mobile.tasks
4b5e9cb
Directly reference TargetFramework
c5d22c7
Modify AppleAppBuilder config
e87abe0
Use forward slash in paths
6badecd
Remove in-tree runtime pack reference
06d67cd
Add TargetArch remove MNCARPD
33b7058
Add NuGet and BuildAppBundle after publish
4a62af7
Minimal working sample
894f033
Modify sample to rely on nuget package instead
a59c56d
Remove Debugging target
93017d7
Add iOS sample nuget package
2bf168f
Add custom UI file
dbfda59
Clean up project file
b1805b3
Update iOS sample Auto Layout
2ad509f
Add action replace iOS with name
17e9c1c
Touch up string replacement
9dbdfd7
Add mono readme and iOS specific readme
49691c4
Update assembly target version
93683dd
Clean up README
0d3b5b8
Clean up notes in README
be096f1
Add brackets around bare url in README
08f2cf7
Remove trailing space and add blank line around list
5947c52
Reference dotnet6 NuGet feed
c9b2820
Remove nuget local repositoryPath
2d79b0a
Reword header for clarification
a31b034
Fix nupkg version match
228d185
Use PropertyPath instead of NuGetPackageRoot
c6c11eb
Remove unnecessary dependencies
54c640e
Add softcode for runtime identifier
1ee0239
Touch up README
35558ad
Add build of dotnet sdk to prereqs
2c3b026
Override with .NET 6 SDK
b1b4658
Fix dotnet version and add installation instructions
2bb0b00
Update target framework to target net6.0
f338c17
Remove handlers and MonoPInvoke Attribute
590a8bb
Move TargetArchitecture to project scope
813b970
Rename Program to iOSSampleApp and trim assemblies
cfaa203
Minor fixes; pulled prereqs into sample readme
adegeo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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,22 @@ | ||
# Sample .NET apps using the Mono runtime | ||
|
||
This folder contains sample code demonstrating how to build mobile (iOS, Android, Browser WebAssembly) apps with the mono runtime. The requirements for each sample can be found within the corresponding folder, and each sample can be ran using `dotnet publish`. | ||
|
||
## Prerequisites | ||
|
||
.NET SDK version 6.0.100-alpha.1.20531.2 is needed to run these samples. To install a specific version of the dotnet sdk, download the latest stable version of the dotnet-install script: | ||
|
||
- Bash (Linux/macOS): <https://dot.net/v1/dotnet-install.sh> | ||
- PowerShell (Windows): <https://dot.net/v1/dotnet-install.ps1> | ||
|
||
Install version .NET version **6.0.100-alpha.1.20531.2**: | ||
|
||
```bash | ||
./dotnet-install.sh --version 6.0.100-alpha.1.20531.2 | ||
``` | ||
|
||
```powershell | ||
./dotnet-install.ps1 -Version 6.0.100-alpha.1.20531.2 | ||
``` | ||
|
||
For more information, see [dotnet-install script reference](https://docs.microsoft.com/dotnet/core/tools/dotnet-install-script) |
This file contains hidden or 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,6 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<configuration> | ||
<packageSources> | ||
<add key="dotnet6" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6/nuget/v3/index.json" /> | ||
</packageSources> | ||
</configuration> |
This file contains hidden or 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,47 @@ | ||
--- | ||
languages: | ||
- csharp | ||
products: | ||
- dotnet-core | ||
page_type: sample | ||
name: "iOS Sample: Simple greeting and counter (C#)" | ||
description: "An iOS application that contains an example of embedding the mono runtime to invoke unmanaged code with C#." | ||
urlFragment: "mono-ios-csharp" | ||
--- | ||
|
||
# iOS Sample: Simple greeting and counter (C#) | ||
|
||
In this sample, the mono runtime is used to invoke Objective-c unmanaged code (main.m) from the C# managed side (iOSSampleApp.cs) and vice versa. With the sample running, you can enter your name and click the corresponding button to modify the greeting message as well as clicking a button to increment a counter. | ||
|
||
> [!NOTE] | ||
> The purpose of this sample is to demonstrate the concept of building an iOS application on top of the mono runtime. The mono runtime headers should be supplied through the build process. | ||
|
||
## Sample Prerequisites | ||
|
||
This sample will only run on macOS as it requires Xcode and an iOS simulator. | ||
|
||
- Xcode: Any version should work with this sample (download Xcode at <https://developer.apple.com/xcode/>). | ||
- iOS simulator 8.0 or greater. | ||
- .NET sdk 6.0.100-alpha.1.20531.2 (Installation instructions in parent directory). | ||
|
||
To install a specific version of the dotnet sdk, download the latest stable version of the dotnet-install script: | ||
|
||
- Bash (Linux/macOS): <https://dot.net/v1/dotnet-install.sh> | ||
- PowerShell (Windows): <https://dot.net/v1/dotnet-install.ps1> | ||
|
||
Install version .NET version **6.0.100-alpha.1.20531.2**: | ||
|
||
```bash | ||
./dotnet-install.sh --version 6.0.100-alpha.1.20531.2 | ||
``` | ||
|
||
```powershell | ||
./dotnet-install.ps1 -Version 6.0.100-alpha.1.20531.2 | ||
``` | ||
|
||
> [!NOTE] | ||
> Modify `IosSimulator` under target `BuildAppBundle` from `iPhone 11` to your simulator's device name. | ||
|
||
## Building the sample | ||
|
||
The source code includes an MSBuild project file for C# (a _.csproj_ file) that targets .NET 6.0. After downloading the _.zip_ file, be sure to have the iOS simulator open and modify `iPhone 11` in `iOSSampleApp.csproj` to the simulator's name. To run the sample, open the command line, navigate to the downloaded folder, and run `dotnet publish`. |
This file contains hidden or 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,7 @@ | ||
{ | ||
"sdk": { | ||
"version": "6.0.100-alpha.1.20531.2", | ||
"rollForward": "major", | ||
"allowPrerelease": true | ||
} | ||
} |
This file contains hidden or 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,55 @@ | ||
// 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 iOSSampleApp | ||
{ | ||
// Defined in main.m | ||
[DllImport("__Internal")] | ||
private extern static void ios_set_text(string value); | ||
|
||
[DllImport("__Internal")] | ||
private extern static void ios_greet_name(string value); | ||
|
||
[DllImport("__Internal")] | ||
private extern static void ios_register_counter_increment(Action action); | ||
|
||
[DllImport("__Internal")] | ||
private extern static void ios_register_name_greet(Action<string> action); | ||
|
||
private static int counter = 1; | ||
|
||
// Called by native code, see main.m | ||
private static void IncrementCounter() | ||
{ | ||
ios_set_text($"Clicked {counter++} times!"); | ||
} | ||
|
||
private static void GreetName(string name) | ||
{ | ||
ios_greet_name(name); | ||
} | ||
|
||
public static async Task Main(string[] args) | ||
{ | ||
// Register a managed callback (will be called by UIButton, see main.m) | ||
// Also, keep the handler alive so GC won't collect it. | ||
ios_register_counter_increment(IncrementCounter); | ||
ios_register_name_greet(GreetName); | ||
|
||
const string msg = "Hello World!"; | ||
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 hidden or 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,57 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<TargetArchitecture>x64</TargetArchitecture> | ||
<RuntimeIdentifier>ios-$(TargetArchitecture)</RuntimeIdentifier> | ||
<OutputType>Exe</OutputType> | ||
<PublishTrimmed>True</PublishTrimmed> | ||
<TrimMode>link</TrimMode> | ||
<Configuration>Release</Configuration> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Runtime.iOS.Sample.Mono" Version="6.0.0-*" GeneratePathProperty="true" /> | ||
</ItemGroup> | ||
|
||
<UsingTask TaskName="AppleAppBuilderTask" | ||
AssemblyFile="$(PkgMicrosoft_NET_Runtime_iOS_Sample_Mono)\tools\net6.0\AppleAppBuilder.dll" /> | ||
|
||
<Target Name="BuildAppBundle" AfterTargets="Publish"> | ||
<PropertyGroup> | ||
<AppDir>$(MSBuildThisFileDirectory)$(PublishDir)</AppDir> | ||
<IosSimulator Condition="'$(TargetArchitecture)' == 'x64' or '$(TargetArchitecture)' == 'x86'">iPhone 11</IosSimulator> | ||
<Optimized Condition="'$(Configuration)' == 'Release'">True</Optimized> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<BundleAssemblies Include="$(AppDir)\*.dll" /> | ||
</ItemGroup> | ||
|
||
<AppleAppBuilderTask | ||
ProjectName="HelloiOS" | ||
AppDir="$(AppDir)" | ||
MonoRuntimeHeaders="%(ResolvedRuntimePack.PackageDirectory)\runtimes\$(RuntimeIdentifier)\native\include\mono-2.0" | ||
MainLibraryFileName="$(MSBuildThisFileName).dll" | ||
Assemblies="@(BundleAssemblies)" | ||
OutputDirectory="$(AppDir)\app" | ||
Optimized="$(Optimized)" | ||
Arch="$(TargetArchitecture)" | ||
BuildAppBundle="True" | ||
GenerateXcodeProject="True" | ||
NativeMainSource="$(MSBuildThisFileDirectory)main.m"> | ||
<Output TaskParameter="AppBundlePath" PropertyName="AppBundlePath" /> | ||
<Output TaskParameter="XcodeProjectPath" PropertyName="XcodeProjectPath" /> | ||
</AppleAppBuilderTask> | ||
|
||
<Message Importance="High" Text="Xcode: $(XcodeProjectPath)" /> | ||
<Message Importance="High" Text="App: $(AppBundlePath)" /> | ||
<Message Importance="High" Text="Restarting device" /> | ||
<Exec Condition="'$(IosSimulator)' != ''" Command="xcrun simctl shutdown "$(IosSimulator)"" ContinueOnError="WarnAndContinue" /> | ||
<Exec Condition="'$(IosSimulator)' != ''" Command="xcrun simctl boot "$(IosSimulator)"" /> | ||
<Exec Condition="'$(IosSimulator)' != ''" Command="open -a Simulator" /> | ||
<Message Importance="High" Text="Installing application" /> | ||
<Exec Condition="'$(IosSimulator)' != ''" Command="xcrun simctl install "$(IosSimulator)" $(AppBundlePath)" /> | ||
<Message Importance="High" Text="Launching application" /> | ||
<Exec Condition="'$(IosSimulator)' != ''" Command="xcrun simctl launch --console booted net.dot.HelloiOS" /> | ||
</Target> | ||
</Project> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also need the URL it will be hosted at in the samples browser when published: https://review.docs.microsoft.com/en-us/samples/browse/?branch=master
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will the url be generated automatically from adding this line or are there other actionables I need to take to get the sample hosted at the url?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IFAIK you just need to add this line. I have heard rumors though that the samples browser doesn't automatically import samples and you need to file a ticket. I've heard it's "supposed" to be automated but it never shows up and when you ask about it, it magically shows up, as if someone is somewhere pushing a button every time.
@IEvangelist true?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My experience is that it takes a long time, roughly a week or so - but it does eventually make its way there. There have been a few times too where it has gotten stuck with no reason why, then you have to ask the right people who have access to get it moved.