accessing the CFSteam that NSURLConnection is using?

  • NSURLConnection was treating me really well and give me almost
    everything I need, but now that I'm at the end of my project and I'm
    working on the last features, it jumps up and bites me!

    For downloads, I show the user a progress indicator, but
    NSURLConnection/NSURLResponse do not support accessing the uploaded
    write count via the delegate for upload POST requests. (not in a
    documented fashion at least)

    I was looking around in the CFNetworking documentation and it looks
    like if I can get access to the CFStream that the NSURLConnection us
    using, I could query it for the current upload info via
    kCFStreamPropertyHTTPRequestBytesWrittenCount.

    kCFStreamPropertyHTTPRequestBytesWrittenCount
    "HTTP Request Bytes Written property. This property can only be
    retrieved; it cannot be set. The value of this property is a CFNumber
    containing the number of body bytes that have been written to the
    server thus far. HTTP header bytes are not included in the count. You
    can use this property to track the progress of HTTP uploads that take
    a substantial amount of time to complete."

    Any suggestions? I might need to do some major retooling in order to
    switch from Cocoa's URL Loading System to CFNetwork Services. Call me
    a wimp, slap me around, call me Betty if you like, but CFNetwork
    Services scares a little bit. My project timeline would be in a world
    of hurt if I need to change a bunch of my code. Any assistance would
    be greatly appreciated.

    Thank you,
    Sean
  • Excellent, this is a great jump start from where I was stuck, thank you.

    I converted my NSURLRequest to use a NSInputStream instead of just an
    NSData, which seems to be working great. Sample code below:

    // [snip]
        NSMutableData *postBody = [NSMutableData data];

        [postBody appendData:[[NSString
    stringWithFormat:@"--%@\r\n",stringBoundary]
    dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[[NSString
    stringWithFormat:@"Content-Disposition: form-data; name=\"upload\";
    filename=\"%@\"\r\n", [imagePath lastPathComponent]]
    dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[[NSString stringWithString:@"Content-Type:
    application/octet-stream\r\n\r\n"]
    dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[NSData dataWithContentsOfFile:imagePath]];
        [postBody appendData:[[NSString
    stringWithFormat:@"\r\n--%@--\r\n",stringBoundary]
    dataUsingEncoding:NSUTF8StringEncoding]];

        // [postRequest setHTTPBody:postBody];
        [postRequest setHTTPBodyStream:[NSInputStream
    inputStreamWithData:postBody]];
    // [snip]

    I have the logic twisted around in my head at the moment, and I'm not
    sure how to determine how much data has been written to the server via
    the POST request from NSInputStream (conceptually, it seems like this
    should be an NSOutputStream, doesn't it?)

    Meanwhile, back at Bat headquarters (after the POST connection is
    connected), this isn't working:

    NSInputStream *requestInputStream = [eachUrlRequest HTTPBodyStream];
    unsigned int * numBytes;
    uint8_t * buffer;

    if ( [requestInputStream getBuffer:&buffer length: numBytes] ) {
        NSLog(@"Sweet, we got the numBytes! length: %d", numBytes);
    } else {
        NSLog(@"Nimrod!, you did it wrong again!");
    }

    On 10/12/05, Simon Spero <ses...> wrote:
    > On Oct 12, 2005, at 3:28 AM, sean wrote:
    >
    >> I was looking around in the CFNetworking documentation and it looks
    >> like if I can get access to the CFStream that the NSURLConnection
    >> us using, I could query it for the current upload info via
    >> kCFStreamPropertyHTTPRequestBytesWrittenCount.
    >
    > Forgot to add: you get the NSInputStream itself by from -
    > [NSURLRequest HTTPBodyStream]
  • Great! This looks like exactly what I need.

    Is there a swoopty way of forward all of the messages that
    PostingStream receives to the initializing NSInputStream? Or should I
    override all of NSStream's methods to do this?

    > - create an NSInputStream subclass (let's call it PostingStream) that
    > initializes from another NSInputStream and passes all messages from
    > itself to the other stream.  Override the methods read:maxLength: and
    > getBuffer:length: so that they perform the read on the other stream,
    > then somehow notify your code of how many bytes were read.
    > - create a PostingStream from the stream for the post body
    > - set the PostingStream as the HTTPBodyStream on the outgoing request
  • Can anybody offer some sample code showing how to provide a full
    implementation for the overridden methods read:maxLength: and
    getBuffer:length: The notification code isn't an issue, but I'm not
    sure what the implementation should do with buffer, length, read, and
    maxlength values?

    Initially, I tried forwarding these calls to the initializing
    NSInputStream object of my 'PostingStream' object, but this didn't
    work for me... But, I'm not that surprised because the docs say that I
    need to provide full implementations of these methods.

    On 10/12/05, sean <seanro...> wrote:
    > Great! This looks like exactly what I need.
    >
    > Is there a swoopty way of forward all of the messages that
    > PostingStream receives to the initializing NSInputStream? Or should I
    > override all of NSStream's methods to do this?
    >
    >> - create an NSInputStream subclass (let's call it PostingStream) that
    >> initializes from another NSInputStream and passes all messages from
    >> itself to the other stream.  Override the methods read:maxLength: and
    >> getBuffer:length: so that they perform the read on the other stream,
    >> then somehow notify your code of how many bytes were read.
    >> - create a PostingStream from the stream for the post body
    >> - set the PostingStream as the HTTPBodyStream on the outgoing request
    >
previous month october 2005 next month
MTWTFSS
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
Go to today