Checking Internet Connection in SWIFT - swift

what’s the easiest way to check internet connection?
I found this code example but is the most efficient way in Xcode11/Swift5?
I only need to check for connection under a button press before calling my function which downloads from the internet. So a simple check before calling my function will do it. Is this constant monitoring the most efficient? Or should I use something directly under my button press.
import Network
class ViewController: UIViewController {
let monitor = NWPathMonitor()
let queue = DispatchQueue(label: "InternetConnectionMonitor")
override func viewDidLoad() {
monitor.pathUpdateHandler = { pathUpdateHandler in
if pathUpdateHandler.status == .satisfied {
print("Internet connection is on.")
} else {
print("There's no internet connection.")
}
}
monitor.start(queue: queue)
}
}

I used for this the Reachability framework by ashleymills:
https://github.com/ashleymills/Reachability.swift
You just need to import via:
import ReachabilitySwift
Then just inside your view controller you can do e.g.:
let reachability = try! Reachability()
if reachability.isReachable {
print("Internet connection is on.")
}
See the ReadMe of the repo for more examples on how to use the closures.
Beware that it is an external framework and might not be up to date with the latest Swift version.

import SystemConfiguration:
import SystemConfiguration
before the viewController class add this class:
public class Reachability {
class func isConnected() -> Bool {
var noAddress = 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))
noAddress.sin_len = UInt8(MemoryLayout.size(ofValue: noAddress))
noAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(to: &noAddress) {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {noSockAddress in
SCNetworkReachabilityCreateWithAddress(nil, noSockAddress)
}
}
var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
return false
}
let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
let ret = (isReachable && !needsConnection)
return ret
}
}
Now in viewDidLoad check the connection:
if Reachability.isConnected(){
print("Internet Connection is ON")
} else {
print("Internet Connection OFF")
}

Related

How to check internet availability for both wifi and cellular data in iOS swift

i am checking network availability for both cellular data and wifi.. but below code working for only wifi i need to check internet availability for cellular data
code:
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(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 = SCNetworkReachabilityFlags(rawValue: 0)
if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
return false
}
/* Only Working for WIFI
let isReachable = flags == .reachable
let needsConnection = flags == .connectionRequired
return isReachable && !needsConnection
*/
// Working for Cellular and WIFI
let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
let ret = (isReachable && !needsConnection)
return ret
}
}
import SystemConfiguration
import Foundation
class TableviewViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
override func viewDidAppear(_ animated: Bool) {
if Reachability.isConnectedToNetwork() == true
{
print("Connected")
}
else
{
let controller = UIAlertController(title: "No Internet Detected", message: "This app requires an Internet connection", preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .default, handler: nil)
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
controller.addAction(ok)
controller.addAction(cancel)
present(controller, animated: true, completion: nil)
}
}
with the above code i am able to check wifi availability but not cellular data.. how to check cellular data availability in iPHONE.. please suggest with code

Get IP address of Apple Watch

How to access IP address of Apple Watch programatically? I have used UIDevice extension in iOS for finding IP. This is an extension of UIDevice but which is not supported in watchOS what could be the other option?
extension UIDevice {
private struct InterfaceNames {
static let wifi = ["en0"]
static let wired = ["en2", "en3", "en4"]
static let cellular = ["pdp_ip0","pdp_ip1","pdp_ip2","pdp_ip3"]
static let supported = wifi + wired + cellular
}
func ipAddress() -> String? {
var ipAddress: String?
var ifaddr: UnsafeMutablePointer<ifaddrs>?
if getifaddrs(&ifaddr) == 0 {
var pointer = ifaddr
while pointer != nil {
defer { pointer = pointer?.pointee.ifa_next }
guard
let interface = pointer?.pointee,
interface.ifa_addr.pointee.sa_family == UInt8(AF_INET) || interface.ifa_addr.pointee.sa_family == UInt8(AF_INET6),
let interfaceName = interface.ifa_name,
let interfaceNameFormatted = String(cString: interfaceName, encoding: .utf8),
InterfaceNames.supported.contains(interfaceNameFormatted)
else { continue }
var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
getnameinfo(interface.ifa_addr,
socklen_t(interface.ifa_addr.pointee.sa_len),
&hostname,
socklen_t(hostname.count),
nil,
socklen_t(0),
NI_NUMERICHOST)
guard
let formattedIpAddress = String(cString: hostname, encoding: .utf8),
!formattedIpAddress.isEmpty
else { continue }
ipAddress = formattedIpAddress
break
}
freeifaddrs(ifaddr)
}
return ipAddress
}
}
UIDevice.current.ipAddress()
How is this possible in watchOS

'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' [duplicate]

I'm trying to convert this code snippet to Swift. I'm struggling on getting off the ground due to some difficulties.
- (BOOL) connectedToNetwork
{
// Create zero addy
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
// Recover reachability flags
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
SCNetworkReachabilityFlags flags;
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
CFRelease(defaultRouteReachability);
if (!didRetrieveFlags)
{
return NO;
}
BOOL isReachable = flags & kSCNetworkFlagsReachable;
BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
return (isReachable && !needsConnection) ? YES : NO;
}
The first and the main issue I'm having is on how to define and work with C structs. In the first line (struct sockaddr_in zeroAddress;) of the above code, I think they're defining a instance called zeroAddress from the struct sockaddr_in(?), I assume. I tried declaring a var like this.
var zeroAddress = sockaddr_in()
But I get the error Missing argument for parameter 'sin_len' in call which is understandable because that struct takes a number of arguments. So I tried again.
var zeroAddress = sockaddr_in(sin_len: sizeof(zeroAddress), sin_family: AF_INET, sin_port: nil, sin_addr: nil, sin_zero: nil)
As expected I get some other error Variable used within its own initial value. I understand the cause of that error too. In C, they declare the instance first and then fill up the parameters. Its not possible in Swift as far as I know. So I'm truly lost at this point on what to do.
I read Apple's official document on interacting with C APIs in Swift but it has no examples in working with structs.
Can anyone please help me out here? I'd really appreciate it.
Thank you.
UPDATE: Thanks to Martin I was able to get past the initial problem. But still Swift ain't making it easier for me. I'm getting multiple new errors.
func connectedToNetwork() -> 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)
var defaultRouteReachability: SCNetworkReachabilityRef = SCNetworkReachabilityCreateWithAddress(UnsafePointer<Void>, UnsafePointer<zeroAddress>) // 'zeroAddress' is not a type
var flags = SCNetworkReachabilityFlags()
let didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, UnsafeMutablePointer<flags>) // 'flags' is not a type
defaultRouteReachability.dealloc(1) // 'SCNetworkReachabilityRef' does not have a member named 'dealloc'
if didRetrieveFlags == false {
return false
}
let isReachable: Bool = flags & kSCNetworkFlagsReachable // Cannot invoke '&' with an argument list of type '(#lvalue UInt32, Int)'
let needsConnection: Bool = flags & kSCNetworkFlagsConnectionRequired // Cannot invoke '&' with an argument list of type '(#lvalue UInt32, Int)'
return (isReachable && !needsConnection) ? true : false
}
EDIT 1: Okay I changed this line to this,
var defaultRouteReachability: SCNetworkReachabilityRef = SCNetworkReachabilityCreateWithAddress(UnsafePointer<Void>(), &zeroAddress)
The new error I'm getting at this line is 'UnsafePointer' is not convertible to 'CFAllocator'. How to you pass NULL in Swift?
Also I changed this line and the error is gone now.
let didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags)
EDIT 2: I passed nil in this line after seeing this question. But that answer contradicts with the answer here. It says there is no equivalent to NULL in Swift.
var defaultRouteReachability: SCNetworkReachabilityRef = SCNetworkReachabilityCreateWithAddress(nil, &zeroAddress)
Anyway I get a new error saying 'sockaddr_in' is not identical to 'sockaddr' at the above line.
(This answer was extended repeatedly due to changes in the Swift language, which made it a bit confusing. I have now rewritten it and removed everything which refers to Swift 1.x. The older code can
be found in the edit history if somebody needs it.)
This is how you would do it in Swift 2.0 (Xcode 7):
import SystemConfiguration
func connectedToNetwork() -> Bool {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
guard let defaultRouteReachability = withUnsafePointer(&zeroAddress, {
SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($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)
}
Explanations:
As of Swift 1.2 (Xcode 6.3), imported C structs have a default initializer in Swift, which initializes all of the struct's fields to zero, so the socket address structure can be initialized with
var zeroAddress = sockaddr_in()
sizeofValue() gives the size of this structure, this has
to be converted to UInt8 for sin_len:
zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
AF_INET is an Int32, this has to be converted to the correct type for sin_family:
zeroAddress.sin_family = sa_family_t(AF_INET)
withUnsafePointer(&zeroAddress) { ... } passes the address of the
structure to the closure where it is used as argument for
SCNetworkReachabilityCreateWithAddress(). The UnsafePointer($0)
conversion is needed because that function expects a pointer to
sockaddr, not sockaddr_in.
The value returned from withUnsafePointer() is the return value
from SCNetworkReachabilityCreateWithAddress() and that has the
type SCNetworkReachability?, i.e. it is an optional.
The guard let statement (a new feature in Swift 2.0) assigns the unwrapped value to the defaultRouteReachability variable if it is
not nil. Otherwise the else block is executed and the function
returns.
As of Swift 2, SCNetworkReachabilityCreateWithAddress() returns
a managed object. You don't have to release it explicitly.
As of Swift 2, SCNetworkReachabilityFlags conforms to
OptionSetType which has a set-like interface. You create an
empty flags variable with
var flags : SCNetworkReachabilityFlags = []
and check for flags with
let isReachable = flags.contains(.Reachable)
let needsConnection = flags.contains(.ConnectionRequired)
The second parameter of SCNetworkReachabilityGetFlags has the type
UnsafeMutablePointer<SCNetworkReachabilityFlags>, which means that you have to
pass the address of the flags variable.
Note also that registering a notifier callback is possible as of
Swift 2, compare Working with C APIs from Swift and Swift 2 - UnsafeMutablePointer<Void> to object.
Update for Swift 3/4:
Unsafe pointers cannot be simply be converted to a pointer of a
different type anymore (see - SE-0107 UnsafeRawPointer API). Here the updated code:
import SystemConfiguration
func connectedToNetwork() -> 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)
}
Swift 3, IPv4, IPv6
Based on the Martin R's answer:
import SystemConfiguration
func isConnectedToNetwork() -> Bool {
guard let flags = getFlags() else { return false }
let isReachable = flags.contains(.reachable)
let needsConnection = flags.contains(.connectionRequired)
return (isReachable && !needsConnection)
}
func getFlags() -> SCNetworkReachabilityFlags? {
guard let reachability = ipv4Reachability() ?? ipv6Reachability() else {
return nil
}
var flags = SCNetworkReachabilityFlags()
if !SCNetworkReachabilityGetFlags(reachability, &flags) {
return nil
}
return flags
}
func ipv6Reachability() -> SCNetworkReachability? {
var zeroAddress = sockaddr_in6()
zeroAddress.sin6_len = UInt8(MemoryLayout<sockaddr_in>.size)
zeroAddress.sin6_family = sa_family_t(AF_INET6)
return withUnsafePointer(to: &zeroAddress, {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
SCNetworkReachabilityCreateWithAddress(nil, $0)
}
})
}
func ipv4Reachability() -> SCNetworkReachability? {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
zeroAddress.sin_family = sa_family_t(AF_INET)
return withUnsafePointer(to: &zeroAddress, {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
SCNetworkReachabilityCreateWithAddress(nil, $0)
}
})
}
Swift 5, Using NWPathMonitor
import Network
func configureNetworkMonitor(){
let monitor = NWPathMonitor()
monitor.pathUpdateHandler = { path in
if path.status != .satisfied {
print("not connected")
}
else if path.usesInterfaceType(.cellular) {
print("Cellular")
}
else if path.usesInterfaceType(.wifi) {
print("WIFI")
}
else if path.usesInterfaceType(.wiredEthernet) {
print("Ethernet")
}
else if path.usesInterfaceType(.other){
print("Other")
}else if path.usesInterfaceType(.loopback){
print("Loop Back")
}
}
monitor.start(queue: DispatchQueue.global(qos: .background))
}
This has nothing to do with Swift, but the best solution is to NOT use Reachability to determine whether the network is online. Just make your connection and handle errors if it fails. Making a connection can at times fire up the dormant offline radios.
The one valid use of Reachability is to use it to notify you when a network transitions from offline to online. At that point you should retry failed connections.
The best solution is to use ReachabilitySwift class, written in Swift 2, and uses SCNetworkReachabilityRef.
Simple and easy:
let reachability = Reachability.reachabilityForInternetConnection()
reachability?.whenReachable = { reachability in
// keep in mind this is called on a background thread
// and if you are updating the UI it needs to happen
// on the main thread, like this:
dispatch_async(dispatch_get_main_queue()) {
if reachability.isReachableViaWiFi() {
print("Reachable via WiFi")
} else {
print("Reachable via Cellular")
}
}
}
reachability?.whenUnreachable = { reachability in
// keep in mind this is called on a background thread
// and if you are updating the UI it needs to happen
// on the main thread, like this:
dispatch_async(dispatch_get_main_queue()) {
print("Not reachable")
}
}
reachability?.startNotifier()
Working like a charm.
Enjoy
A SwiftUI take on Mithra Sigam's solution above:
import SwiftUI
import Network
class NetworkReachabilityManager: ObservableObject {
#Published var networkPathStatus: NWPath.Status
#Published var availableInterfaces: [NWInterface]
let monitor = NWPathMonitor()
init() {
monitor.start(queue: DispatchQueue.global(qos: .background))
let currentPath = monitor.currentPath
networkPathStatus = currentPath.status
availableInterfaces = currentPath.availableInterfaces
monitor.pathUpdateHandler = { [self] networkPath in
DispatchQueue.main.async {
networkPathStatus = networkPath.status
availableInterfaces = networkPath.availableInterfaces
}
}
}
deinit {
monitor.cancel()
}
}
updated juanjo's answer to create singleton instance
import Foundation
import SystemConfiguration
final class Reachability {
private init () {}
class var shared: Reachability {
struct Static {
static let instance: Reachability = Reachability()
}
return Static.instance
}
func isConnectedToNetwork() -> Bool {
guard let flags = getFlags() else { return false }
let isReachable = flags.contains(.reachable)
let needsConnection = flags.contains(.connectionRequired)
return (isReachable && !needsConnection)
}
private func getFlags() -> SCNetworkReachabilityFlags? {
guard let reachability = ipv4Reachability() ?? ipv6Reachability() else {
return nil
}
var flags = SCNetworkReachabilityFlags()
if !SCNetworkReachabilityGetFlags(reachability, &flags) {
return nil
}
return flags
}
private func ipv6Reachability() -> SCNetworkReachability? {
var zeroAddress = sockaddr_in6()
zeroAddress.sin6_len = UInt8(MemoryLayout<sockaddr_in>.size)
zeroAddress.sin6_family = sa_family_t(AF_INET6)
return withUnsafePointer(to: &zeroAddress, {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
SCNetworkReachabilityCreateWithAddress(nil, $0)
}
})
}
private func ipv4Reachability() -> SCNetworkReachability? {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
zeroAddress.sin_family = sa_family_t(AF_INET)
return withUnsafePointer(to: &zeroAddress, {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
SCNetworkReachabilityCreateWithAddress(nil, $0)
}
})
}
}
Usage
if Reachability.shared.isConnectedToNetwork(){
}
This is in Swift 4.0
I am using this framework https://github.com/ashleymills/Reachability.swift
And Install Pod ..
In AppDelegate
var window: UIWindow?
var reachability = InternetReachability()!
var reachabilityViewController : UIViewController? = nil
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
reachabilityChecking()
return true
}
extension AppDelegate {
func reachabilityChecking() {
reachability.whenReachable = { reachability in
DispatchQueue.main.async {
print("Internet is OK!")
if reachability.connection != .none && self.reachabilityViewController != nil {
}
}
}
reachability.whenUnreachable = { _ in
DispatchQueue.main.async {
print("Internet connection FAILED!")
let storyboard = UIStoryboard(name: "Reachability", bundle: Bundle.main)
self.reachabilityViewController = storyboard.instantiateViewController(withIdentifier: "ReachabilityViewController")
let rootVC = self.window?.rootViewController
rootVC?.present(self.reachabilityViewController!, animated: true, completion: nil)
}
}
do {
try reachability.startNotifier()
} catch {
print("Could not start notifier")
}
}
}
The reachabilityViewController screen will appear if internet is not there

Swift2, Call swift function in CFSocketCallBack - EXEC_BAD_ACCESS

I'm trying to write a socket server app for Mac OSX with Xcode:7.2.1 in Swift2.1.1. referring to CocoaEcho sample code.
But I cannot call a swift function in the socketCallBack function.
My code is here. I'm passing the self based on the answer at Swift 2 - UnsafeMutablePointer to object. And I think the part of the code is working ok.
class myServer: NSObject {
// sockets
private var socketipv4: CFSocket!
private var socketipv6: CFSocket!
// Connections
var connections = Set<SPFConnection>()
func start(address: String) -> Bool {
var sockCtxt = CFSocketContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
sockCtxt.info = UnsafeMutablePointer(unsafeAddressOf(self))
// create socket with CFSocketCreate
socketipv4 = CFSocketCreate(
kCFAllocatorDefault,
PF_INET,
SOCK_STREAM,
IPPROTO_TCP,
kCFSocketAutomaticallyReenableAcceptCallBack,
socketCallBack,
&sockCtxt)
// ipv4
var sin = sockaddr_in() // = initStruct()
let server_addr_size = socklen_t(INET_ADDRSTRLEN)
sin.sin_len = UInt8(server_addr_size)
sin.sin_family = sa_family_t(AF_INET)
sin.sin_port = UInt16(9999).bigEndian
sin.sin_addr.s_addr = inet_addr(address)
let sinData = NSData(bytes: &sin, length: sizeof(sockaddr_in))
let ptr = UnsafePointer<UInt8>(sinData.bytes)
let sincfd = CFDataCreate(kCFAllocatorDefault, ptr, sizeof(sockaddr_in))
let ipv4SocketError: CFSocketError = CFSocketSetAddress(socketipv4, sincfd)
switch ipv4SocketError {
case .Success:
print("ipv4 Success")
default:
print("ipv4 error = \(ipv4SocketError.rawValue)")
return false
}
let socketSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socketipv4, 0)
CFRunLoopAddSource(CFRunLoopGetCurrent(), socketSource, kCFRunLoopDefaultMode)
return true
}
// CFSocket call back
var socketCallBack : #convention(c)(CFSocket!, CFSocketCallBackType, CFData!, UnsafePointer<Void>, UnsafeMutablePointer<Void>) -> Void = {
(socketRef, callbackType, address, data, info) in
print("acceptConnection callback-ed") // \(socketRef), \(callbackType), \(address), \(data),\(info)")
var tempData: CFSocketNativeHandle = 0
var anNSData:NSData = NSData(bytes: data, length: sizeofValue(data))
anNSData.getBytes(&tempData, length: sizeof(CFSocketNativeHandle))
var tempAry = [UnsafeMutablePointer<Void>]()
tempAry.append(info)
if callbackType == CFSocketCallBackType.AcceptCallBack {
let server = unsafeBitCast(info, myServer.self)
// **** EXEC_BAD_ACCESS, code=2 ***** //
server.acceptConnection(tempData)
} else {
print("callbacktype = \(callbackType.rawValue)")
}
}
func acceptConnection(data: CFSocketNativeHandle) {
print("acceptConnection called")
var readStream: Unmanaged<CFReadStream>?
var writeStream: Unmanaged<CFWriteStream>?
CFStreamCreatePairWithSocket(kCFAllocatorDefault, data, &readStream, &writeStream)
if readStream != nil && writeStream != nil {
CFReadStreamSetProperty(readStream!.takeUnretainedValue(), kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue)
CFWriteStreamSetProperty(writeStream!.takeUnretainedValue(), kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue)
let connection = SPFConnection()
connection.inputStream = readStream!.takeRetainedValue()
connection.outputStream = writeStream!.takeRetainedValue()
if connection.open() {
connections.insert(connection)
}
}
}
}
I'm getting EXEC_BAD_ACCESS code=2 at the code server.acceptConnection(tempData).
Debugger shows same pointer for both info and server, which should mean info(self) is properly assigned to server.
But EXEC_BAD_ACCESS seems to mean self is no longer available.
I'm struggling to find a solution. If anyone could give me any advise,
it'd be very much appreciated.
Thanks in advance for your help.
I'll admit I don't know much about using these lower level C conventions, but since the callback function is part of your class, can't just say self.acceptConnection(tempData)?

Check network status in Swift, Could not find an overload for '~=' that accepts the supplied arguments

I'm using Reachability.h library to check the network status in my swift application.
I'm having this issue in the "cases" lines:
Could not find an overload for '~=' that accepts the supplied
arguments
How can I solve it ?
func checkNetworkStatus(){
var reachability = Reachability()
var internetReachable = Reachability(hostName: "www.google.es")
var status: NetworkStatus = internetReachable.currentReachabilityStatus()
switch(status){
case NotReachable:
println("No connection")
case ReachableViaWiFi:
println("wifi")
case ReachableViaWWAN:
println("Wwan")
}
}
Solved
I've solved with:
status.value
returns an integer:
0 : no connection
1 : wifi
2 : wwan
The simplest solution is to replace the NetworkStatus declaration with the following:
typedef NS_ENUM(NSInteger, NetworkStatus) {
NotReachable = 0,
ReachableViaWiFi,
ReachableViaWWAN
};
Apple uses the NS_ENUM and NS_OPTION macros to convert enums to Swift. However, the enum is not declared using this macro and it is not possible to convert it directly to Swift.
Another solution is to add (pattern matching for NetworkStatus)
func ~=(a: NetworkStatus, b : NetworkStatus) -> Bool {
return (a.value == b.value)
}
but note you will need a default: branch in the switch, too.
Try this
import Foundation
import SystemConfiguration
public class ConectionReachability
{
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) ? true : false
}
}