Bjqn
Bjqn

Reputation: 146

iOS Swift fastest way to download many small files

I'm writing an iPad app that needs, to download many, but fairly small, .json and .jpg files from an server.

So fare I am doing it like this:

    ///Function to allow for recursive calls to syncronize inspections sequentially.
    func getInspection(ip: String, view: sensorSyncronizationDelegate, idarr:[IdData], appDelegate: AppDelegate){
    let inspectionID = idarr[0]
    var newArr = idarr
    //A task is created for each inspection that needs to be downloaded, and the json is parsed and added to the database.
    if self.session != nil {
        let inspectionURL = NSURL(string: "http://\(ip)/inspections/\(inspectionID.id!).json")
        let inspectionTask = self.session!.dataTaskWithURL(inspectionURL!) { (data, response, error) in
            //If data is nil, end the task.
            if data == nil {
                view.setInspectionSyncCompleted()
                view.completion("Error: Timeout please ensure Instrument is on, and attempt syncronization again")
                print(error)
                return
            }

            //if newArr is NOT empty make a recursiv call to getInspection()
            newArr.removeAtIndex(0)
            if !newArr.isEmpty{
                self.getInspection(ip, view: view, idarr: newArr, appDelegate: appDelegate)
            }else{
                self.syncMisc(ip, view: view)
            }

(I'm always using dataTaskWithURL)

And this is how the session is setup:

var session : NSURLSession?

///Function to set up various http configurations, and call the various syncronization functions.
func syncWithSensor(view: sensorSyncronizationDelegate, ip: String!){

        //Session Configuration
        let config = NSURLSessionConfiguration.defaultSessionConfiguration()
        config.allowsCellularAccess = true
        config.timeoutIntervalForRequest = 30
        config.timeoutIntervalForResource = 60

        config.URLCache = nil

        //Authentication config
        let userpasswordString = "MAMA:PassWord"
        let userpasswordData = userpasswordString.dataUsingEncoding(NSUTF8StringEncoding)
        let base64encodedCreds = userpasswordData!.base64EncodedStringWithOptions([])
        let authString = "Basic \(base64encodedCreds)"
        config.HTTPAdditionalHeaders = ["Authorization" : authString, "Connection" : "Upgrade"]

        session = NSURLSession(configuration: config)

    //Check if for some reason ip is invalid
    if ip == nil{
        view.setSeriesSyncCompleted()
        view.setTemplateSyncCompleted()
        view.setInspectionSyncCompleted()
        view.completion("Error: Failed to connect to ***, please reset connection")
    }

    //Call the inspection sync function.
    syncInspections(ip, view: view)
}

//Function to respond to authentication challenges.
func URLSession(session: NSURLSession, task: NSURLSessionTask,  didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void) {
    let credential = NSURLCredential(user: "MAMA", password: "PassWord", persistence: .ForSession)
    completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, credential)
}

And yes it work like just fine. I can download 280+ files (.json and .jpg) in 22sec, which is decent, but a very long time for a user, to look at a download counter.

And the plan is, to have more then that.. So I really need a way to do this faster.

I can provide more of the code i'm using, if needed.

Thanks in advance :)

Upvotes: 1

Views: 1167

Answers (1)

Tomasz Bąk
Tomasz Bąk

Reputation: 6204

Try optimizing with json and images batching (server side optimization). It's always better to download one big file than a lot of small ones for a period of time. If you always need all of them it's a big win for battery life as it was pointed in documentation.

Upvotes: 5

Related Questions