【Avalonia】无开发者账号使用iOS真机调试跨平台应用

发布于:2025-08-10 ⋅ 阅读:(18) ⋅ 点赞:(0)

1. 要求

1.1 无需Apple开发者账号

我这里开发的应用仅是用于调试、体验IOS应用开发流程,并没有发布到AppSotre的计划,所以没有申请一年$99的开发者账号。

但没加入开发者计划也有一些使用限制:

  1. 你的应用签名有效期只有一周,到期之后需要重新把手机插到电脑上重新安装一次。
  2. 不能分发应用,多台手机的话只能一个一个装

(如果你已经有了开发者账号,则可以参考这篇文章 Maui劝退:用windows直接真机调试iOS,无须和Mac配对,无需mac电脑)

1.2 最新版mac系统

macOS版本:15.0以上。
你需要有一台装了macOS的电脑,可以是黑苹果或白苹果。(我是找了台不用的dell电脑,花了50装了最新的黑果系统)

系统最好是最新版,因为.net 9只支持macOS 15以上的版本。参见:Target Framework
在这里插入图片描述

1.3 最新版Xcode

AppStore安装最新的Xcode,xamarin/maui/avalonia开发的ios应用都依赖xcode。

2. 配对Mac

这一步比较简单,确保开发机和mac在同一个网段,vs就会自动查找到对应的mac。
在这里插入图片描述
然后点击“connect”即可,会自动在mac上安装需要的work load,大概需要十几分钟。
我这里已经连接过了所以显示“disconnect”

3. 配置开发证书

总体上可以参考这篇略过时的文章:如何在iPhone或iPad上构建和运行应用程序

也可以直接参考我的步骤:

3.1 创建一个名为MTClient的Xcode项目

Xcode中首先登录你的AppleID,然后创建一个名为MTClient的IOS项目。

创建有三个信息比较重要:

  1. Product Name:这里的MTClient是我应用的名字,你也可以改成其它的。
  2. Organization Identifier:组织名,你用ApppleID登陆Xcode时会提示是否创建一个组织,这里自动填充的GymOrg就是我之前创建的组织。当然这里也可以用其他的组织。
  3. Bundle Identifier核心,牢记,这个相当于你应用的标识符,后续所有的签名及证书都是基于此标识符。

在这里插入图片描述
创建完成后,把手机插到mac上调试下看是否能正常跑起来。

3.2 找到签名证书

打开SpotLight,输入KeyChainAccess:
在这里插入图片描述
打开钥匙串访问.app,搜索关键词develop找到刚创建的证书。
在这里插入图片描述
将此证书的名字复制下来备用。

3.3 配置签名

首先将项目属性 Bundle Signing Scheme改为Manual Provisioning:
在这里插入图片描述
然后打开项目的.csproj,添加<CodesignKey>,值就是之前拷贝的证书字符串。
在这里插入图片描述

3.4 配置标识符

签名配置好了,还要配置对应的应用标识符。签名+标识符才是完整的一套。
在这里插入图片描述
打开info.plist将Bundle Identifier改为之前我们配置的值即可。

4. 真机调试

这个没什么好说的,rebuild下项目,然后调试设备选择你的IOS真机,接下来就是正常的调试步骤。

4.1 设置应用首屏 Launch Screen

默认首屏显示的是一个白底黑字你应用名字的一个页面。
你可以修改LaunchScreen.xib文件内容进行调整:
在这里插入图片描述
同样你可以修改info.plist的选项以关闭首次打开时显示首屏页面:
在这里插入图片描述
(但设置为not set后可以影响你app的展示尺寸)

4.2 设置应用图标

打开info.plist,在这里设置应用图标:
在这里插入图片描述
需要多个不同宽高的图标:
在这里插入图片描述
可使用在线工具一次性全部生成。

5. 问题

5.1 DI异常

报错 Attempting to JIT compile method 'Microsoft.Extensions.DependencyInjection.ServiceProvider :

Received unhandled Objective-C exception that was marshalled from a managed exception: Attempting to JIT compile method 'Microsoft.Extensions.DependencyInjection.ServiceProvider Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions:BuildServiceProvider (Microsoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.DependencyInjection.ServiceProviderOptions)' while running in aot-only mode. See https://learn.microsoft.com/xamarin/ios/internals/limitations for more information.
 (System.ExecutionEngineException)
   at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection )
   at MessageTransferClient.App.OnFrameworkInitializationCompleted() in H:\MyProgram\SomePractice\Avaloni

此问题只出现在IOS真机上,IOS模拟器、Windows、安卓都没有问题。原因是因为IOS真机不允许JIT,所以只能用AOT,但并非所有的.net 特性都支持AOT,所以就会报错。

AOT使用的一些限制具体请参考:Xamarin.iOS 的限制

该问题的解决

使用<UserInterpreter>

但并不意味着所有AOT不支持的特性你都不能使用,可以参考iOS 和 Mac Catalyst 上的 Mono 解释器官方文档,在csproj中添加<UseInterpreter>。这样对于AOT不支持的特性就可以使用Mono解释器执行,缺点就是运行速度会慢一点而且也不是100%解决问题。

然而尝试使用Mono解释器后并没有解决此问题,报错变成了:

Error: VTable setup of type Microsoft.Extensions.DependencyInjection.ServiceProvider failed.

解释器无法构造出DI类型所需要的函数表,网上搜了一圈也没找到如何解决。

后续我又尝试使用SimpleInject等对AOT友好的DI或者自己手写DI,但我所用到的SignalR.Client这个库严重依赖MSDI,并且无法替换。

探索MAUI

我曾经一度怀疑.net for ios是个鸡肋,于是在github上搜索现成的基于SignalR的MAUI开发的app,看是否都能正常工作。搜到一个之后真机调试运行了没有发现任何问题,DI也完全正常。这难道是Avalonia自身的问题?

于是乎又经历了一番尝试:将.net版本改为与MAUI中的一致、将所有用的nuget package改为与MAUI中的一致、检查plist是否一致,一番操作之后然而并没有什么用,同样的报错。

此问题遂搁置,等周末再研究。

曙光

于是来到了今天上午,在尝试继续解决这个问题前,我升级了下VS2022的版本,从17.10升级到了目前的最新版17.14.11。
神奇的是DI就这样完全好用了,期间一个星期我没有改动过任何代码,就这么升级一下VisualStuido就解决了。不确定最终问题原因是出现了VisualStudio里还是依赖的.net9 workload里。

关于JIT问题的两个参考链接:

  1. https://github.com/AvaloniaUI/Avalonia/discussions/19267
  2. https://github.com/AvaloniaUI/Avalonia/issues/9934

5.2 其他报错

在这里插入图片描述
开发过程中如果你遇到了像这种奇奇怪怪本不应该报错的报错,clean–>rebuild下你的IOS项目就可以了。

5.3 Entitlements权利

在尝试解决前面的DI问题时,我猜测可能是权利问题(但其实并不是)。所以又检索了macOS Catalina 公证以及对 .NET 下载和项目的影响这篇文章,了解了下权利。简单来说所有你准备在IOS或MAC平台上进行分发的软件都需要具备对应的权利。

但Avalonia模板创建出来的默认应用,并没有添加.net对应的权利,所以适时可以将权利添加到Entitlements.plist文件中。


网站公告

今日签到

点亮在社区的每一天
去签到