How to include ifaddrs.h - ios

i have the following issue:
i wanna to get the ip address from my app iOS.
But I get error when trying to import from swift
CODE:
module.modulemap
module ifaddrs [system] [extern_c] {
header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/ifaddrs.h"
export *
}
module net [system] [extern_c] {
module types {
header "/usr/include/sys/types.h"
export *
}
module if_dl {
header "/usr/include/net/if_dl.h"
export *
}
}
Bridging-header
#include <ifaddrs.h>
#include <net/if_dl.h>
import and functions
import ifaddrs
func getIFAddresses() -> [String] {
var addresses = [String]()
// Get list of all interfaces on the local machine:
var ifaddr : UnsafeMutablePointer<ifaddrs> = nil
if getifaddrs(&ifaddr) == 0 {
// For each interface ...
for (var ptr = ifaddr; ptr != nil; ptr = ptr.memory.ifa_next) {
let flags = Int32(ptr.memory.ifa_flags)
var addr = ptr.memory.ifa_addr.memory
// Check for running IPv4, IPv6 interfaces. Skip the loopback interface.
if (flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING) {
if addr.sa_family == UInt8(AF_INET) || addr.sa_family == UInt8(AF_INET6) {
// Convert interface address to a human readable string:
var hostname = [CChar](count: Int(NI_MAXHOST), repeatedValue: 0)
if (getnameinfo(&addr, socklen_t(addr.sa_len), &hostname, socklen_t(hostname.count),
nil, socklen_t(0), NI_NUMERICHOST) == 0) {
if let address = String.fromCString(hostname) {
addresses.append(address)
}
}
}
}
}
freeifaddrs(ifaddr)
}
return addresses
}
func getDataUsage() -> [UInt32] {
var ifaddr : UnsafeMutablePointer<ifaddrs> = nil
var networkData: UnsafeMutablePointer<if_data>! = nil
var wifiDataSent:UInt32 = 0
var wifiDataReceived:UInt32 = 0
var wwanDataSent:UInt32 = 0
var wwanDataReceived:UInt32 = 0
if getifaddrs(&ifaddr) == 0 {
for (var ptr = ifaddr; ptr != nil; ptr = ptr.memory.ifa_next) {
let name = String.fromCString(ptr.memory.ifa_name)
let flags = Int32(ptr.memory.ifa_flags)
var addr = ptr.memory.ifa_addr.memory
if addr.sa_family == UInt8(AF_LINK) {
if name?.hasPrefix("en") == true {
networkData = unsafeBitCast(ptr.memory.ifa_data, UnsafeMutablePointer<if_data>.self)
wifiDataSent += networkData.memory.ifi_obytes
wifiDataReceived += networkData.memory.ifi_ibytes
}
if name?.hasPrefix("pdp_ip") == true {
networkData = unsafeBitCast(ptr.memory.ifa_data, UnsafeMutablePointer<if_data>.self)
wwanDataSent += networkData.memory.ifi_obytes
wwanDataReceived += networkData.memory.ifi_ibytes
}
}
}
freeifaddrs(ifaddr)
}
return [wifiDataSent, wifiDataReceived, wwanDataSent, wwanDataReceived]
}

Related

Getting the Local IP Address from iPhone, Sometimes it doesn't work, why?

I want to get the local IP address of the iPhone, sometimes it works and show this address:
http://192.168.8.152/home.htm
But sometimes it does't work and show this address:
http://fd4c:d1a1:ee79:6400:f5dd:b93:12b7:2d42/home.htm
What's wrong? How to fix it?
Here is the Swift code:
func getIpAddress() -> String! {
var address: String?
var ifaddr: UnsafeMutablePointer<ifaddrs>? = nil
if getifaddrs(&ifaddr) == 0 {
var ptr = ifaddr
while ptr != nil {
defer { ptr = ptr?.pointee.ifa_next }
let interface = ptr?.pointee
let addrFamily = interface?.ifa_addr.pointee.sa_family
if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {
if let name: String = String(cString: (interface?.ifa_name)!), name == "en0" {
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
)
address = String(cString: hostname)
}
}
}
freeifaddrs(ifaddr)
}
return address as? String ?? ""
}
#IBOutlet weak var lblUrl: UILabel! {
didSet {
sAddr = getIpAddress()
var sLabel : String! = "http://"
sLabel += sAddr
sLabel += "/home.htm"
lblUrl.text = sLabel
}
}

How to get ipaddress when connected to mobile data swift3

I am getting ipaddress of the phone in this way.
func getIPAddress() -> String? {
var address : String?
var ifaddr : UnsafeMutablePointer<ifaddrs>? = nil
if getifaddrs(&ifaddr) == 0 {
var ptr = ifaddr
while ptr != nil {
defer { ptr = ptr?.pointee.ifa_next }
let interface = ptr?.pointee
let addrFamily = interface?.ifa_addr.pointee.sa_family
if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {
if let name:String = String(cString: (interface?.ifa_name)!), name == "en0" {
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)
address = String(cString: hostname)
}
}
}
freeifaddrs(ifaddr)
}
return address
}
But this returns when connected to wifi only. How to get ipaddress when I connected to mobile data.
To get IPAddress of device on turning Wifi or Mobile data ON, use below method :
func getIPAddress() -> String? {
var address : String?
// Get list of all interfaces on the local machine:
var ifaddr : UnsafeMutablePointer<ifaddrs>?
guard getifaddrs(&ifaddr) == 0 else { return nil }
guard let firstAddr = ifaddr else { return nil }
// For each interface ...
for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
let interface = ifptr.pointee
// Check for IPv4 or IPv6 interface:
let addrFamily = interface.ifa_addr.pointee.sa_family
if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {
// Check interface name:
let name = String(cString: interface.ifa_name)
if name == "en0" || name == "pdp_ip0" {
// Convert interface address to a human readable string:
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)
address = String(cString: hostname)
}
}
}
freeifaddrs(ifaddr)
return address
}
Here if name == "en0" || name == "pdp_ip0" works for both Wifi and Mobile data.
Hope will be helping! :)

Check internet connectivity throughout the app by adding observer

I do not want to check internet connectivity on every time the app is open instead want to show the no connection banner in status bar or in navigation bar just like the Facebook app does.
Here is my code:
import SystemConfiguration
public class Reachability {
class func isConnectedToNetwork() -> Bool {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(&zeroAddress) {
SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0))
}
var flags = SCNetworkReachabilityFlags()
if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
return false
}
let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
return (isReachable && !needsConnection)
}
}
Apply a periodic check by using NSTimer
override func viewDidLoad() {
super.viewDidLoad()
//Swift 2.2 selector syntax
var timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: #selector(MyClass.update), userInfo: nil, repeats: true)
}
// must be internal or public.
func update()
{
if(!Reachability.isConnectedToNetwork()){
print("Internet connection not available.");
return
}
}
your Reachability Class
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(kCFAllocatorDefault, UnsafePointer($0))
}
var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
return false
}
let isReachable = flags == .Reachable
let needsConnection = flags == .ConnectionRequired
return isReachable && !needsConnection
}
}
Creating a notificationc object to help notif the app when a change in connectivity is encountered
var reach: Reachability!
do {
reach = try Reachability.reachabilityForInternetConnection()
self.reach!.reachableOnWWAN = false
NSNotificationCenter.defaultCenter().addObserver(self,
selector: "reachabilityChanged:",
name: ReachabilityChangedNotification,
object: nil)
try self.reach!.startNotifier()
} catch {
}
and the function based on which the app behaves
func reachabilityChanged(notification: NSNotification) {
if self.reach!.isReachableViaWiFi() || self.reach!.isReachableViaWWAN() {
print("Service available !!!")
} else {
print("No service available !!!")
}
}
And use this Reachability class
import Foundation
import SystemConfiguration
import Foundation
public enum ReachabilityError: ErrorType {
case FailedToCreateWithAddress(sockaddr_in)
case FailedToCreateWithHostname(String)
case UnableToSetCallback
case UnableToSetDispatchQueue
}
public let ReachabilityChangedNotification = "ReachabilityChangedNotification"
func callback(reachability:SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutablePointer<Void>) {
let reachability = Unmanaged<Reachability>.fromOpaque(COpaquePointer(info)).takeUnretainedValue()
dispatch_async(dispatch_get_main_queue()) {
reachability.reachabilityChanged(flags)
}
}
public class Reachability: NSObject {
public typealias NetworkReachable = (Reachability) -> ()
public typealias NetworkUnreachable = (Reachability) -> ()
public enum NetworkStatus: CustomStringConvertible {
case NotReachable, ReachableViaWiFi, ReachableViaWWAN
public var description: String {
switch self {
case .ReachableViaWWAN:
return "Cellular"
case .ReachableViaWiFi:
return "WiFi"
case .NotReachable:
return "No Connection"
}
}
}
// MARK: - *** Public properties ***
public var whenReachable: NetworkReachable?
public var whenUnreachable: NetworkUnreachable?
public var reachableOnWWAN: Bool
public var notificationCenter = NSNotificationCenter.defaultCenter()
public var currentReachabilityStatus: NetworkStatus {
if isReachable() {
if isReachableViaWiFi() {
return .ReachableViaWiFi
}
if isRunningOnDevice {
return .ReachableViaWWAN
}
}
return .NotReachable
}
public var currentReachabilityString: String {
return "\(currentReachabilityStatus)"
}
private var previousFlags: SCNetworkReachabilityFlags?
// MARK: - *** Initialisation methods ***
required public init(reachabilityRef: SCNetworkReachability) {
reachableOnWWAN = true
self.reachabilityRef = reachabilityRef
}
public convenience init(hostname: String) throws {
let nodename = (hostname as NSString).UTF8String
guard let ref = SCNetworkReachabilityCreateWithName(nil, nodename) else { throw ReachabilityError.FailedToCreateWithHostname(hostname) }
self.init(reachabilityRef: ref)
}
public class func reachabilityForInternetConnection() throws -> Reachability {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
guard let ref = withUnsafePointer(&zeroAddress, {
SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0))
}) else { throw ReachabilityError.FailedToCreateWithAddress(zeroAddress) }
return Reachability(reachabilityRef: ref)
}
public class func reachabilityForLocalWiFi() throws -> Reachability {
var localWifiAddress: sockaddr_in = sockaddr_in(sin_len: __uint8_t(0), sin_family: sa_family_t(0), sin_port: in_port_t(0), sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
localWifiAddress.sin_len = UInt8(sizeofValue(localWifiAddress))
localWifiAddress.sin_family = sa_family_t(AF_INET)
// IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0
let address: UInt32 = 0xA9FE0000
localWifiAddress.sin_addr.s_addr = in_addr_t(address.bigEndian)
guard let ref = withUnsafePointer(&localWifiAddress, {
SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0))
}) else { throw ReachabilityError.FailedToCreateWithAddress(localWifiAddress) }
return Reachability(reachabilityRef: ref)
}
// MARK: - *** Notifier methods ***
public func startNotifier() throws {
guard !notifierRunning else { return }
var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
context.info = UnsafeMutablePointer(Unmanaged.passUnretained(self).toOpaque())
if !SCNetworkReachabilitySetCallback(reachabilityRef!, callback, &context) {
stopNotifier()
throw ReachabilityError.UnableToSetCallback
}
if !SCNetworkReachabilitySetDispatchQueue(reachabilityRef!, reachabilitySerialQueue) {
stopNotifier()
throw ReachabilityError.UnableToSetDispatchQueue
}
// Perform an intial check
dispatch_async(reachabilitySerialQueue) { () -> Void in
let flags = self.reachabilityFlags
self.reachabilityChanged(flags)
}
notifierRunning = true
}
public func stopNotifier() {
defer { notifierRunning = false }
guard let reachabilityRef = reachabilityRef else { return }
SCNetworkReachabilitySetCallback(reachabilityRef, nil, nil)
SCNetworkReachabilitySetDispatchQueue(reachabilityRef, nil)
}
// MARK: - *** Connection test methods ***
public func isReachable() -> Bool {
let flags = reachabilityFlags
return isReachableWithFlags(flags)
}
public func isReachableViaWWAN() -> Bool {
let flags = reachabilityFlags
// Check we're not on the simulator, we're REACHABLE and check we're on WWAN
return isRunningOnDevice && isReachable(flags) && isOnWWAN(flags)
}
public func isReachableViaWiFi() -> Bool {
let flags = reachabilityFlags
// Check we're reachable
if !isReachable(flags) {
return false
}
// Must be on WiFi if reachable but not on an iOS device (i.e. simulator)
if !isRunningOnDevice {
return true
}
// Check we're NOT on WWAN
return !isOnWWAN(flags)
}
// MARK: - *** Private methods ***
private var isRunningOnDevice: Bool = {
#if (arch(i386) || arch(x86_64)) && os(iOS)
return false
#else
return true
#endif
}()
private var notifierRunning = false
private var reachabilityRef: SCNetworkReachability?
private let reachabilitySerialQueue = dispatch_queue_create("uk.co.ashleymills.reachability", DISPATCH_QUEUE_SERIAL)
private func reachabilityChanged(flags: SCNetworkReachabilityFlags) {
guard previousFlags != flags else { return }
if isReachableWithFlags(flags) {
if let block = whenReachable {
block(self)
}
} else {
if let block = whenUnreachable {
block(self)
}
}
notificationCenter.postNotificationName(ReachabilityChangedNotification, object:self)
previousFlags = flags
}
private func isReachableWithFlags(flags: SCNetworkReachabilityFlags) -> Bool {
if !isReachable(flags) {
return false
}
if isConnectionRequiredOrTransient(flags) {
return false
}
if isRunningOnDevice {
if isOnWWAN(flags) && !reachableOnWWAN {
// We don't want to connect when on 3G.
return false
}
}
return true
}
// WWAN may be available, but not active until a connection has been established.
// WiFi may require a connection for VPN on Demand.
private func isConnectionRequired() -> Bool {
return connectionRequired()
}
private func connectionRequired() -> Bool {
let flags = reachabilityFlags
return isConnectionRequired(flags)
}
// Dynamic, on demand connection?
private func isConnectionOnDemand() -> Bool {
let flags = reachabilityFlags
return isConnectionRequired(flags) && isConnectionOnTrafficOrDemand(flags)
}
// Is user intervention required?
private func isInterventionRequired() -> Bool {
let flags = reachabilityFlags
return isConnectionRequired(flags) && isInterventionRequired(flags)
}
private func isOnWWAN(flags: SCNetworkReachabilityFlags) -> Bool {
#if os(iOS)
return flags.contains(.IsWWAN)
#else
return false
#endif
}
private func isReachable(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.Reachable)
}
private func isConnectionRequired(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.ConnectionRequired)
}
private func isInterventionRequired(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.InterventionRequired)
}
private func isConnectionOnTraffic(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.ConnectionOnTraffic)
}
private func isConnectionOnDemand(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.ConnectionOnDemand)
}
func isConnectionOnTrafficOrDemand(flags: SCNetworkReachabilityFlags) -> Bool {
return !flags.intersect([.ConnectionOnTraffic, .ConnectionOnDemand]).isEmpty
}
private func isTransientConnection(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.TransientConnection)
}
private func isLocalAddress(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.IsLocalAddress)
}
private func isDirect(flags: SCNetworkReachabilityFlags) -> Bool {
return flags.contains(.IsDirect)
}
private func isConnectionRequiredOrTransient(flags: SCNetworkReachabilityFlags) -> Bool {
let testcase:SCNetworkReachabilityFlags = [.ConnectionRequired, .TransientConnection]
return flags.intersect(testcase) == testcase
}
private var reachabilityFlags: SCNetworkReachabilityFlags {
guard let reachabilityRef = reachabilityRef else { return SCNetworkReachabilityFlags() }
var flags = SCNetworkReachabilityFlags()
let gotFlags = withUnsafeMutablePointer(&flags) {
SCNetworkReachabilityGetFlags(reachabilityRef, UnsafeMutablePointer($0))
}
if gotFlags {
return flags
} else {
return SCNetworkReachabilityFlags()
}
}
override public var description: String {
var W: String
if isRunningOnDevice {
W = isOnWWAN(reachabilityFlags) ? "W" : "-"
} else {
W = "X"
}
let R = isReachable(reachabilityFlags) ? "R" : "-"
let c = isConnectionRequired(reachabilityFlags) ? "c" : "-"
let t = isTransientConnection(reachabilityFlags) ? "t" : "-"
let i = isInterventionRequired(reachabilityFlags) ? "i" : "-"
let C = isConnectionOnTraffic(reachabilityFlags) ? "C" : "-"
let D = isConnectionOnDemand(reachabilityFlags) ? "D" : "-"
let l = isLocalAddress(reachabilityFlags) ? "l" : "-"
let d = isDirect(reachabilityFlags) ? "d" : "-"
return "\(W)\(R) \(c)\(t)\(i)\(C)\(D)\(l)\(d)"
}
deinit {
stopNotifier()
reachabilityRef = nil
whenReachable = nil
whenUnreachable = nil
}
}
Reachability class used from : https://github.com/ashleymills/Reachability.swift/blob/master/Reachability/Reachability.swift

swift - How to give and parse data from swift?

I'm a socket project in swift. I try to give data that are JSON and Parse them but i have two problem:
1- when I received data are incomplete and return nil value for some bytes.
2- I don't know when The receiving data ends. I receive data in NSSTreamEvent.hasBytesAvailable but never run the NSStreamEvent.EndEncountered and after some moments the code was error and app crashed.
3- My socket 2 times open while I call them 1 time...
There is my code :
import Foundation
class SocketManager : NSObject , NSStreamDelegate {
let ip = "192.168.1.12"
let port = 6969
let introduceStr = ["Type" : 4 , "MobileID" : 2 , "Introduce" : ["ExKey" : 123]]
let jsonParser = JsonMaker() // This is a class for convert string to json
var inputStream : NSInputStream?
var outputStream : NSOutputStream?
var openedSocket = Int()
var total = NSString()
override init() {
openedSocket = 0
}
func openSocket() {
NSStream.getStreamsToHostWithName(ip, port: port, inputStream: &inputStream, outputStream: &outputStream)
let inputStatus : NSStreamStatus = (inputStream?.streamStatus)!
let outputStatus : NSStreamStatus = (outputStream?.streamStatus)!
if inputStatus != NSStreamStatus.Reading && inputStatus != NSStreamStatus.Open && inputStatus != NSStreamStatus.Opening && outputStatus != NSStreamStatus.Writing && outputStatus != NSStreamStatus.Open && outputStatus != NSStreamStatus.Opening {
inputStream?.delegate = self
outputStream?.delegate = self
inputStream?.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)
outputStream?.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)
inputStream?.open()
outputStream?.open()
}
}
func tryOpen() {
inputStream?.close()
outputStream?.close()
inputStream?.removeFromRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)
outputStream?.removeFromRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)
performSelector("openSocket", withObject: nil, afterDelay: 5)
}
func closeSocket() {
inputStream?.removeFromRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)
outputStream?.removeFromRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)
inputStream?.close()
outputStream?.close()
performSelector("openSocket", withObject: nil, afterDelay: 15)
}
func getData(aStream : NSStream) {
if (aStream == inputStream) {
let MAXSIZE = 1024 * 8
var allLength = Int()
var buffer = [UInt8](count: MAXSIZE , repeatedValue: 0)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
while self.inputStream?.hasBytesAvailable == true {
let readBytes = self.inputStream?.read(&buffer, maxLength: sizeofValue(buffer))
allLength += readBytes!
if readBytes > 0 {
let data : NSData = NSData(bytes: &buffer, length: sizeofValue(buffer))
if let str = NSString(data: data, encoding: NSUTF8StringEncoding) {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.total = (self.total as String) + (str as String)
})
}
}
}
})
}
}
func sendData(message : NSString ) -> Int{
if openedSocket == 0 {
return -1
} else {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
let data : NSData = message.dataUsingEncoding(NSUTF8StringEncoding)!
var buffer = [UInt8](count: (data.length), repeatedValue: 0)
data.getBytes(&buffer, length: buffer.count)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.outputStream!.write(&buffer, maxLength: (data.length))
})
})
return 1
}
}
func introduce() {
if openedSocket == 1{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
let str = self.jsonParser.dictionaryToJson(self.introduceStr)
let data : NSData = str.dataUsingEncoding(NSUTF8StringEncoding)!
var buffer = [UInt8](count: (data.length), repeatedValue: 0)
data.getBytes(&buffer, length: buffer.count)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.outputStream!.write(&buffer, maxLength: (data.length))
print("the output introducing is finised")
})
})
} else {
tryOpen()
}
}
func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {
switch eventCode {
case NSStreamEvent.ErrorOccurred :
print("This is the Errorrr")
break
case NSStreamEvent.OpenCompleted :
openedSocket = 1
performSelector("introduce", withObject: nil, afterDelay: 0.3)
break
case NSStreamEvent.HasBytesAvailable :
getData(aStream)
break
case NSStreamEvent.EndEncountered :
print(total)
break
default :
break
}
}
}

How to get local and subnet mask ip address in swift

I need to get the local IP address and subnet mask using Swift code.
Please help me in this. I have some code working in Objective-C. How to get the equivalent code in Swift??
Below I have added Objective-C code:
+(NSDictionary *)getLocalIPAddress{
NSDictionary *dictIPDetails;
NSString *address = #"error";
NSString *netmask = #"error";
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;int success = 0;
// retrieve the current interfaces - returns 0 on success
success = getifaddrs(&interfaces);
if (success == 0)
{
temp_addr = interfaces;
while(temp_addr != NULL)
{
// check if interface is en0 which is the wifi connection on the iPhone
if(temp_addr->ifa_addr->sa_family == AF_INET)
{
if([#(temp_addr->ifa_name) isEqualToString:#"en0"])
{
address = #(inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr));
netmask = #(inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_netmask)->sin_addr));
dictIPDetails = #{LOCAL_IP_ADDR:address,SUBNET_MASK:netmask};
}
}
temp_addr = temp_addr->ifa_next;
}
}
freeifaddrs(interfaces);
return dictIPDetails;
}
I have modified the answer from here to include netmask along with ip.
With the code below you can do something like this:
let ip = getIFAddresses().last!.ip
let netmask = getIFAddresses().last!.netmask
Hope this helps.
struct NetInfo {
let ip: String
let netmask: String
}
// Get the local ip addresses used by this node
func getIFAddresses() -> [NetInfo] {
var addresses = [NetInfo]()
// Get list of all interfaces on the local machine:
var ifaddr : UnsafeMutablePointer<ifaddrs> = nil
if getifaddrs(&ifaddr) == 0 {
// For each interface ...
for (var ptr = ifaddr; ptr != nil; ptr = ptr.memory.ifa_next) {
let flags = Int32(ptr.memory.ifa_flags)
var addr = ptr.memory.ifa_addr.memory
// Check for running IPv4, IPv6 interfaces. Skip the loopback interface.
if (flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING) {
if addr.sa_family == UInt8(AF_INET) || addr.sa_family == UInt8(AF_INET6) {
// Convert interface address to a human readable string:
var hostname = [CChar](count: Int(NI_MAXHOST), repeatedValue: 0)
if (getnameinfo(&addr, socklen_t(addr.sa_len), &hostname, socklen_t(hostname.count),
nil, socklen_t(0), NI_NUMERICHOST) == 0) {
if let address = String.fromCString(hostname) {
var net = ptr.memory.ifa_netmask.memory
var netmaskName = [CChar](count: Int(NI_MAXHOST), repeatedValue: 0)
getnameinfo(&net, socklen_t(net.sa_len), &netmaskName, socklen_t(netmaskName.count),
nil, socklen_t(0), NI_NUMERICHOST) == 0
if let netmask = String.fromCString(netmaskName) {
addresses.append(NetInfo(ip: address, netmask: netmask))
}
}
}
}
}
}
freeifaddrs(ifaddr)
}
return addresses
}
If you need more bells and whistles I have this version of NetInfo which will calculate your network and broadcast addresses as well.
struct NetInfo {
// IP Address
let ip: String
// Netmask Address
let netmask: String
// CIDR: Classless Inter-Domain Routing
var cidr: Int {
var cidr = 0
for number in binaryRepresentation(netmask) {
let numberOfOnes = number.componentsSeparatedByString("1").count - 1
cidr += numberOfOnes
}
return cidr
}
// Network Address
var network: String {
return bitwise(&, net1: ip, net2: netmask)
}
// Broadcast Address
var broadcast: String {
let inverted_netmask = bitwise(~, net1: netmask)
let broadcast = bitwise(|, net1: network, net2: inverted_netmask)
return broadcast
}
private func binaryRepresentation(s: String) -> [String] {
var result: [String] = []
for numbers in (split(s) {$0 == "."}) {
if let intNumber = numbers.toInt() {
if let binary = String(intNumber, radix: 2).toInt() {
result.append(NSString(format: "%08d", binary) as String)
}
}
}
return result
}
private func bitwise(op: (UInt8,UInt8) -> UInt8, net1: String, net2: String) -> String {
let net1numbers = toInts(net1)
let net2numbers = toInts(net2)
var result = ""
for i in 0..<net1numbers.count {
result += "\(op(net1numbers[i],net2numbers[i]))"
if i < (net1numbers.count-1) {
result += "."
}
}
return result
}
private func bitwise(op: UInt8 -> UInt8, net1: String) -> String {
let net1numbers = toInts(net1)
var result = ""
for i in 0..<net1numbers.count {
result += "\(op(net1numbers[i]))"
if i < (net1numbers.count-1) {
result += "."
}
}
return result
}
private func toInts(networkString: String) -> [UInt8] {
return (split(networkString){$0 == "."}).map{UInt8($0.toInt()!)}
}
}
changed the code so it works with swift 3:
struct NetInfo {
let ip: String
let netmask: String
}
// Get the local ip addresses used by this node
class func getIFAddresses() -> [NetInfo] {
var addresses = [NetInfo]()
// Get list of all interfaces on the local machine:
var ifaddr : UnsafeMutablePointer<ifaddrs>? = nil
if getifaddrs(&ifaddr) == 0 {
var ptr = ifaddr;
while ptr != nil {
let flags = Int32((ptr?.pointee.ifa_flags)!)
var addr = ptr?.pointee.ifa_addr.pointee
// Check for running IPv4, IPv6 interfaces. Skip the loopback interface.
if (flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING) {
if addr?.sa_family == UInt8(AF_INET) || addr?.sa_family == UInt8(AF_INET6) {
// Convert interface address to a human readable string:
var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
if (getnameinfo(&addr!, socklen_t((addr?.sa_len)!), &hostname, socklen_t(hostname.count),
nil, socklen_t(0), NI_NUMERICHOST) == 0) {
if let address = String.init(validatingUTF8:hostname) {
var net = ptr?.pointee.ifa_netmask.pointee
var netmaskName = [CChar](repeating: 0, count: Int(NI_MAXHOST))
getnameinfo(&net!, socklen_t((net?.sa_len)!), &netmaskName, socklen_t(netmaskName.count),
nil, socklen_t(0), NI_NUMERICHOST)// == 0
if let netmask = String.init(validatingUTF8:netmaskName) {
addresses.append(NetInfo(ip: address, netmask: netmask))
}
}
}
}
}
ptr = ptr?.pointee.ifa_next
}
freeifaddrs(ifaddr)
}
return addresses
}
Here's Mellson's extended NetInfo re-written for Swift 2 (Hope it save's someone else the time to work it out)
struct NetInfo {
// IP Address
let ip: String
// Netmask Address
let netmask: String
// CIDR: Classless Inter-Domain Routing
var cidr: Int {
var cidr = 0
for number in binaryRepresentation(netmask) {
let numberOfOnes = number.componentsSeparatedByString("1").count - 1
cidr += numberOfOnes
}
return cidr
}
// Network Address
var network: String {
return bitwise(&, net1: ip, net2: netmask)
}
// Broadcast Address
var broadcast: String {
let inverted_netmask = bitwise(~, net1: netmask)
let broadcast = bitwise(|, net1: network, net2: inverted_netmask)
return broadcast
}
private func binaryRepresentation(s: String) -> [String] {
var result: [String] = []
for numbers in (s.characters.split {$0 == "."}) {
if let intNumber = Int(String(numbers)) {
if let binary = Int(String(intNumber, radix: 2)) {
result.append(NSString(format: "%08d", binary) as String)
}
}
}
return result
}
private func bitwise(op: (UInt8,UInt8) -> UInt8, net1: String, net2: String) -> String {
let net1numbers = toInts(net1)
let net2numbers = toInts(net2)
var result = ""
for i in 0..<net1numbers.count {
result += "\(op(net1numbers[i],net2numbers[i]))"
if i < (net1numbers.count-1) {
result += "."
}
}
return result
}
private func bitwise(op: UInt8 -> UInt8, net1: String) -> String {
let net1numbers = toInts(net1)
var result = ""
for i in 0..<net1numbers.count {
result += "\(op(net1numbers[i]))"
if i < (net1numbers.count-1) {
result += "."
}
}
return result
}
private func toInts(networkString: String) -> [UInt8] {
return (networkString.characters.split {$0 == "."}).map{UInt8(String($0))!}
}
}
let theOutput = Pipe()
func shell(Path:String ,args: String...) -> Int32 {
let task = Process()
task.launchPath = Path
task.arguments = args
task.standardOutput = theOutput
task.standardError = theOutput
task.launch()
task.waitUntilExit()
return task.terminationStatus
}
shell(Path:"/usr/sbin/arp",args: "-a")
let theTaskData = theOutput.fileHandleForReading.readDataToEndOfFile()
let stringResult = String(data: theTaskData, encoding: .utf8)
print(stringResult!)

Resources