Swift에서 인터넷 연결 가능 여부 확인
스위프트를 이용하여 인터넷 연결이 가능한지 확인할 수 있는 방법이 있습니까?
이것을 할 수 있는 많은 타사 라이브러리가 있다는 것을 알고 있지만 모두 Objective-C로 작성되어 있습니다.스위프트 대안을 찾고 있습니다.
댓글에 언급된 것처럼 스위프트에서 Objective-C 라이브러리를 사용하는 것이 가능하지만, 저는 좀 더 순수한 스위프트 솔루션을 원했습니다.기존의 Apple Reachability 클래스와 다른 타사 라이브러리는 제가 Swift로 번역하기에는 너무 복잡해 보였습니다.구글에서 좀 더 검색해보니 네트워크 가용성을 확인할 수 있는 간단한 방법을 보여주는 기사를 보게 되었습니다.스위프트로 번역을 시작했습니다.많은 난관에 부딪혔지만 StackOverflow의 Martin R 덕분에 해결할 수 있었고 마침내 Swift에서 실행 가능한 솔루션을 얻었습니다.코드는 여기 있습니다.
import Foundation
import SystemConfiguration
public class Reachability {
class func isConnectedToNetwork() -> Bool {
var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(&zeroAddress) {
SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0)).takeRetainedValue()
}
var flags: SCNetworkReachabilityFlags = 0
if SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) == 0 {
return false
}
let isReachable = (flags & UInt32(kSCNetworkFlagsReachable)) != 0
let needsConnection = (flags & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
return isReachable && !needsConnection
}
}
Swift > 3.0의 경우
public class Reachability {
public func isConnectedToNetwork() -> Bool {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
zeroAddress.sin_family = sa_family_t(AF_INET)
guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
SCNetworkReachabilityCreateWithAddress(nil, $0)
}
}) else {
return false
}
var flags: SCNetworkReachabilityFlags = []
if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) {
return false
}
if flags.isEmpty {
return false
}
let isReachable = flags.contains(.reachable)
let needsConnection = flags.contains(.connectionRequired)
return (isReachable && !needsConnection)
}
}
이것은 3G와 WiFi 연결에 모두 적합합니다.나는 그것을 나의 GitHub에도 작업 예시와 함께 업로드 했습니다.
Swift 3.1용 (iOS 10.1)
네트워크 유형(즉, WiFi 또는 WWAN)을 구별하고자 하는 경우:
다음을 사용할 수 있습니다.
func checkWiFi() -> Bool {
let networkStatus = Reachability().connectionStatus()
switch networkStatus {
case .Unknown, .Offline:
return false
case .Online(.WWAN):
print("Connected via WWAN")
return true
case .Online(.WiFi):
print("Connected via WiFi")
return true
}
}
다음은 네트워크 유형을 구분한 전체 도달 가능성 클래스입니다.
import Foundation
import SystemConfiguration
import UIKit
import SystemConfiguration.CaptiveNetwork
public let ReachabilityStatusChangedNotification = "ReachabilityStatusChangedNotification"
public enum ReachabilityType: CustomStringConvertible {
case WWAN
case WiFi
public var description: String {
switch self {
case .WWAN: return "WWAN"
case .WiFi: return "WiFi"
}
}
}
public enum ReachabilityStatus: CustomStringConvertible {
case Offline
case Online(ReachabilityType)
case Unknown
public var description: String {
switch self {
case .Offline: return "Offline"
case .Online(let type): return "Online (\(type))"
case .Unknown: return "Unknown"
}
}
}
public class Reachability {
func connectionStatus() -> ReachabilityStatus {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
guard let defaultRouteReachability = (withUnsafePointer(to: &zeroAddress) {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) { zeroSockAddress in
SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
}
}) else {
return .Unknown
}
var flags : SCNetworkReachabilityFlags = []
if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) {
return .Unknown
}
return ReachabilityStatus(reachabilityFlags: flags)
}
func monitorReachabilityChanges() {
let host = "google.com"
var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
let reachability = SCNetworkReachabilityCreateWithName(nil, host)!
SCNetworkReachabilitySetCallback(reachability, { (_, flags, _) in
let status = ReachabilityStatus(reachabilityFlags: flags)
NotificationCenter.default.post(name: NSNotification.Name(rawValue: ReachabilityStatusChangedNotification), object: nil, userInfo: ["Status": status.description])}, &context)
SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetMain(), CFRunLoopMode.commonModes.rawValue)
}
}
extension ReachabilityStatus {
public init(reachabilityFlags flags: SCNetworkReachabilityFlags) {
let connectionRequired = flags.contains(.connectionRequired)
let isReachable = flags.contains(.reachable)
let isWWAN = flags.contains(.isWWAN)
if !connectionRequired && isReachable {
if isWWAN {
self = .Online(.WWAN)
} else {
self = .Online(.WiFi)
}
} else {
self = .Offline
}
}
}
내가 더 좋은 방법을...
이 코드로 클래스를 만들어야 합니다.
import Foundation
public class Reachability {
class func isConnectedToNetwork()->Bool{
var Status:Bool = false
let url = NSURL(string: "http://google.com/")
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "HEAD"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
request.timeoutInterval = 10.0
var response: NSURLResponse?
var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: nil) as NSData?
if let httpResponse = response as? NSHTTPURLResponse {
if httpResponse.statusCode == 200 {
Status = true
}
}
return Status
}
}
그런 다음 이 코드를 사용하여 프로젝트의 어느 곳에서나 인터넷 연결을 확인할 수 있습니다.
if Reachability.isConnectedToNetwork() == true {
println("Internet connection OK")
} else {
println("Internet connection FAILED")
}
아주 쉽습니다!
*이 방법은 Vikram Pote의 답변을 기반으로 합니다!
SWIFT 3: 와이파이 및 인터넷 연결 확인:
import Foundation
import SystemConfiguration
public class Reachability {
public func isConnectedToNetwork() -> Bool {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
zeroAddress.sin_family = sa_family_t(AF_INET)
guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress, {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
SCNetworkReachabilityCreateWithAddress(nil, $0)
}
}) else {
return false
}
var flags: SCNetworkReachabilityFlags = []
if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) {
return false
}
let isReachable = flags.contains(.reachable)
let needsConnection = flags.contains(.connectionRequired)
return (isReachable && !needsConnection)
}
}
사용방법:
if Reachability.isConnectedToNetwork() == true {
print("Connected to the internet")
// Do something
} else {
print("No internet connection")
// Do something
}
sendSynchronousRequest가 더 이상 사용되지 않기 때문에 시도했지만 응답이 끝나기 전에 'return Status'가 호출되었습니다.
이 답변은 잘 먹히나요, 스위프트와 인터넷 연결이 되는지 확인해보세요.
어쨌든 내가 시도한 것은 다음과 같습니다.
import Foundation
public class Reachability {
class func isConnectedToNetwork()->Bool{
var Status:Bool = false
let url = NSURL(string: "http://google.com/")
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "HEAD"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
request.timeoutInterval = 10.0
let session = NSURLSession.sharedSession()
session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
print("data \(data)")
print("response \(response)")
print("error \(error)")
if let httpResponse = response as? NSHTTPURLResponse {
print("httpResponse.statusCode \(httpResponse.statusCode)")
if httpResponse.statusCode == 200 {
Status = true
}
}
}).resume()
return Status
}
}
아래 답변을 사용할 수도 있습니다.
func checkInternet(flag:Bool, completionHandler:(internet:Bool) -> Void)
{
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
let url = NSURL(string: "http://www.google.com/")
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "HEAD"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
request.timeoutInterval = 10.0
NSURLConnection.sendAsynchronousRequest(request, queue:NSOperationQueue.mainQueue(), completionHandler:
{(response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
UIApplication.sharedApplication().networkActivityIndicatorVisible = false
let rsp = response as NSHTTPURLResponse?
completionHandler(internet:rsp?.statusCode == 200)
})
}
func yourMethod()
{
self.checkInternet(false, completionHandler:
{(internet:Bool) -> Void in
if (internet)
{
// "Internet" mean Google
}
else
{
// No "Internet" no Google
}
})
}
Swift 5의 경우:
import Network
let monitor = NWPathMonitor()
func checkInterwebs() -> Bool {
var status = false
monitor.pathUpdateHandler = { path in
if path.status == .satisfied {
status = true // online
}
}
return status
}
스위프트 4
if isInternetAvailable() {
print("if called Internet Connectivity success \(isInternetAvailable())");
} else {
print("else called Internet Connectivity success \(isInternetAvailable())");
}
func isInternetAvailable() -> Bool {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
}
}
var flags = SCNetworkReachabilityFlags()
if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
return false
}
let isReachable = flags.contains(.reachable)
let needsConnection = flags.contains(.connectionRequired)
// print(isReachable && !needsConnection)
return (isReachable && !needsConnection)
}
프로젝트에서 Alamofire를 사용하는 경우 다음 샘플 기능을 사용할 수 있습니다.
import Alamofire
class Network {
func isConnected(_ complition: @escaping(Bool) -> Void) {
let retVal = NetworkReachabilityManager()!.isReachable
complition(retVal)
}
}
연결되어 있는지 여부만 알고 Swift를 사용하는 경우UI:
서비스:
import Foundation
import Network
class ConnectionService: ObservableObject {
@Published var connected: Bool = false
private var monitor: NWPathMonitor
init() {
monitor = NWPathMonitor()
monitor.pathUpdateHandler = { [weak self] path in
switch path.status {
case .satisfied:
self?.connected = true
case .unsatisfied, .requiresConnection:
self?.connected = false
@unknown default:
self?.connected = false
}
}
monitor.start(queue: DispatchQueue.main)
}
}
용도:
// step 1: add in your App struct
@StateObject var internet = ConnectionService()
// step 2: add this modifier to your top level view
.environmentObject(internet)
// step 3: add this in any child view
@EnvironmentObject var internet: ConnectionService
// step 4: example usage in that child view
Text("internet: \(internet.connected ? "true" : "false")")
SWIFT 3 : 3G & Wi-Fi 연결 확인
DispatchQueue.main.async {
let url = URL(string: "https://www.google.com")!
let request = URLRequest(url: url)
let task = URLSession.shared.dataTask(with: request) {data, response, error in
if error != nil {
// do something here...
print("Internet Connection not Available!")
}
else if let httpResponse = response as? HTTPURLResponse {
if httpResponse.statusCode == 200 {
// do something here...
print("Internet Connection OK")
}
print("statusCode: \(httpResponse.statusCode)")
}
}
task.resume()
}
언급URL : https://stackoverflow.com/questions/25398664/check-for-internet-connection-availability-in-swift
'source' 카테고리의 다른 글
C/C++에서 Windows 기능을 후크하려면 어떻게 해야 합니까? (0) | 2023.09.11 |
---|---|
Django 앱을 Mariadb에서 Postgresql로 전환 (0) | 2023.09.11 |
조건부 서식(공백이 아닌 경우) (0) | 2023.09.06 |
자바스크립트 터치 디바이스용 드래그 앤 드롭 (0) | 2023.09.06 |
jQuery로 클릭 이벤트를 하는 동안 키가 눌렸는지 확인하려면 어떻게 해야 합니까? (0) | 2023.09.06 |