2015-07-31 20 views
8

Đang cố gắng lấy SSID của thiết bị hiện tại. Tôi đã tìm thấy rất nhiều ví dụ về làm thế nào để làm điều đó tuy nhiên tôi đang đấu tranh với việc nhận được các CNCopySupportedInterfaces để tự động hoàn thành. Tôi đã 'nhập SystemConfiguration' ở đầu tệp nhanh nhưng không thành công. Có vẻ như không thể hiểu được tôi đang làm gì sai.Swift CNCopySupportedInterfaces không hợp lệ

Trả lời

15

Bạn cần import SystemConfiguration.CaptiveNetwork

Bên dưới vỏ, CaptiveNetwork là một tập tin header C (.h) đó là trong khuôn khổ SystemConfigura:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/SystemConfiguration.framework/Headers/CaptiveNetwork.h

Nếu bạn biết Objective-C, điều này đi vào chiều sâu hơn:

iPhone get SSID without private library

Ngoài ra, tự động hoàn thành không hài lòng với các hình ảnh toàn cầu cũ; nó chỉ muốn các lớp ở cấp cao nhất. Có lẽ vì có quá nhiều @ # $ @ # globals.

Oh, và bạn phải viết đoạn tuyệt vời này để làm cho nó làm việc:

for interface in CNCopySupportedInterfaces().takeRetainedValue() as! [String] { 
     println("Looking up SSID info for \(interface)") // en0 
     let SSIDDict = CNCopyCurrentNetworkInfo(interface).takeRetainedValue() as! [String : AnyObject] 
     for d in SSIDDict.keys { 
      println("\(d): \(SSIDDict[d]!)") 
     } 
    } 

PHỤ LỤC CHO SWIFT 2.2 và 3,0

Bridging đã được đơn giản hóa nhưng lại phức tạp cho CFxxx kiểu dữ liệu và bây giờ mở ra và rất nhiều phà là bắt buộc nhưng không có cuộc gọi giữ lại. Tôi không biết rằng Swift 2 đã làm mọi thứ dễ dàng hơn nhưng nó khá rõ ràng những gì đang xảy ra, cộng với các nil giúp chúng tôi xác định các mô phỏng. Câu trả lời khác sử dụng rất nhiều hoạt động đúc bit và không an toàn có vẻ không phải là Swiftian, vì vậy tôi cung cấp điều này.

func getInterfaces() -> Bool { 
     guard let unwrappedCFArrayInterfaces = CNCopySupportedInterfaces() else { 
      print("this must be a simulator, no interfaces found") 
      return false 
     } 
     guard let swiftInterfaces = (unwrappedCFArrayInterfaces as NSArray) as? [String] else { 
      print("System error: did not come back as array of Strings") 
      return false 
     } 
     for interface in swiftInterfaces { 
      print("Looking up SSID info for \(interface)") // en0 
      guard let unwrappedCFDictionaryForInterface = CNCopyCurrentNetworkInfo(interface) else { 
       print("System error: \(interface) has no information") 
       return false 
      } 
      guard let SSIDDict = (unwrappedCFDictionaryForInterface as NSDictionary) as? [String: AnyObject] else { 
       print("System error: interface information is not a string-keyed dictionary") 
       return false 
      } 
      for d in SSIDDict.keys { 
       print("\(d): \(SSIDDict[d]!)") 
      } 
     } 
     return true 
    } 

[Ngoài ra, sau 10 phút, tự động hoàn tất bắt đầu hoạt động cho CNxxx. Rõ ràng một sợi nền đang bận rộn tiêu hóa hàng ngàn globals trong SourceKit]

Output về thành công:.

SSIDDATA: < 57696c6d 79>

BSSID: 12: 34: 56: 78: 9a: bc

SSID: YourSSIDHere

+0

takeRetainedValue là gì()? – Nilesh

+0

Tính tương thích với các API C cũ không sử dụng các đối tượng được ARC duy trì. Nó đưa đối tượng vào quản lý theo ARC để nó sẽ tự động được giải phóng khi bạn không còn cần đến nó nữa. http://stackoverflow.com/questions/29048826/when-to-use-takeunretainedvalue-or-takeretainedvalue-to-retrieve-unmanaged-o – BaseZen

+0

Edited cho Swift 2.2 – BaseZen

8

Trong Swift 2.0/iOS 9 CaptiveNetwork API được (gần) đi hoặc khấu hao. Tôi liên lạc với Apple về vấn đề này và tôi nghĩ rằng chúng tôi có thể (hoặc nên) sử dụng NEHotspotHelper để thay thế. Tôi có một phản ứng từ Apple ngày hôm nay: Chúng ta nên tiếp tục sử dụng CaptiveNetwork và hai API có liên quan (thậm chí cứng rắn có đánh dấu khấu hao):

CNCopySupportedInterfaces 
CNCopyCurrentNetworkInfo 

Các braime user posted một cập nhật mã đoạn cho vấn đề này trên Ray Wenderlich forums:

let interfaces:CFArray! = CNCopySupportedInterfaces() 
    for i in 0..<CFArrayGetCount(interfaces){ 
     let interfaceName: UnsafePointer<Void> 
      = CFArrayGetValueAtIndex(interfaces, i) 
     let rec = unsafeBitCast(interfaceName, AnyObject.self) 
     let unsafeInterfaceData = CNCopyCurrentNetworkInfo("\(rec)") 
     if unsafeInterfaceData != nil { 
      let interfaceData = unsafeInterfaceData! as Dictionary! 
      currentSSID = interfaceData["SSID"] as! String 
     } else { 
      currentSSID = "" 
     } 
    } 

Làm việc hoàn hảo cho tôi.

+0

Swift 2 + Xcode 7.2.1 nhắm mục tiêu cấu hình 'Debug' cho kiến trúc 'x86_64' sử dụng 'OS X 10.11' sdk phàn nàn về "Lỗi: 'CNCopyCurrentNetworkInfo' là không có sẵn" mặc dù SystemConfiguration.CaptiveNetwork được nhập khẩu như một khuôn khổ. Bất kỳ đề xuất nào về cách nhận SSID hiện tại? –

+0

Chúng tôi có cần hồ sơ cấp phép từ trung tâm thành viên để truy cập vào các khung công tác này không? Chúng tôi cũng có thể sử dụng chúng để kết nối lại thiết bị với mạng không? –

0

Swift:

import SystemConfiguration.CaptiveNetwork 

func currentSSIDs() -> [String] { 
     guard let interfaceNames = CNCopySupportedInterfaces() as? [String] else { 
      return [] 
     } 
     return interfaceNames.flatMap { name in 
      guard let info = CNCopyCurrentNetworkInfo(name as CFString) as? [String:AnyObject] else { 
       return nil 
      } 
      guard let ssid = info[kCNNetworkInfoKeySSID as String] as? String else { 
       return nil 
      } 
      return ssid 
     } 
    } 

Sau đó print(currentSSIDs()), không làm việc trên mô phỏng, chỉ có các thiết bị thực.

Taken từ https://forums.developer.apple.com/thread/50302

Các vấn đề liên quan