Have a Traccar server at http://188.120.235.97:8082/, trying to connect websocket using Swift library Starscream (https://github.com/daltoniam/Starscream).
There is my code:
func connect(_ token: String) {
var urlString = "\(self.serverURL)api/socket"
urlString = urlString.replacingOccurrences(of: "http", with: "ws")
self.socket = WebSocket(url: URL(string: urlString)!, protocols: ["chat"])
guard let socket = self.socket else { return }
socket.headers["Cookie"] = "JSESSIONID=\(token)"
socket.headers["Sec-WebSocket-Key"] = "\(token)"
socket.headers["Sec-WebSocket-Protocol"] = "chat"
socket.headers["Sec-WebSocket-Version"] = "13"
socket.headers["Host"] = self.serverURL
socket.headers["Upgrade"] = "websocket"
socket.headers["Connection"] = "Upgrade"
socket.headers["Origin"] = self.serverURL
socket.headers["Sec-WebSocket-Accept"] = "application/json, text/html"
socket.delegate = self
socket.connect()
print("isConnected: \(socket.isConnected)")
print("socket: \(socket)")
print("headers: \(socket.headers)")
}
Nothing happened, status of websocket is CONNECTING, never OPEN.
Using Fiddler cannot see any GET request also, when calling socket.connect...
Does it work in iOS simulator?
Related
I am trying to setup server using Vapor. As client, I have simple iOS app using NSUrlSession - URLSessionWebSocketTask. My question is... how I can set session.data from iOS app?
iOS App - Connect method
func connect(completion: #escaping ()->() = { }) {
guard webSocketTask == nil else { return }
self.username = "Name"
self.userID = UUID().uuidString
let url = URL(string: "ws://localhost:8080/connect")!
webSocketTask = URLSession.shared.webSocketTask(with: url)
webSocketTask?.receive(completionHandler: onReceive)
webSocketTask?.resume()
}
Vapor:
app.webSocket("connect") { request, ws in
let controller = Controller()
let userName = request.session.data["nickname"] ?? "Unknown user"
let data = request.session.data["data"] ?? "Empty Data"
controller.addUser(userName, with: room, withConnection: ws)
.....
....
...
..
.
You may use NSURLSessionDataTask.
https://developer.apple.com/documentation/foundation/nsurlsessiondatatask
Iam using libjingle_peerconnection library for webrtc connection,
this is the init of rtc connection, i works for the same network,
not for other networks
what i need to do for turn server to work???
func initalizeWebRTC() -> Void {
RTCPeerConnectionFactory.initializeSSL()
self.webRtcClient = RTCPeerConnectionFactory.init()
let stunServer = self.defaultStunServer()
let turnServer = self.getTurn()
let defaultConstraint = self.createDefaultConstraint()
let array = [turnServer, stunServer]
print(array)
self.peerConnection = self.webRtcClient?.peerConnection(withICEServers: array, constraints: defaultConstraint, delegate: self)
print(peerConnection)
self.localVideoView.delegate = self
self.remoteVideoView.delegate = self
// webrtc initalized local rendering of video on
self.addLocalMediaStrem()
}
func defaultStunServer() -> RTCICEServer {
let url = URL.init(string: "stun:stun.l.google.com:19302");
let iceServer = RTCICEServer.init(uri: url, username: "", password: "")
return iceServer!
}
func getTurn() -> RTCICEServer {
let url = URL.init(string: "turn:xxx.xxx.xx.xxx:xxxx");
let iceServer = RTCICEServer.init(uri: url, username: "xxxx", password: "xxxxxxxxxxxx")
return iceServer!
}
I had a couple of tries to make a connection with SSL via Starscream but I got the same error for some reasons.
Here are simples of connection and response
client = WebSocket(url: URL(string: "wss://XXXXXXXX:443/")!)
client?.enabledSSLCipherSuites = [TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
let certificateData = try Data(contentsOf:Bundle.main.url(forResource: "certificate", withExtension: "cer")!)
let cert = SSLCert(data: certificateData)
let security = SSLSecurity(certs: [cert], usePublicKeys: true)
security.validatedDN = false
security.validateEntireChain = false
client?.security = security
client?.delegate = self
client?.connect()
2nd one
do
{
client = WebSocket(url: URL(string: "wss://XXXXXXXX:443/")!)
let urlPath = Bundle.main.path(forResource: "certificate", ofType: "der")
let url = NSURL.fileURL(withPath: urlPath!)
let certificateData = try Data(contentsOf: url)
let certificate: SecCertificate =
SecCertificateCreateWithData(kCFAllocatorDefault, certificateData as CFData)!
var trust: SecTrust?
let policy = SecPolicyCreateBasicX509()
let status = SecTrustCreateWithCertificates(certificate, policy, &trust)
if status == errSecSuccess {
let key = SecTrustCopyPublicKey(trust!)!;
let ssl = SSLCert(key: key)
let security = SSLSecurity(certs: [ssl], usePublicKeys: false)
security.validateEntireChain = false
client?.security = security
client?.delegate = self
client?.connect()
}
}catch let error as NSError
{
print(error)
}
And Logs
CFNetwork SSLHandshake failed (-9807)
0 TCP Conn 0x600003119c80 SSLHandshake failed (-9807)
ERROR - %# Optional("The operation couldn’t be completed. (OSStatus error -9807.)")
I've some trouble about SSL Pinning in Alamofire. I've examine all the document that I can found but I couldn't manage to handle it. I might get it wrong.
Currently, I am working on an example
https://github.com/antekarin/ios-ssl-pinning
I converted it to swift 3 and updated the pods to the latest version of Alamofire.
To make it clear; the project is use "github.com.cer" certificate, and because I define domain (like below) I expect to get success when I go to "https://github.com" and to get failure when I enter (in example) "https://twitter.com". But in every condition my request return some value and does not block other requests.
self.serverTrustPolicies = [
"github.com": self.serverTrustPolicy!
]
Code:
let githubCert = "github.com"
let corruptedCert = "corrupted"
var urlSession: Foundation.URLSession!
var serverTrustPolicy: ServerTrustPolicy!
var serverTrustPolicies: [String: ServerTrustPolicy]!
var afManager: SessionManager!
var isSimulatingCertificateCorruption = false
override func viewDidLoad() {
super.viewDidLoad()
self.configureAlamoFireSSLPinning()
self.configureURLSession()
self.activityIndicator.hidesWhenStopped = true
}
// MARK: SSL Config
func configureAlamoFireSSLPinning() {
let pathToCert = Bundle.main.path(forResource: githubCert, ofType: "cer")
let localCertificate:NSData = NSData(contentsOfFile: pathToCert!)!
self.serverTrustPolicy = ServerTrustPolicy.pinCertificates(
certificates: [SecCertificateCreateWithData(nil, localCertificate)!],
validateCertificateChain: true,
validateHost: true
)
self.serverTrustPolicies = [
"github.com": self.serverTrustPolicy!
]
self.afManager = SessionManager(
configuration: URLSessionConfiguration.default,
serverTrustPolicyManager: ServerTrustPolicyManager(policies: self.serverTrustPolicies)
)
}
// MARK: Button actions
#IBAction func alamoFireRequestHandler(_ sender: UIButton) {
self.activityIndicator.startAnimating()
if let urlText = self.urlTextField.text {
self.afManager.request(urlText).responseString { response in
guard let data = response.data, response.error == nil else {
self.responseTextView.text = response.error.debugDescription
self.responseTextView.textColor = UIColor.red
return
}
self.responseTextView.text = String(data: data, encoding: String.Encoding.utf8)!
self.responseTextView.textColor = UIColor.black
}
}
}
This question already has answers here:
Check for internet connection with Swift
(31 answers)
Closed 6 years ago.
Is there an Apple framework bundle to detect if there's an internet connection? Currently my application crashes when it tries to geolocate the user's position without an internet connection.
/*inside locationManager didUpdateLocations method*/
var currentLocation:CLLocation? = locations[0] as? CLLocation
geocoder = CLGeocoder()
//Crashes on line below when there isn't an internet connection
//Need to add function to check if internet connection is live
//Before running reverseGeocodeLocation
geocoder.reverseGeocodeLocation (currentLocation,handleGeocode)
I'm a bit new to swift and ios programming - my apologies.
Not a full-fledged network checking library but I found this simple method for checking the network availability. I managed to translate it to Swift and here the final code.
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) ? true : false
}
}
It works for both 3G and WiFi connections. I've also uploaded it to my Github with a working example. If you're looking for a simple way to check for network availability purely in Swift, you can use it.
Using Babatunde's code sample but here is an updated version for Swift 2.0 and error handling:
EDIT: Also changed the URL for Google as HTTPS for iOS 9.
EDIT2: Original article: http://www.brianjcoleman.com/tutorial-check-for-internet-connection-in-swift/
import Foundation
import SystemConfiguration
public class Reachability {
// Check if internet connection is available
class func isConnectedToNetwork() -> Bool {
var status:Bool = false
let url = NSURL(string: "https://google.com")
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "HEAD"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
request.timeoutInterval = 10.0
var response:NSURLResponse?
do {
let _ = try NSURLConnection.sendSynchronousRequest(request, returningResponse: &response) as NSData?
}
catch let error as NSError {
print(error.localizedDescription)
}
if let httpResponse = response as? NSHTTPURLResponse {
if httpResponse.statusCode == 200 {
status = true
}
}
return status
}
}
As Reachability has not been fully ported to swift yet, you can use the sample code below to check for internet connection:
public class Reachability {
/**
* Check if internet connection is available
*/
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
}
}
See sample usage of the function below:
// Check if internet is available before proceeding further
if Reachability.isConnectedToNetwork() {
// Go ahead and fetch your data from the internet
// ...
} else {
println("Internet connection not available")
var alert = UIAlertView(title: "No Internet connection", message: "Please ensure you are connected to the Internet", delegate: nil, cancelButtonTitle: "OK")
alert.show()
}