HTTP Long Polling in Swift
Asked Answered
T

1

7

I am trying to implement a long-polling solution in Swift using iOS 8+.

While the solution undoubtedly works and leaves the main thread free for UI interactions, the memory usage climbs continuously so I am obviously doing something wrong. The class I have written is as follows:

enum LongPollError:ErrorType{
    case IncorrectlyFormattedUrl
    case HttpError
}

public class LongPollingRequest: NSObject {
    var GlobalUserInitiatedQueue: dispatch_queue_t {
        return dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.rawValue), 0)
    }

    var GlobalBackgroundQueue: dispatch_queue_t {
        return dispatch_get_global_queue(Int(QOS_CLASS_BACKGROUND.rawValue), 0)
    }

    var longPollDelegate: LongPollingDelegate
    var request: NSURLRequest?

    init(delegate:LongPollingDelegate){
        longPollDelegate = delegate
    }

    public func poll(endpointUrl:String) throws -> Void{
        let url = NSURL(string: endpointUrl)
        if(url == nil){
            throw LongPollError.IncorrectlyFormattedUrl
        }
        request = NSURLRequest(URL: url!)
        poll()
    }

    private func poll(){
        dispatch_async(GlobalBackgroundQueue) {
            self.longPoll()
        }
    }

    private func longPoll() -> Void{
        autoreleasepool{
            do{
                let urlSession = NSURLSession.sharedSession()
                let dataTask = urlSession.dataTaskWithRequest(self.request!, completionHandler: {
                    (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
                    if( error == nil ) {
                        self.longPollDelegate.dataReceived(data)
                        self.poll()
                    } else {
                        self.longPollDelegate.errorReceived()
                    }
                })
                dataTask.resume()
            }
        }
    }
}

I have tried profiling the app in Instruments but the results are confusing. I am hoping somebody can point me in the right direction.

Thanks

Tami answered 29/12, 2015 at 15:16 Comment(6)
LongPollDelegate is strong so you probably have a retain cycle. Try making it weak.Eldon
its obvious HTTP polling for long period of time climbs up memory usage..obviously not a good idea..So ,there comes the magic of sockets...Look at socket programming or Go with Some API like PusherVtehsta
Thanks for the comment @anishparajuli but why is it obvious? From the code example above where would you attribute the raised memory footprint? Repeated actions does not necessarily mean increased memory usage (I think David H above has highlighted the issue). I agree re sockets but fail to see how an API like Pusher has any relevance - would you mind elaborating? ThanksTami
if its about memory..then its right you need to declare LongPollDelegate as weak.considering polling for API makes use of CPU,resources continuously...therefore using of socket optimizes how you reques to server in the form of a single packet instead of making a HTTP request.Vtehsta
@DavidH - you were correct. That resolved the issue - do you want to post an answer so I can mark it as correct? As a side note, please beware of taking too much attention of the Xcode memory monitor - ALWAYS use InstrumentsTami
would you mind to share the whole code (related to the sample)? It seems a very good model to follow for such scenarios. thx!Isolecithal
E
3

LongPollDelegate is strong so you have a retain cycle. Make it a weak variable.

Eldon answered 30/12, 2015 at 16:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.