The Apple docs mark CFStreamCreatePairWithSocket as deprecated since IOS 15.0.
What would be a related successor ?
We use CFSocket/NSStream functions currently to have event driven network reads/writes in a runloop.
For the record, we ended up rewriting our code to use plain Berkeley sockets together with the GCD dispatch_source machinery ... there is a working socket server sample not triggering the local network prompt at
https://github.com/leopatras/GCDSimpleSocketServer/
The dispatch_source_zzz functions allow a similar event driven approach like the CFStreamCreatePairWithSocket function (and even less code).
See https://github.com/leopatras/cfsocket for comparison with the old CFSocket stuff.
As this is anyway deprecated and triggers the local network prompt in some situations: don't use it anymore.
I had an intensive exchange with the Apple support about this topic, they did recommend using the new Network framework functions instead of Berkeley sockets (See https://developer.apple.com/documentation/network?language=objc) and I tried hard to use them however I failed to create a simple reliable working echo server with those functions in obj-C (didn't try the Swift route).
Related
Let's say I want to build a SDK that communicates with a server. I don't want any one (not even the app that implements the SDK) to intercept and look at my requests/responses.
If I'd use a common lib like AFNetworking it would be possible to look at all requests i.e by registering a NSURLProtocol.
I'm assuming that this would be harder to do if I would use i.e CFNetworking to perform my request/response handling? Or am I missing something? Would it be possible to intercept that traffic as well?
Using non NSURLConnection based classes, especially C low level classes (because NSIn/OutStream can be swizzled) like CFNetwork's CFStream, would make life harder for a potential curious developer. However, it will never stop a determined one. Your framework could, for example, be decompiled, although that's not a trivial task, which means many will quit even before starting, if the information is not worthwhile.
I'm implementing an autocomplete functionallity in a mobile app. I plan to have an autocomplete function on Parse Cloud Code but I'm afraid of the latency/delay that could bring up.
Specifically I would like to know how is calling parse Cloud Functions compared to do calls to a regular webserver over a WebSocket connection.
NOTE: I see the iOS SDK call to Parse functions uses NSURLSession which will leverage KeepAlive by default. What I don't know if the server copes up with that.
Cloud functions can be done both sync and async however they are very stingy about how long the connection stays open. In other-words you'd have to separate api calls. So, your answer is no.
Also, I might mention this from their guide on iOS cloud code calls
There is a limit of 8 concurrent httpRequests per Cloud Code request, and additional requests will be queued up.
This means that even if you somehow forced the connection to stay open like a WebSocket...you couldn't have more than 8 people using that view/cloud function at a time or everyone else wouldn't be able to access the function.
However, Ive dealt with this myself and you have a few options....
1)Make your own SocketIO server that make rest requests to parses cloud code functions. Theres even a iOS SDK from SocketIO now. So this is a pretty easy option.
2)Accept that youll have a pretty high API call rate and keep making it.
3)Do what I did and Call all the objects you need at the beginning and have iOS perform the autocomplete on the fly. Heres a helpful search on cocoa controls that should give you a head start to get it handled check it out here. Any one of these would save you hours of time of trying to sort through and repopulate yourself. If you have a lot of objects you need to get. Remember if you are returning more than 100 results(the default return amount) set query.limit = 1000(max return limit).
There is a piece of code that does DNS lookups using CFHostStartInfoResolution(). However this is synchronously and thus blocks anything before it returns - it's bad and I also think it causes crashes due to timeouts when connection is weak (when its bad it fails out safely directly)
So I want to do this asynchronously, as it's supposed to in the docs https://developer.apple.com/library/ios/documentation/CoreFoundation/Reference/CFHostRef/Reference/reference.html
New docs URL 20190227: https://developer.apple.com/documentation/cfnetwork/cfhostref
Specifically it says:
If you want to resolve the host asynchronously. call CFHostSetClient
to associate your client context and user-defined callback function
with the host. Then call CFHostScheduleWithRunLoop to schedule the
host on a run loop.
However this put me off because I haven't coded C in ages and can't get callbacks and runloops/threading right.
How am I supposed to call CFHostSetClient, CFHostScheduleWithRunLoop, and how do I implement those callbacks? Do I need to start a new thread?
Actually CFHost has a bug since on macOS since 10.7. Up to 10.7 it was possible to cancel a synchronous lookup calling CFHostCancelInfoResolution() on a second thread but since 10.7 this is not possible any longer (it just won't cancel the lookup). I reported that to Apple in 2013 (bug number is 13672880) but despite confirming it, Apple has never fixed it up to today.
Yet the more interesting part was what Apple suggested in their reply:
The best API for host name resolution is DNSServiceGetAddrInfo
and that's asynchronous and cancelable.
This API is documented to exist on macOS since 10.11.4, on iOS since 9.3, on tvOS since 9.2 and on watchOS since 2.2 - yet I think this cannot be correct, it must have existed, otherwise how could Apple recommend it in 2013 (10.11 was released 2015). I can confirm that this API also existed on iOS 8 and on macOS 10.9 and probably even earlier on both systems.
This API is internally using an undocumented asynchronous version of the otherwise synchronous C call getaddrinfo() which is found on all POSIX like systems today.
One advantage over other APIs is that you can choose if you only want to retrieve IPv4, IPv6, or both kind of addresses or you can let the system decide to pick the address family for you, depending on which addresses the system considers reachable at the moment (this is the default for most other resolving APIs).
Also in case a system has multiple active network interfaces (e.g. cable + WiFi or WiFi + mobile), you can pick the interface to use as different DNS settings may be set on different interfaces (and different DNS servers can deliver different results for the same domain name). If you don't pick one, the system will always use the current default server (this is the default for most other resolving APIs).
Should be something like this
CFHostSetClient(host, callbackFunction, hostContext);
CFHostScheduleWithRunLoop(host, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
CFHostStartInfoResolution(host, kCFHostAddresses, 0);
And callbackFunction
void callbackFunction(CFHostRef theHost, CFHostInfoType typeInfo, const CFStreamError *error, void *info) {
// Do something
}
You don't need to start a new thread, system will do it for you.
I am learning C and Objective-C so am still dependent on examples...
I found AsyncUDPSocket which has a lot of example code in the Google Code repository, but I'm not far enough along to understand it all yet.
I'm trying to build an iPhone app that uses UDP for communication to another device (Arduino). I have the device end working (testing with the UDP Tool app). I just need help with the iOS side of it...
An example with more explanation would really help (that is, a tutorial)... Is there one or what would some example code with good comments be?
https://github.com/robbiehanson/CocoaAsyncSocket
GCDAsyncUdpSocket and AsyncUdpSocket are UDP/IP socket networking libraries. Here are the key features available in both:
Native objective-c, fully self-contained in one class. No need to
muck around with low-level sockets. This class handles everything for
you.
Full delegate support.
Errors, send completions, receive completions, and disconnections all result in a call to your delegate method.
Queued non-blocking send and receive operations, with optional
timeouts.
You tell it what to send or receive, and it handles everything for you. Queueing, buffering, waiting and checking errno - all
handled for you automatically.
Support for IPv4 and IPv6.
Automatically send/recv using IPv4 and/or IPv6. No more worrying about multiple sockets.
Can any one tell me which is more stable? I know each has their own advantages and disadvantages. But which one is better for http, etc?
In my previous application I used indy9 but I wasn't satisfied with it, as I would sometimes get strange errors.
Can anyone recommend one?
I use Indy in a lot of projects. I used both 9 and 10 mainly as HTTP server and proxy. The projects get very intense traffic at times (HTTP). Indy never did let me down. It works very stable.
But I also had some "strange" situations where I had to dig deep to find the underlying problem. I also do not like the way Indy tends to handle a lot of things through exceptions. In general I like the ICS coding style more. But let me go to ICS.
ICS uses non-blocking sockets, while indy uses blocking. While non-blocking is ok and seems to be better at first sight, I found it irritating in a lot of situations. The problem is that the natural flow of the code gets lost because of the callback functions. This makes it harder to write procedural type of libraries. Furthermore I do not like how everything is handled through messages. For me it gets messy real quick when mixed with multithreading. And multithreading is mainstream these days.
So while I like the coding style and quality of the code in ICS, I prefer the simplicity of use and blocking mode of Indy. What you like more is up to you, but both libraries are mature and stable.
These are my two cents.
I also use both Indy and ICS.
Most of the time I prefer Indy because implementing sequential type of protocols with it is very easy (the request runs in it's own thread so you simply Read/Write to the connection, really easy). Using Indy requires solid knowledge of threading and synchronization. Unlike Runner I like how Indy uses Exceptions to handle "exceptional" stuff because it allows me to concentrate on the normal flow of the protocol (I use try-finally blocks to make sure I deallocate resources).
I also used ICS in a application where Indy simply failed: I used it for an application that implements an TCP/IP proxy. Using ICS was simpler because of it's non-blocking nature. I was able to "proxy" TCP/IP protocols that I know nothing about, so I have no idea how bytes would flow from one end to the other. Indy failed in that scenario because in Indy you're ether reading or you're writing, you can't do both at the same time. Using ICS to implement an sequential-type protocol is a bit of pain: you essentially need to use state-machine logic, brake the protocol in small bits, keep flags laying around so you know where you are in the protocol. An big plus: François Piette, the author of ICS, is active and very helpful on a number of forums and mailing list, and is very prompt to help with anything related to ICS.
For me, if I need to do something with TCP/IP, the decision path is very simple: Can it be done with Indy? Then it's Indy. If it can't be done with Indy then it'll be done with ICS!
I've used Indy 9 and 10 for TCP, HTTP and FTP with very few problems. ICS is a good choice, too. It's non blocking, which will change how you use it.
I haven't used it, but I've heard good things about Synapse, which is also blocking.
We test Indy10 IdTCPClient to receive video stream from remote server, it's OK. But when it's receiveing stream, the same time use it send some data to the server, after some minute, the received stream data began lost data bytes. We use sniffer tool to trace this problem, confirmed that IdTCPClient lost some bytes in receiveing stream.
So, we test Indy9.018, the same problem happend but a few times VS. Indy 10.
Remember that Indy is always in beta stage. Sometimes you need to work with night builds.
Which one is better really depends on specific use case, but I was unhappy with indy as an http client and ICS ended up being exactly what I needed it to be, with a lot less random quirks.
Note though that it is non blocking, so it's not just a drop in replacement.
I use Indy 9 for stable, released, production code to over 1 million users, and have never received any strange errors.
I'd say the answer depends on what you want to do with the internet. Indy is fine if you are prepared to get involved with understanding how it works, and is very capable. ICS is a different take on things, and I've used it effectively for many-connection systems. But for day to day "grab a file or send an email" type stuff, where you want to do a basic task, I pretty much always use Clever Components Internet Suite as you just create the component,
set the options, and it works. The suite is quite comprehensive, and gets useful updates.