Как избежать принудительного понижения с любого на CFString - PullRequest
0 голосов
/ 05 февраля 2020

Итак, вот некоторый код, который я нашел из другого вопроса, с принудительным понижением с Any до CFString

import SystemConfiguration.CaptiveNetwork

func fetchSSIDInfo() -> String? {
    var ssid: String?
    if let interfaces = CNCopySupportedInterfaces() as NSArray? {
        for interface in interfaces {
            // is there any way to remove the force downcast below ?
            if let interfaceInfo = CNCopyCurrentNetworkInfo(interface as! CFString) as NSDictionary? {
                ssid = interfaceInfo[kCNNetworkInfoKeySSID as String] as? String
                break
            }
        }
    }
    return ssid
}

Вам нужно использовать принудительное снижение или есть другой способ? Существуют ли особые правила при работе со старыми объектами Corefoundation? Потому что работа с NSObjects кажется намного проще.

Ответы [ 2 ]

1 голос
/ 05 февраля 2020

Вы можете избежать принудительного понижения и для безопасной проверки типа элементов в CFArray, возвращаемых CNCopySupportedInterfaces, путем условного приведения каждого элемента к String, а затем к CFString в вашем вызове CNCopyCurrentNetworkInfo.

func fetchSSIDInfo() -> String? {
    var ssid: String?
    if let interfaces = CNCopySupportedInterfaces() as NSArray? {
        for cfInterface in interfaces {
            guard let interface = cfInterface as? String else {
                continue
            }
            if let interfaceInfo = CNCopyCurrentNetworkInfo(interface as CFString) as NSDictionary? {
                ssid = interfaceInfo[kCNNetworkInfoKeySSID as String] as? String
                break
            }
        }
    }
    return ssid
}

Условное приведение возвращаемого значения от CNCopySupportedInterfaces к [CFString] позволяет избежать принудительного понижения, но не позволяет безопасно проверять тип элементов в массиве. Например, следующий фрагмент будет скомпилирован, но при выполнении выдает исключение NSException.

let cfArray = [1 as CFNumber, 2 as CFNumber] as CFArray
if let arrayOfStrings = cfArray as? [CFString] {
    for e in arrayOfStrings {
        print((e as String).appending("foo"))
    }
}
1 голос
/ 05 февраля 2020

Импорт Foundation, чтобы предоставить компилятору информацию о мостах между типами Core Foundation и Foundation. Затем приведите массив как хотите:

import Foundation
import SystemConfiguration.CaptiveNetwork

func fetchSSIDInfo() -> String? {
    var ssid: String?
    if let interfaces = CNCopySupportedInterfaces() as? [CFString] {
        for interface in interfaces {
            if let interfaceInfo = CNCopyCurrentNetworkInfo(interface) as NSDictionary? {
                ssid = interfaceInfo[kCNNetworkInfoKeySSID as String] as? String
                break
            }
        }
    }
    return ssid
}
...