1

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 :)

Bjqn
  • 146
  • 2
  • 19
  • Might be that the response from the server is slow ? btw you don't have to implement the connection manually and there exist libraries to do that in several lines, check this out : https://github.com/Alamofire/Alamofire – AaoIi Oct 07 '15 at 10:59
  • I dont think that the case.. The connection to the server is fast enough.. – Bjqn Oct 07 '15 at 11:04
  • https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/index.html#//apple_ref/occ/clm/NSData/dataWithContentsOfURL: NSData's dataWithContentsOfURL method will be useful to download small files – Gobi M Oct 07 '15 at 11:06
  • @GobiM It is a bad idea to use a synchronous call for networking. – Abizern Oct 07 '15 at 11:21

1 Answers1

5

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.

Tomasz Bąk
  • 6,124
  • 3
  • 34
  • 48
  • That was some really good advice.. But this download operation, is only done 1-5 times a day (in a real world scenario), but the amount of files could be way bigger.. and I only want to download the new json files not all of them.. (i have a system that sorts them already) ? – Bjqn Oct 07 '15 at 11:39