公司有一些设备,需要使用手机进行控制,之前是使用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虚拟机跑这个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>
预配:
就这样还是不行... 后来我发现了一个事情,我的APP不在“使用无线局域网与蜂窝网络的App”列表中。但是在上述权限里面,理论上应该会提示我“允许使用无线数据”啊。
后来,我怀疑是因为我没有实际的访问网络,所以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命令,让界面功能多起来就完事了!