fix(iOS): 修复iOS 14+获取WiFi名称的权限与适配问题
1. 添加位置权限请求逻辑适配iOS 14+ NEHotspotNetwork要求 2. 新增NetworkExtension框架依赖并更新Xcode项目配置 3. 修复构建脚本中的日志标识与应用名大小写问题 4. 更新启动图标配置与iOS项目设置 5. 优化WiFi SSID获取的兼容逻辑与日志输出
This commit is contained in:
parent
400fdf60a5
commit
89609dea58
@ -1,6 +1,6 @@
|
||||
#if UNITY_IOS
|
||||
using UnityEditor;
|
||||
using UnityEditor.Callbacks;
|
||||
using UnityEditor.iOS.Xcode;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEngine;
|
||||
@ -14,6 +14,7 @@ public class iOSFixDuplicateShellScript
|
||||
|
||||
FixDuplicateShellScript(pathToBuiltProject);
|
||||
FixPodfile(pathToBuiltProject);
|
||||
AddNetworkExtensionFramework(pathToBuiltProject);
|
||||
}
|
||||
|
||||
private static void FixDuplicateShellScript(string pathToBuiltProject)
|
||||
@ -21,7 +22,7 @@ public class iOSFixDuplicateShellScript
|
||||
string projPath = Path.Combine(pathToBuiltProject, "Unity-iPhone.xcodeproj/project.pbxproj");
|
||||
if (!File.Exists(projPath))
|
||||
{
|
||||
Debug.LogWarning("[FixDupShellScript] pbxproj not found: " + projPath);
|
||||
Debug.LogWarning("[PostProcess] pbxproj not found: " + projPath);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -33,12 +34,13 @@ public class iOSFixDuplicateShellScript
|
||||
if (newContent != content)
|
||||
{
|
||||
File.WriteAllText(projPath, newContent);
|
||||
Debug.Log("[FixDupShellScript] Removed duplicate ShellScript from GameAssembly target");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("[FixDupShellScript] No duplicate ShellScript found");
|
||||
Debug.Log("[PostProcess] Removed duplicate ShellScript from GameAssembly target");
|
||||
}
|
||||
|
||||
// 修复光子矩阵 app 大小写
|
||||
newContent = newContent.Replace("photonmatrix.app", "PhotonMatrix.app");
|
||||
|
||||
File.WriteAllText(projPath, newContent);
|
||||
}
|
||||
|
||||
private static void FixPodfile(string pathToBuiltProject)
|
||||
@ -46,21 +48,19 @@ public class iOSFixDuplicateShellScript
|
||||
string podfilePath = Path.Combine(pathToBuiltProject, "Podfile");
|
||||
if (!File.Exists(podfilePath))
|
||||
{
|
||||
Debug.LogWarning("[FixPodfile] Podfile not found");
|
||||
Debug.LogWarning("[PostProcess] Podfile not found");
|
||||
return;
|
||||
}
|
||||
|
||||
string content = File.ReadAllText(podfilePath);
|
||||
bool modified = false;
|
||||
|
||||
// 移除不需要的 Firebase/Analytics
|
||||
if (content.Contains("Firebase/Analytics"))
|
||||
{
|
||||
content = Regex.Replace(content, @"\s*pod\s+'Firebase/Analytics'[^\n]*\n?", "\n");
|
||||
modified = true;
|
||||
}
|
||||
|
||||
// 将 12.4.0 统一为 12.14.0
|
||||
if (content.Contains("12.4.0"))
|
||||
{
|
||||
content = content.Replace("12.4.0", "12.14.0");
|
||||
@ -70,12 +70,23 @@ public class iOSFixDuplicateShellScript
|
||||
if (modified)
|
||||
{
|
||||
File.WriteAllText(podfilePath, content);
|
||||
Debug.Log("[FixPodfile] Cleaned up Podfile");
|
||||
Debug.Log("[PostProcess] Cleaned up Podfile");
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
private static void AddNetworkExtensionFramework(string pathToBuiltProject)
|
||||
{
|
||||
string projPath = PBXProject.GetPBXProjectPath(pathToBuiltProject);
|
||||
PBXProject proj = new PBXProject();
|
||||
proj.ReadFromString(File.ReadAllText(projPath));
|
||||
|
||||
string unityFrameworkGuid = proj.GetUnityFrameworkTargetGuid();
|
||||
bool added = proj.AddFrameworkToProject(unityFrameworkGuid, "NetworkExtension.framework", false);
|
||||
|
||||
if (added)
|
||||
{
|
||||
Debug.Log("[FixPodfile] Podfile already clean");
|
||||
File.WriteAllText(projPath, proj.WriteToString());
|
||||
Debug.Log("[PostProcess] Added NetworkExtension.framework");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1,28 +1,100 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <SystemConfiguration/CaptiveNetwork.h>
|
||||
#import <NetworkExtension/NetworkExtension.h>
|
||||
#import <CoreLocation/CoreLocation.h>
|
||||
|
||||
static CLLocationManager *locationManager = nil;
|
||||
|
||||
extern "C" {
|
||||
void RequestLocationPermission() {
|
||||
if (locationManager != nil) return;
|
||||
|
||||
locationManager = [[CLLocationManager alloc] init];
|
||||
|
||||
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
|
||||
if (status == kCLAuthorizationStatusAuthorizedWhenInUse ||
|
||||
status == kCLAuthorizationStatusAuthorizedAlways) {
|
||||
NSLog(@"[WiFiHelper] Location permission already granted (status: %d)", (int)status);
|
||||
// 位置权限已获得但还需要启动定位才能让WiFi API工作
|
||||
[locationManager startUpdatingLocation];
|
||||
// 短暂启动后停止(不需要持续定位,只是激活权限链)
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
|
||||
[locationManager stopUpdatingLocation];
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (status == kCLAuthorizationStatusNotDetermined) {
|
||||
NSLog(@"[WiFiHelper] Requesting WhenInUse location permission");
|
||||
[locationManager requestWhenInUseAuthorization];
|
||||
} else {
|
||||
NSLog(@"[WiFiHelper] Location permission denied/restricted (status: %d)", (int)status);
|
||||
}
|
||||
}
|
||||
|
||||
const char* GetWiFiSSID() {
|
||||
NSString *ssid = nil;
|
||||
// 确保位置已启动至少一次(NEHotspotNetwork 的隐式要求)
|
||||
if (locationManager != nil && [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse) {
|
||||
[locationManager startUpdatingLocation];
|
||||
}
|
||||
|
||||
NSArray *interfaces = (__bridge_transfer NSArray *)CNCopySupportedInterfaces();
|
||||
__block NSString *resultSSID = nil;
|
||||
__block BOOL finished = NO;
|
||||
|
||||
for (NSString *interfaceName in interfaces) {
|
||||
NSDictionary *info = (__bridge_transfer NSDictionary *)CNCopyCurrentNetworkInfo((__bridge CFStringRef)interfaceName);
|
||||
if (@available(iOS 14.0, *)) {
|
||||
NSLog(@"[WiFiHelper] Using NEHotspotNetwork.fetchCurrent");
|
||||
|
||||
if (info && info[@"SSID"]) {
|
||||
ssid = info[@"SSID"];
|
||||
break;
|
||||
[NEHotspotNetwork fetchCurrentWithCompletionHandler:^(NEHotspotNetwork * _Nullable network) {
|
||||
if (network && network.SSID.length > 0) {
|
||||
resultSSID = network.SSID;
|
||||
}
|
||||
finished = YES;
|
||||
}];
|
||||
|
||||
// 用 CFRunLoop 等待,不阻塞主线程事件处理
|
||||
NSTimeInterval deadline = [[NSDate date] timeIntervalSinceReferenceDate] + 3.0;
|
||||
while (!finished && [[NSDate date] timeIntervalSinceReferenceDate] < deadline) {
|
||||
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
|
||||
}
|
||||
|
||||
if (resultSSID != nil) {
|
||||
NSLog(@"[WiFiHelper] NEHotspotNetwork SSID: %@", resultSSID);
|
||||
} else {
|
||||
NSLog(@"[WiFiHelper] NEHotspotNetwork returned nil (finished=%d)", finished);
|
||||
}
|
||||
}
|
||||
|
||||
if (ssid == nil) {
|
||||
// Fallback
|
||||
if (resultSSID == nil) {
|
||||
NSLog(@"[WiFiHelper] Fallback to CNCopyCurrentNetworkInfo");
|
||||
NSArray *interfaces = (__bridge_transfer NSArray *)CNCopySupportedInterfaces();
|
||||
if (interfaces != nil) {
|
||||
for (NSString *interfaceName in interfaces) {
|
||||
NSDictionary *info = (__bridge_transfer NSDictionary *)CNCopyCurrentNetworkInfo((__bridge CFStringRef)interfaceName);
|
||||
if (info && info[(NSString *)kCNNetworkInfoKeySSID]) {
|
||||
resultSSID = info[(NSString *)kCNNetworkInfoKeySSID];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (locationManager != nil) {
|
||||
[locationManager stopUpdatingLocation];
|
||||
}
|
||||
|
||||
if (resultSSID == nil) {
|
||||
NSLog(@"[WiFiHelper] No WiFi SSID found.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *utf8String = [ssid UTF8String];
|
||||
char *result = (char *)malloc(strlen(utf8String) + 1);
|
||||
strcpy(result, utf8String);
|
||||
NSLog(@"[WiFiHelper] SSID: %@", resultSSID);
|
||||
|
||||
const char *utf8String = [resultSSID UTF8String];
|
||||
size_t len = strlen(utf8String) + 1;
|
||||
char *result = (char *)malloc(len);
|
||||
if (result == NULL) return NULL;
|
||||
memcpy(result, utf8String, len);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -150,13 +150,19 @@ namespace Kill.UI.Pages
|
||||
[System.Runtime.InteropServices.DllImport("__Internal")]
|
||||
private static extern System.IntPtr GetWiFiSSID();
|
||||
|
||||
[System.Runtime.InteropServices.DllImport("__Internal")]
|
||||
private static extern void RequestLocationPermission();
|
||||
|
||||
/// <summary>
|
||||
/// iOS 获取 WiFi 名称
|
||||
/// iOS 获取 WiFi 名称(先请求位置权限)
|
||||
/// </summary>
|
||||
private string GetWiFiNameIOS()
|
||||
{
|
||||
try
|
||||
{
|
||||
// iOS 14+ NEHotspotNetwork 需要位置权限
|
||||
RequestLocationPermission();
|
||||
|
||||
System.IntPtr ptr = GetWiFiSSID();
|
||||
if (ptr == System.IntPtr.Zero)
|
||||
{
|
||||
|
||||
@ -414,34 +414,7 @@ PlayerSettings:
|
||||
m_Kind: 4
|
||||
m_SubKind: App Store
|
||||
- m_Textures:
|
||||
- {fileID: 2800000, guid: 72592ba5df3304ad8a664eb6c0ab04da, type: 3}
|
||||
m_Width: 180
|
||||
m_Height: 180
|
||||
m_Kind: 0
|
||||
m_SubKind: iPhone
|
||||
- m_Textures:
|
||||
- {fileID: 2800000, guid: d89f75d2829914aefabc2c12ee61e74d, type: 3}
|
||||
m_Width: 120
|
||||
m_Height: 120
|
||||
m_Kind: 0
|
||||
m_SubKind: iPhone
|
||||
- m_Textures: []
|
||||
m_Width: 167
|
||||
m_Height: 167
|
||||
m_Kind: 0
|
||||
m_SubKind: iPad
|
||||
- m_Textures: []
|
||||
m_Width: 152
|
||||
m_Height: 152
|
||||
m_Kind: 0
|
||||
m_SubKind: iPad
|
||||
- m_Textures: []
|
||||
m_Width: 76
|
||||
m_Height: 76
|
||||
m_Kind: 0
|
||||
m_SubKind: iPad
|
||||
- m_Textures:
|
||||
- {fileID: 2800000, guid: d89f75d2829914aefabc2c12ee61e74d, type: 3}
|
||||
- {fileID: 0}
|
||||
m_Width: 120
|
||||
m_Height: 120
|
||||
m_Kind: 3
|
||||
@ -514,6 +487,33 @@ PlayerSettings:
|
||||
m_Height: 20
|
||||
m_Kind: 2
|
||||
m_SubKind: iPad
|
||||
- m_Textures:
|
||||
- {fileID: 2800000, guid: 29fdb52e7fc6c411891c323b5d5b6f01, type: 3}
|
||||
m_Width: 180
|
||||
m_Height: 180
|
||||
m_Kind: 0
|
||||
m_SubKind: iPhone
|
||||
- m_Textures:
|
||||
- {fileID: 2800000, guid: 2fe29f66f37c34d5ca39cf642d8a2ba3, type: 3}
|
||||
m_Width: 120
|
||||
m_Height: 120
|
||||
m_Kind: 0
|
||||
m_SubKind: iPhone
|
||||
- m_Textures: []
|
||||
m_Width: 167
|
||||
m_Height: 167
|
||||
m_Kind: 0
|
||||
m_SubKind: iPad
|
||||
- m_Textures: []
|
||||
m_Width: 152
|
||||
m_Height: 152
|
||||
m_Kind: 0
|
||||
m_SubKind: iPad
|
||||
- m_Textures: []
|
||||
m_Width: 76
|
||||
m_Height: 76
|
||||
m_Kind: 0
|
||||
m_SubKind: iPad
|
||||
m_BuildTargetBatching: []
|
||||
m_BuildTargetShaderSettings: []
|
||||
m_BuildTargetGraphicsJobs: []
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user