views:

70

answers:

3

I need to connect to a remote host and exchange data with some binary protocol. I'm connecting with:

CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"whatever.host.com", 
           port, &readStream, &writeStream);

Everything is fine, except the error handling. I'm

  1. handling NSStreamEventErrorOccurred in my stream's delegate
  2. retrieving the error with theError = [stream streamError];
  3. trying to get user-friendly error text with [theError localizedDescription].

And here is the problem: instead of nice error message, like 'Host not found', I get "Operation could not be completed. (NSUnknownErrorDomain error 8.)"
Or, when the device is in Airplane mode, I get "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error 2.)"

Question: how do I get a socket connection, where I can retrieve proper error messages? When I used NSURLConnection (in another app), the error messages were nice and friendly, so I'd like to get something similar.

A: 

Don't you think it's easier to just catch the error, check it's type and present a custom error message then? Might me way easier than rewriting code just to make nice messages. Bonus: this way you have the full control and can add longer descriptions if you want to...

Max Seelemann
No, I don't want to write a custom error message for every possible connection error
unbeli
Still, I'm quite sure this is the easiest solution. But that's up to you. Can't be that many...
Max Seelemann
+1  A: 

I believe the provisioning for localized error descriptions has to happen at the framework level. In other words, the Foundation framework developers have provided more useful messages and had the localization folks translate them, etc. Judging by your description, the CoreFoundation layer hasn't received as much attention in this regard.

Are there Foundation APIs that you could use here instead?

Kaelin Colclasure
Are there Foundation APIs to open plain socket connections?
unbeli
+1  A: 

Apple has not provided proper descriptions for error conditions on iOS. This is not a bug in your code or theirs--the strings simply aren't present on iOS devices.

To provide more interesting error information, it is going to be up to you to check the domain and code of CFError and NSError objects and return something. A list of error descriptions from kCFErrorDomainCFNetwork is available here on Apple's site. Code like this would help--call it when building your error presentation UI:

NSString *GetUsefulErrorDescription(NSError *e) {
    NSString *codeString = [NSString stringWithFormat: @"%li", (long)[e code]];
    NSString *localized = NSLocalizedStringInTable(codeString, [e domain], nil);
    if (!localized || [localized isEqual: codeString])
        return [e localizedDescription];
    else
        return localized;
}

This looks in a file in your app bundle called "kCFErrorDomainCFNetwork.strings" for a string such as "100" (for kCFSOCKSErrorUnknownClientVersion, whose value you could supply as "The SOCKS server rejected access because it does not support connections with the requested SOCKS version.") If no such error description is available, it instead uses the string returned by NSError, which would be "The operation couldn’t be completed. [...]"

Jonathan Grynspan
this is, again, another way to write descriptions for all possible errors myself. This is exactly what I want to avoid.
unbeli
You don't have a choice on iOS. The OS *flat out* does not include any descriptions of these errors.
Jonathan Grynspan
not true, when using NSURLConnection, the errors are nice and friendly, so there are descriptions *somewhere*.
unbeli
Yes--for `NSURLConnection`. At the `CFSocket` level, they're not available.
Jonathan Grynspan