Я создал класс в Swift 5.0, который будет использовать сетевой модуль и определять тип интерфейса, используемый в настоящее время пользователем.
import UIKit
import Network
@objc public class NetworkStrength: NSObject {
let shared = NetworkStrength()
var startTime = CFAbsoluteTime()
var stopTime = CFAbsoluteTime()
let monitor = NWPathMonitor()
@objc public var interfaceType = "No Interface connected"
@objc public func startMonitoring() {
let queue = DispatchQueue.global(qos: .background)
monitor.start(queue: queue)
monitor.pathUpdateHandler = { path in
if path.status == .satisfied {
print("Connected...")
let isCellular: Bool = path.usesInterfaceType(.cellular)
let isWifi: Bool = path.usesInterfaceType(.wifi)
let isEthernet: Bool = path.usesInterfaceType(.wiredEthernet)
let isOther: Bool = path.usesInterfaceType(.other)
let isLoopback: Bool = path.usesInterfaceType(.loopback)
if isCellular {
self.interfaceType = "Cellular"
}else if isWifi {
self.interfaceType = "Wifi"
}else if isEthernet {
self.interfaceType = "Wired Ethernet"
}else if isLoopback {
self.interfaceType = "Loopback"
}else if isOther{
self.interfaceType = "Other (Virtual or other undermined network)"
}else {
self.interfaceType = "No interface connected"
}
print("Interface Type => \(self.interfaceType)")
}
else if path.status == .requiresConnection || path.status == .unsatisfied {
print("Connection not available. Please connect to the internet.")
}
}
}
@objc public func stopMonitoring() {
monitor.cancel()
}
}
Меня попросили создать плагин Unity iOS, где этот код можно использовать в Unity, вызвав NetworkStrength.startMonitor () или NetworkStrength.interfaceType. Класс называется NetworkStrength, поскольку у него есть специальный тест скорости, который я не могу включить, потому что код станет слишком большим.
У меня нет опыта использования Objective C. Но я пробовал следующие решения.
Блог 1 Блог 2
Используя их, я создал проект фреймворка iOS, который имеет files
NetworkStrength.swift // который показан выше
NetworkStrength.mm
#import <UIKit/UIKit.h>
#import <NetworkStrength/NetworkStrength-Swift.h>
#pragma mark - C interface
extern "C" {
void _startMonitoring() {
[[NetworkStrength shared] startMonitoring];
}
void _stopMonitoring() {
[[NetworkStrength shared] stopMonitoring];
}
char* _returnInterfaceType() {
NSString *returnString = [[NetworkStrength shared] interfaceType];
char* cStringCopy(const char* string);
return cStringCopy([returnString UTF8String]);
}
}
char* cStringCopy(const char* string){
if (string == NULL){
return NULL;
}
char* res = (char*)malloc(strlen(string)+1);
strcpy(res, string);
return res;
}
и
NetworkStrength.h, как указано в этой ссылке документация Apple , которая содержит
@class NetworkStrength;
и для параметра Defines Module значение Yes. Я построил проект, и ошибок не было.
Итак, я пошел дальше и создал новый проект единства, в котором все указанные файлы находятся внутри Assets / Plugins / iOS / NetworkStrength / Source. Как сказано в блоге, я создал файл NetworkStrength.cs, содержащий следующий код.
using System;
using System.Runtime.InteropServices;
using UnityEngine;
public class NetworkStrength : MonoBehaviour {
#region Declare external C interface
#if UNITY_IOS && !UNITY_EDITOR
[DllImport("__Internal")]
private static extern void _startMonitoring();
[DllImport("__Internal")]
private static extern void _stopMonitoring();
[DllImport("__Internal")]
private static extern void _returnInterfaceType();
#endif
#endregion
#region Wrapped methods and properties
public static void StartMonitoring() {
#if UNITY_IOS && !UNITY_EDITOR
_startMonitoring();
#endif
}
public static void StopMonitoring() {
#if UNITY_IOS && !UNITY_EDITOR
_stopMonitoring();
#endif
}
public static void ReturnInterfaceType() {
#if UNITY_IOS && !UNITY_EDITOR
_returnInterfaceType();
#endif
}
#endregion
#region Singleton implementation
private static NetworkStrength _instance;
public static NetworkStrength Instance
{
get
{
if (_instance == null)
{
var obj = new GameObject("NetworkStrength");
_instance = obj.AddComponent<NetworkStrength>();
}
return _instance;
}
}
private void Awake()
{
if (_instance != null)
{
Destroy(gameObject);
return;
}
DontDestroyOnLoad(gameObject);
}
#endregion
}
и добавил SwiftPostProcessor.cs в Assets / Plugins / iOS / NetworkStrength / Editor, содержащий следующий код.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using System.Diagnostics;
using System.IO;
using System.Linq;
public static class SwiftPostProcess {
[PostProcessBuild]
public static void OnPostProcessBuild(BuildTarget buildTarget, string buildPath)
{
if (buildTarget == BuildTarget.iOS)
{
var projPath = buildPath + "/Unity-Iphone.xcodeproj/project.pbxproj";
var proj = new PBXProject();
proj.ReadFromFile(projPath);
var targetGuid = proj.GetUnityFrameworkTargetGuid() ;
//// Configure build settings
proj.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "NO");
proj.SetBuildProperty(targetGuid, "SWIFT_OBJC_BRIDGING_HEADER", "Libraries/Plugins/iOS/NetworkStrength/Source/NetworkStrength.h");
proj.SetBuildProperty(targetGuid, "SWIFT_OBJC_INTERFACE_HEADER_NAME", "NetworkStrength-Swift.h");
proj.AddBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks");
proj.WriteToFile(projPath);
}
}
}
Сделав это, я построил проект, чтобы посмотреть, нет ли ошибок. Первая ошибка, которую я получил, была
Файл NetworkStrength / NetworkStrength-Swift.h не найден. Я пробовал разные решения, но каждый раз получал одну и ту же ошибку. Кажется, я не могу решить эту проблему. Помогите, пожалуйста, решить эту проблему.
PS. Я попробовал NetworkStrength-Bridging-Header.h, как и в блоге, но продолжал получать ошибку: использование заголовков моста с целями фреймворка не поддерживается. Я последовал тому, что было предложено в этом решении .