One time Internet Connection Check swift - swift

I need to check the internet connection of a user for one time.
I thought of something like Device.isConnectedToTheInternet but I didn't find something similar...
Every solution that if found was like an internet monitor over time, but that's not exactly what I need.
Someone ideas?
Thanks, Boothosh

As Rob Napier mentioned, it looks like the only thing readily available is the NWPathMonitor, which you can use to check the 'connectivity' to a certain location, like www.google.com, or something else that would be relatively trustworthy to be available 24/7, or just the URL you are about to try and use. Here is a short HackingWithSwift tutorial for NWPathMonitor.
I know this isn't exactly your current situation, but in my projects (and a lot of peoples projects) using an API like AlamoFire is pretty common, and has a ton of usefulness for creating GET/PUT/POST/DELETE requests and of course, has a NetworkReachabilityManager which can be used to make a convenient global function for a simple true/false result for 'isConnectedToInternet' like this:
/*
Connectivity
Struct
Utilizes AlamoFire to check for network availability.
isConnectedToInternet should return true in all cases the phone has access (Cellular, No cellular + wifi, Cellular + wifi, wifi)
*/
struct Connectivity {
static let sharedInstance = NetworkReachabilityManager()!
static var isConnectedToInternet:Bool {
let connected = self.sharedInstance.isReachable
return connected
}
}//end Connectivity

See NWPathMonitor().currentPath. It will tell you the current path. This is only occasionally useful, since "connected to the internet" is not a meaningful condition. There is not concrete definition of "the internet." But you can use the NWPath to answer some questions you probably are looking for. The fact that there is an NSPath available does not mean that you can actually connect to something on "the internet." The only way to know that is to send a packet and get a packet back. So if your real question is "can I connect to a specific host," then you're going to need to send packets to that host (and that still won't prove that you can send packets to the host in the future).
All that said, there is a little UI-level usefulness to asking "if I tried to connect, would it certainly fail?" And currentPath can help you answer that. It just can't tell you if it would succeed.

Related

Read from a serial port in Swift 4 using ORSSerialPort

I've been wanting to make an app that sends instructions over serial to my LED controller. For this to work, I need to read what the controller sends back after sending it a command. I found the following function in ORSSerialPort:
func serialPort(_ serialPort: ORSSerialPort, didReceive data: Data) {
// Do things
}
However, is there something like ORSSerialPort.read()?
I don't think ORSSerialPort.read() is a good idea. I know some other serial libraries are written that way, but the only way for that to work is for read() to block (possibly with a timeout) until a byte comes in on the port. Blocking I/O makes it a lot harder to write a good, responsive app, and I want to guide developers using ORSSerialPort away from that approach.
Instead, you should indeed implement serialPort(_:, didReceive:) in your ORSSerialPort delegate. When data is received by the serial port, that method will be called with the received data and you can do whatever you'd like with it.
That said, if your device communicates using a command/response type protocol (ie. every time you send a command, the device sends some response), you ought to look at ORSSerialPort's request/response API. It allows you to explicitly define the format of expected responses to commands, and ORSSerialPort itself will handle asynchronously waiting for, parsing, and validating responses. See the documentation for more info about this part of ORSSerialPort. The library also includes a sample project, RequestResponseDemo, that demonstrates using this API. Both Swift and Objective-C versions are included.
The ORSSerialPort library is popular and generally good. However, I'd found that it didn't work well with TTY serial devices. This was primarily because of its use of IOKit to discover serial ports -- it would only discover physical devices.
This is likely OK in your case but where you want to test your code but don't want to connect to a physical device, it falls over. Good code always needs a testing framwork. So, check out https://github.com/kpishere/POSIXSerialPort for a very simple serial interface API it is just what you need to write and respond to incoming data and also works with physical or virtual devices (as Unix was originally envisoned!).
To your question though, you don't want to call read() directly. You get into understanding whether or not, "is it a blocking read?" Then you get into dealing with threads. Both of the suggested APIs insulate you from that and allow you to think in terms of an event driven model -- this makes for much simpler code.

How to tell the difference between an offline and online mobile phone via sip?

For a toy project I want to find out if a mobile phone is connected to gsm or not. So I thought "Okay, let's use my local sip provider and see".
But in both cases, the thing goes like this:
I send an INVITE
0 s: I get a 100 Trying
5 s: I get a 183 Session description
I get an audio stream, in the one case with the ringing, in the other case with a "The person you are calling is…"
If I wait long enough (~ 40 s), I get a more appropiate status code like 180 Ringing.
Audio analysis is not an option, really.
Any hints on where to go now?
(I used twinkle for testing and a local german sip-provider.)
This issue is endemic in the way telephone networks work, and is not specific to SIP or IP. It's why, when you place a call to another country and the number is busy, you might sometimes hear your local country's busy tone, or you might hear a different busy tone that comes from the other country. In the latter case you cannot detect except by audio analysis, what the problem is. In SS7 and ISDN we speak of Q.931 cause codes instead of SIP error codes, but the principle is the same.
There's an argument to be made for configuring telephone systems to emit status codes instead of audio error messages. For callers using normal phones, the originating switch (the one closest to the caller) can then map that code to the appropriate spoken error message or audio tone. That way, when the call is being placed by software rather than by a person, the software can have access to the actual error code right away.
On the other hand you can also argue for having the remote switch (the one nearest the destination or the one that encounters the problem) speak its own error message. That switch knows best what the actual problem is. For example, a mobile operator can emit a spoken error message saying that the mobile phone you are trying to call is currently out of range. There is no Q.931 code (or SIP error code for that matter) with that meaning. It could return 27=Destination out of order?? Or 35=Destination unattainable?? Both of those codes are so esoteric, who knows what error message the local switch would translate them to (in practice: probably just a reorder tone, which is really user-unfriendly to a human caller). And when you try to map Q.931 cause codes to SIP error codes back and forth, even more information is lost because the codes really don't match up well at all. It's likely to be a much better user experience for the caller if the remote switch just plays back an informative, appropriate, recording which describes the problem.
Since there is this dilemma (arguments on both sides), we can conclude that this will not likely be resolved by completely standardizing on one way or ther other way anytime soon.
Anyway, sometimes this is configurable: your SIP provider may be able to configure your trunk for coded errors instead of recorded messages. If they offer this (some do), it's worth a try to set this option. But results will vary: this option only affects its local behaviour. In general if you want immediately call clearing with cause code and are instead getting a recorded error message from the other end, you will not be able to do anything about it, because the switch that makes the decision on which way it's going to respond is the remote one.
When using the audio message method, a proper Q.931 cause code or SIP error code usually comes eventually (after the recording is finished), but as you point out, it's probably too late by then.

Is there a reliable alternative to NSURLConnection?

My app is calling a web service to retrieve some data, and I want to make the experience as best as possible. I figured out that using NSURLConnection it's very hard to give good timely feedback.
Sometimes my iPhone tries to load the data for a minute or two and I see no way of figuring out what is taking so long, or why the download is so troublesome. Then after a few minutes I sometimes end up with an error code.
I'd like to display exactly what is happening. Messages like:
"Establishing internet connection"
"Trying to connect to server"
"Connected..."
"Downloading data..."
"Download complete!"
And when there is trouble like server not reachable or DNS could not be resolved, it would be nice to just try again a few times and not simply quit and throw error.
Are there replacements for NSURLConnection which handle these things more gracefully and give better in-time feedback about what is happening?
I've been a big fan of the AFNetworking library. Very easy to use and wraps all your networking calls in blocks that are very easy to work with.
It is also is kept very current, so you should be safe in getting all the updates it needs as your project progresses and ages.
I think you should be misusing NSURLConnection and NSURLConnectionDelegate, since you can do most of you needs with them.
But, what about MKNetworkKit? I've been using it and it really makes those kind of issues easier to deal with.
Something that can help you achieve what you want. Since ASIHTTPRequest is no longer being supported MKNetworkKit would be your best choice. To check for connectivity, you can always use Reachability.

GameKit: sending reliable NSData to other players?

Okay, I managed to create a match between two players. Now I will do a little test about sending data to a player.
I didn't quite get the explanation about NSData. Essentially, what is it? How do I send a, dunno, array to another player?
Apple mentioned data packets could be lost. But there was a "reliable" mode to prevent that. But I couldn't find about such.
Any ideas?
Yes, you have to make your OWN protocol. "making a protocol" is something you do yourself. Something like...Essentially on the server end
// the message arrives and you then do this...
[data getBytes:&getMe length:sizeof(CommsProt)];
whereas on the client end to send messages, you do this...
NSData * data = [NSData dataWithBytes:&sendMe length:sizeof(CommsProt)];
// ...now send that data using GameKit or whatever system you end up with
and you define your protocol - at least the chunks of data - like this:
typedef struct _CommsProt
{
BOOL happyThing;
someThings wotJustHappened;
float happyValue;
float anotherHappyValue;
// etc
}
CommsProt;
If you are new to GK, be aware of this critical tip ...
Client/Server GKSessions
This could also help...
Most effective way to do networking on Mac/iPhone?
Some helpful notes...
(i) "client" and "server" mean nothing. You will be able to send the handbags of information (such as "CommsProt" above) in either direction. If you want to think of, and refer to one, end as a server (particularly if you have a hub-type arrangement), that's fine. But it's only in your head. (By the way, commonly you might use a different data structure in each direction, that's perfectly fine.)
(ii) Regarding sockets. If you get heavily in to networking, you will have to deal with sockets and write your own sockets code. However it is very likely you can choose a networking layer where you never even have to say the word "sockets"! GameKit + Bonjour, for example, completely take care of handling sockets for you, AND that combination takes care of the other incredibly difficult issue which is FINDING one of your client/servers. If you are new I recommend you completely set aside sockets for now, and use a system such as GameKit (or whatever is equivalent on Windows) for your networking layer.
(iii) Indeed AT FIRST just use something incredibly simple like GameKit, while you figure out your protocol and all the other headaches. Later, if necessary you can rewrite the networking layer, or, switch to some other package that you hear about. Happily everything up to the code examples above will be unchanged, only the networking layer will change.
(iv) Regarding WiFi. GameKit and most convenience packages, are completely agnostic to the physical layer: they take care of it for you. GK will work fine however the phones are connected -- bluetooth, ethernet, whatever! Indeed you "won't know" what physical layer is being used. (It's sometimes annoying you can't control this: let it go, users couldn't care less.)

Client/Server GKSessions

I have an application that is set up so that if the user selects the device to be a server it creates a GKSession in server mode, and if it selects cient it create a GKSession in client mode.
Whats happening at the moment is the server is sending out the data fine, which is just a string containing the time of the server.
The problem starts however, when I have one client already connected to the server and I then connect another client .. the problem is: the second connected client connects also to the first client for some reason.
I want to be able to not connect to other clients and just connect to the server. Any help would be great
You've hit the nail on the head:
Strangely enough, GK allows an "any to any" model.
This is a truly impressive achievement, technologically, by Apple
BUT !!! ........it is very important to realise that this is a very unusual option. In networking - for games - you almost always want a "normal" client-server model.
Over some 30 years, a huge amount of science has become established, regarding doing networking using a normal client-server "spoke" model. And indeed, for game programming, 99% of the time you definitely need, and want, a standard client-server "spoke" model.
This bears repeating:
(1) Apple created a highly unusual "peer to peer" mode when they made GK.
(2) That is technologically astounding, but,
(3) this novel P2P technology would not, actually, be used in very typical networking programming for games.
(4) Very confusingly: all the documentation talks about the P2P mode. This is confusing because: if you are new to networking programming, it would make you think that is "normal". In fact, it is very likely you will never use the P2P mode at all, when making real normal games.
To repeat!
If you are new to networking, when you see all the mentions of P2P mode in Apple's doco, it's important to realise that the (amazing) P2P feature is more of a novelty. In fact, for essentially all game networking, you will definitely need normal "everyday" client-server "spoke style" networking.
Just to ne crystal-clear .. it is much, much, much !! easier to do real-life networking using a normal client-server "spoke" model.
The P2P mode is "really clever" and you could definitely spend some time experimenting with it. For instance, it is fine for just "sending chat around" to every device connected.
But again (if you're a new networking programmer) you should realise it is rather a novelty. You will have to program using a normal, everyday, client-server model.
So ......................
given that you are going to program in a normal everyday client-server model.
Your first job becomes, strangely enough, "disabling" the P2P aspect!!!!!
This is easy enough if you know how. Here's precisely how to do it...
sessionMode:GKSessionModeServer .. on the server.
sessionMode:GKSessionModeClient .. on the client.
So, for normal client-server programming, don't use GKSessionModePeer anywhere.
Secondly, don't forget in your clients, simply do not implement didReceiveConnectionRequestFromPeer:
Finally if all that doesn't work! In your clients, in peer:didChangeState:, you need to do this ...
// so this is in the CLIENT...
-(void)session:(GKSession *)session peer:(NSString *)peerID
didChangeState:(GKPeerConnectionState)state
{
switch (state)
{
case GKPeerStateAvailable:
// you have found the server!!
// [session displayNameForPeer:peerID]
self.theServerWeAreConnectedToPeerID = peerID;
// you will definitely need to save that
[session connectToPeer:theServerWeAreConnectedToPeerID
withTimeout:0];
break;
case GKPeerStateConnected:
// MAKE SURE it's our server
// not just some bizarre peers, etc etc.
if ( [theServerWeAreConnectedToPeerID isEqualToString:peerID] )
{
// you are connected - launch your tick or whatever
}
else
{
// completely ignore this!
}
break;
case GKPeerStateDisconnected:
if ( [theServerWeAreConnectedToPeerID isEqualToString:peerID] )
{
// you have been disconnected from the server!!
}
else
{
// weirdly this is telling you that one of your sister
// clients, has been disconnected from the server. IGNORE
}
break;
// GKPeerStateUnavailable .. likely not relevant
case GKPeerStateUnavailable:
// do nothing, ignore
break;
// from the modern doco..
// "The delegate should ignore GKPeerStateConnecting changes
// and implement the session:didReceiveConnectionRequestFromPeer:
// method instead." .. blah blah .. for us that comment only
// applies TO OUR SERVER, NOT here in the client.
case GKPeerStateConnecting:
// do nothing, ignore
break;
}
}
Just to repeat. It is very likely you will want to NOT-use the P2P model: so, all of the above explains "how to DISABLE the P2P stuff."
Once again to repeat for absolute clarity:
GK (surpriginsly) contains a P2P mode. This is technologically amazing. You can, of course, use P2P mode for simple networking problems (notably chat-like problems). In practice, all the typical networking needs of any real game (whether an FPS, sports game, or whatever) must be done in ordinary client-server paradigm. (It would be staggeringly difficult to use P2P mode.)
Thus, it's necessary as a "first step" to know how to "not use" the P2P system in GK -- that is explained above in length.
(If you DO want to use the P2P system - you're all set, go for it !!)
GK is fantastic if you can figure out all the subtleties. With GK and ASIHttpRequest, you can basically do anything between computers at least in a basic way.
This question has hit the nail on the head ........ GK has a (highly unusual) P2P mode, and the documentation focusses on the P2P mode, which can be confusing to newcomers. Again P2P is incredibly clever, but as a rule you do not want the P2P mode. You want a normal clients-with-server spoke model, which is incedibly easier to program. Hope it helps!