Skip to content

Commit

Permalink
Merge pull request #2 from chamons/swift_smash
Browse files Browse the repository at this point in the history
Complete basic iOS support and port to be fully Swift powered
  • Loading branch information
Redth authored Jul 21, 2022
2 parents d21b74d + d0d5261 commit ab916e4
Show file tree
Hide file tree
Showing 47 changed files with 646 additions and 795 deletions.
3 changes: 1 addition & 2 deletions DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ This project is built upon a native library, one for iOS and another for Android
Those native libraries are bound in binding projects to be callable from c#:

- Android: Microsoft.PlatformChannels.Binding/Microsoft.PlatformChannels.Binding.csproj
- There are some iOS references here, but it is not used on iOS today
- iOS: Microsoft.PlatformChannels.Binding.Apple/Microsoft.PlatformChannels.Binding.Apple.csproj
- iOS: Platforms/Apple/Microsoft.PlatformChannels.Binding.Apple/Microsoft.PlatformChannels.Binding.Apple.csproj

The PlatformChannel abstraction is built using C# (leveraging those native libraries) in two layers:

Expand Down
13 changes: 13 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
TARGET=net6.0-ios
#TARGET=net6.0-maccatalyst

both:: build run

build::
make -C Platforms/Apple/
dotnet build Microsoft.Maui.PlatformChannels/ -f:$(TARGET)
dotnet build -f:$(TARGET) SamplePlatformChannels

run::
# -MONO_TRACE=E:all ./SamplePlatformChannels/bin/Debug/net6.0-maccatalyst/maccatalyst-x64/SamplePlatformChannels.app/Contents/MacOS/SamplePlatformChannels
dotnet build -t:Run -f:$(TARGET) SamplePlatformChannels
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0-android</TargetFrameworks>
<TargetFrameworks>net6.0-android;net6.0-ios;net6.0-maccatalyst</TargetFrameworks>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
<ImplicitUsings>enable</ImplicitUsings>
Expand All @@ -16,6 +16,12 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.PlatformChannels\Microsoft.PlatformChannels.csproj" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.Contains('-android'))">
<ProjectReference Include="..\Microsoft.PlatformChannels.Binding\Microsoft.PlatformChannels.Binding.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0-ios' OR '$(TargetFramework)' == 'net6.0-maccatalyst'">
<ProjectReference Include="..\Platforms\Apple\Microsoft.PlatformChannels.Binding.Apple\Microsoft.PlatformChannels.Binding.Apple.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
global using PlatformView = global::UIKit.UIView;
global using PlatformObject = global::Foundation.NSObject;
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
using Microsoft.Maui.Handlers;
using Microsoft.PlatformChannels;
using Foundation;
using UIKit;

using iOSViewChannel = Microsoft.PlatformChannels.Platform.ViewChannel;

namespace Microsoft.Maui.PlatformChannels;

public partial class PlatformChannelViewHandler : ViewHandler<IPlatformChannelView, UIKit.UIView>
{
iOSViewChannel platformViewChannel;
PlatformManagedHandler managedHandler;
UIView viewGroup;

protected string ChannelTypeId { get; private set; }
protected string ChannelInstanceId { get; private set; }

IChannelService channelService;

protected override UIKit.UIView CreatePlatformView()
{
if (viewGroup is null) {
// TODO - Fix this hard coded size
viewGroup = new UIView(new CoreGraphics.CGRect(0, 0, 400, 100));
}
EnsureChannelCreated();
return viewGroup;
}

void EnsureChannelCreated()
{
if (string.IsNullOrEmpty(VirtualView?.ChannelTypeId))
return;

var instanceId = VirtualView?.ChannelInstanceId ?? ChannelService.DEFAULT_INSTANCE_ID;

// Is the new id the same as the old?
if (VirtualView?.ChannelTypeId == ChannelTypeId)
{
// Is the instance null on both (so both default and the same)
// or is the new instance Id not the same as the old
if (instanceId == ChannelInstanceId)
return; // No change to actual channel, return
}

channelService ??= MauiContext.Services.GetRequiredService<IChannelService>();

if (platformViewChannel is not null)
{
foreach (var subview in viewGroup.Subviews) {
subview.RemoveFromSuperview ();
}

if (viewGroup.Superview is not null)
viewGroup.RemoveFromSuperview ();

channelService.DisposeChannel(ChannelTypeId, ChannelInstanceId);
platformViewChannel = null;
}

ChannelTypeId = VirtualView.ChannelTypeId;
ChannelInstanceId = instanceId;

var channel = Microsoft.PlatformChannels.Platform.ChannelService.GetOrCreate(ChannelTypeId, ChannelInstanceId);

if (channel == null) {
throw new InvalidOperationException($"No registered ViewChannel found for: '{ChannelTypeId}', instance: '{ChannelInstanceId}'");
}

if (channel is not iOSViewChannel viewChannel)
throw new InvalidCastException($"Registered channel '{ChannelTypeId}' is not a 'ViewChannel' type for instance: '{ChannelInstanceId}");

platformViewChannel = viewChannel;

managedHandler = new PlatformManagedHandler((id, parameters) =>
{
return OnReceivedFromPlatform?.Invoke(id, parameters);
});

platformViewChannel.SetManagedHandler(managedHandler);

var platformView = platformViewChannel.GetPlatformView();
viewGroup.AddSubview (platformView);
}

public static void MapChannelTypeId(IPlatformViewHandler handler, IPlatformChannelView view)
{
if (handler is PlatformChannelViewHandler h)
h.EnsureChannelCreated();
}

public static void MapChannelInstanceId(IPlatformViewHandler handler, IPlatformChannelView view)
{
if (handler is PlatformChannelViewHandler h)
h.EnsureChannelCreated();
}

internal object SendToPlatformImpl(string messageId, object[] args)
{
var platformObjs = args.ToPlatformObjects();

var platformResp = platformViewChannel?.OnChannelMessage(messageId, platformObjs);

var result = platformResp.ToDotNetObject();

return result;
}

class PlatformManagedHandler : NSObject, Microsoft.PlatformChannels.Platform.IChannelMessageHandler
{
public PlatformManagedHandler(Func<string, object[], object> callback)
{
Callback = callback;
}

protected readonly Func<string, object[], object> Callback;

public PlatformObject OnChannelMessage(string id, PlatformObject[] parameters)
=> Callback?.Invoke(id, parameters.ToDotNetObjects()).ToPlatformObject();
}
}
11 changes: 0 additions & 11 deletions Microsoft.Maui.PlatformChannels/Platforms/iOS/ViewChannel.ios.cs

This file was deleted.

10 changes: 0 additions & 10 deletions Microsoft.PlatformChannels.Binding.Apple/ApiAdditions.cs

This file was deleted.

132 changes: 0 additions & 132 deletions Microsoft.PlatformChannels.Binding.Apple/ApiDefinitions.cs

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,14 @@

<PropertyGroup Condition="'$(TargetFramework)' == 'net6.0-ios' OR '$(TargetFramework)' == 'net6.0-maccatalyst' ">
<IsBindingProject>True</IsBindingProject>
<!--<NoBindingEmbedding>true</NoBindingEmbedding>-->
<!--<SupportedOSPlatformVersion>10.0</SupportedOSPlatformVersion>-->
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0-android'">
<AndroidLibrary Include="..\Platforms\Android\platformchannels\build\outputs\aar\platformchannels-debug.aar" Link="platformchannels.aar" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0-ios' OR '$(TargetFramework)' == 'net6.0-maccatalyst' ">
<!--<Compile Include="ApiAdditions.cs" />-->
<NativeReference Include="..\Platforms\Apple\DotNetPlatformChannels\build\DotNetPlatformChannels.xcframework\ios-arm64_x86_64-simulator\DotNetPlatformChannels.framework">
<!--<Link>DotNetPlatformChannels.xcframework</Link>-->
<NativeReference Include="..\Platforms\Apple\DotNetPlatformChannels\build\DotNetPlatformChannels.xcframework">
<Kind>Framework</Kind>
<Frameworks></Frameworks>
</NativeReference>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<ProjectReference Include="..\Microsoft.PlatformChannels.Binding\Microsoft.PlatformChannels.Binding.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0-ios' or '$(TargetFramework)' == 'net6.0-maccatalyst'">
<ProjectReference Include="..\Microsoft.PlatformChannels.Binding.Apple\Microsoft.PlatformChannels.Binding.Apple.csproj" />
<ProjectReference Include="..\Platforms\Apple\Microsoft.PlatformChannels.Binding.Apple\Microsoft.PlatformChannels.Binding.Apple.csproj" />
</ItemGroup>
<ItemGroup>

Expand Down
Loading

0 comments on commit ab916e4

Please sign in to comment.