4 Replies
      Latest reply on Jun 10, 2018 7:39 PM by eskimo
      lapatil Level 1 Level 1 (0 points)

        I want my application to use cellular data when WI-FI is On.

        For that, I need access to socket before it is connected

        so that it can be bound to cellular network IP and port.

        Thought of using CFStreamCreatePairWithSocket() instead of CFStreamCreatePairWithSocketToHost()

        but stream callbacks are not received.

         

        Steps.

        1. Create socket with CFSocketCreate() function

        2. Get a native socket using CFSocketGetNative() and bind it to cellular IP.

        3. Make a connection using CFSocketConnectToAddress() with timeout

            parameter as -1 (Need a non-blocking connect).

        4. Scheduled it over run loop using CFRunLoopAddSource

        5. Upon kCFSocketConnectCallBack call back event create streams using

            CFStreamCreatePairWithSocket().

        6. Assigns clients to a streams for stream events.

        7. Scheduled streams over run loop and opened the stream.

         

        Expected Results:

        1. Receive socket call back events.

        2. Receive stream call backs events.

         

        Actual Results:

        1. Received kCFSocketConnectCallBack once and kCFSocketWriteCallBack twice. Rest events are not received.

        2. Received only kCFStreamEventOpenCompleted.

         

        Version/Build:

        10.3.2

         

        Kindly, let me know if I am missing something in above steps or there is any different way to do this.

        Is there any API at application level instead of socket level to force application to use cellular network

        when wifi is ON?

        • Re: CFReadStream & CFWriteStream callbacks not received
          eskimo Apple Staff Apple Staff (9,835 points)

          I recommend that you avoid using CFSocket here, because CFSocket has many sharp edges.  The alternative is pretty simple: Do this part of the job using BSD Sockets.  Now, BSD Sockets has lots of sharp edges as well, but they’re well-documented sharp edges (-:

          The main complication with replacing CFSocket with BSD Sockets is the async connect.  Fortunately dispatch event sources make that relatively easy.

          Finally, once you have a connect BSD Socket I recommend that you wrap that in an NSStream pair rather than a CFStream pair, because the NSStream API is substantially easier to use.  You do this by exploiting the toll-free bridge between the types, that is, call CFStreamCreatePairWithSocket and cast the resulting values to NSInputStream and NSOutputStream.  You can steal the basic code outline from QA1652 Using NSStreams For A TCP Connection Without NSHost (although that uses CFStreamCreatePairWithSocketToHost instead of CFStreamCreatePairWithSocket).

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"