公司有一些设备,需要使用手机进行控制,之前是使用Android手机进行操作的,但是由于域网络的一些限制,导致Android手机不能加入域了。对于.NET Core这应该不是什么难的事情,所以我准备翻版一下Android应用,使用iOS版本进行控制。

他们的底层都是基于上一任开发的基础进行的,使用的.NET Standard 2.0 + System.Net.Sockets 这种原生的方式向指定服务器发送UDP广播。

开发iOS的过程就那么回事,没有什么可说的,调试的时候我开始使用的是“免费预配”,免费预配在官方文档的“限制”节中写道,“通过免费预配创建的配置文件一周后过期,签名标识一年后过期。” 我理解就是这玩意不靠谱,有可能一周之后就不能用了。我不知道是我操作错误还是怎样,在第二周再尝试界面上的交互按钮之后,果然服务器是没有收到任何消息的。我查询了很多文档,在苹果开发者社区有这么一篇提示:Using the Multicast Networking Add… | Apple Developer Forums,大概的内容是说如果你想在iOS14.0后使用多播网络(Multicast Networking)就需要有“com.apple.developer.networking.multicast” 权限,经过和领导沟通我升级成为了个人开发者¥688。

经过一番申请之后,我获得了这个权限。它会出现在这个位置

IOS搜不到扩展广播 苹果没有广播_ios

签名,证书,描述文件此处略,很多地方都有如何处理这些的文章。

一切准备就绪了,继续调试但是不行!在这期间我用本地iOS虚拟机跑这个app的时候,UDP是可以发送出去的。但是上了真机就不行。

已开始我怀疑是签名问题,我重新下载签名,进行手动签名,试了各种方法都无济于事,这些是我尝试的权限和预配。

Info.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDisplayName</key>
	<string>appname</string>
	<key>CFBundleIdentifier</key>
	<string>com.appname</string>
	<key>CFBundleShortVersionString</key>
	<string>1.0</string>
	<key>CFBundleVersion</key>
	<string>1.0</string>
	<key>LSRequiresIPhoneOS</key>
	<true/>
	<key>UIApplicationSceneManifest</key>
	<dict>
		<key>UIApplicationSupportsMultipleScenes</key>
		<true/>
		<key>UISceneConfigurations</key>
		<dict>
			<key>UIWindowSceneSessionRoleApplication</key>
			<array>
				<dict>
					<key>UISceneConfigurationName</key>
					<string>Default Configuration</string>
					<key>UISceneDelegateClassName</key>
					<string>SceneDelegate</string>
					<key>UISceneStoryboardFile</key>
					<string>Main</string>
				</dict>
			</array>
		</dict>
	</dict>
	<key>MinimumOSVersion</key>
	<string>15.2</string>
	<key>UIDeviceFamily</key>
	<array>
		<integer>1</integer>
		<integer>2</integer>
	</array>
	<key>UILaunchStoryboardName</key>
	<string>LaunchScreen</string>
	<key>UIMainStoryboardFile</key>
	<string>Main</string>
	<key>UIMainStoryboardFile~ipad</key>
	<string>Main</string>
	<key>UIRequiredDeviceCapabilities</key>
	<array>
		<string>armv7</string>
		<string>wifi</string>
		<string>microphone</string>
	</array>
	<key>UISupportedInterfaceOrientations</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
	</array>
	<key>UISupportedInterfaceOrientations~ipad</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationPortraitUpsideDown</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
	<key>XSAppIconAssets</key>
	<string>Assets.xcassets/AppIcon.appiconset</string>
	<key>UIRequiresPersistentWiFi</key>
	<true/>
	<key>NSMicrophoneUsageDescription</key>
	<string>使用麦克风以增强互动</string>
	<key>NSNetworkVolumesUsageDescription</key>
	<string>请开启网络功能</string>
	<key>NSLocalNetworkUsageDescription</key>
	<string>请开启网络功能</string>
	<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSAllowsArbitraryLoads</key>
		<true/>
	</dict>
</dict>
</plist>

Entitlements.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.developer.networking.multicast</key>
	<true/>
	<key>com.apple.developer.networking.networkextension</key>
	<array>
		<string>app-proxy-provider</string>
	</array>
	<key>com.apple.developer.networking.wifi-info</key>
	<true/>
	<key>com.apple.developer.networking.multipath</key>
	<true/>
	<key>com.apple.external-accessory.wireless-configuration</key>
	<true/>
</dict>
</plist>

预配:

IOS搜不到扩展广播 苹果没有广播_ios_02

就这样还是不行... 后来我发现了一个事情,我的APP不在“使用无线局域网与蜂窝网络的App”列表中。但是在上述权限里面,理论上应该会提示我“允许使用无线数据”啊。

IOS搜不到扩展广播 苹果没有广播_xamarin_03

后来,我怀疑是因为我没有实际的访问网络,所以iOS以为我不需要,于是我写了一行代码,来下载点东西,让系统真的去访问无线数据!

try
{
    var config = NSUrlSessionConfiguration.BackgroundSessionConfiguration(Guid.NewGuid().ToString());
    var session = NSUrlSession.FromConfiguration(config);
    var downloadTask = session.CreateDownloadTask(NSUrlRequest.FromUrl(new NSUrl("https://www.google.com")));
    downloadTask.Resume();
}
catch
{ }

于是,他就真的开始访问无线网络了,并出现在了“使用无线局域网与蜂窝网络的App”列表中。

测试了一下Socket,已经可以用了,非常好!剩下的就是完善更多的UDP命令,让界面功能多起来就完事了!