[Swift 1] Day 15 - Saving Image and Text Data


#1

The Day 15 Lesson is an introduction to all of the ways you can save data and covers the basic File System access.

There’s a lot of cool technologies like Core Data, CloudKit, and app backends. Before you use those, I think it’s important to understand how saving files works, and how you can make sure your code is working correctly.

I’m preparing two lectures and a bunch of code tutorials that will feed into the code exercise. I’m also including a ton of links for additional resources if you want to dig into one of the related, more advanced file saving technologies. (Look under the video on the website)

Feedback and updates

  1. Let me know what you think.
  2. All future lessons will be with Yosemite and Xcode 6.1 (Apple keeps updating our software)
  3. @JohnC asked for more sample code/resources. I’ll be working to incorporate more into the existing as well as future lessons.

Week 3 Topics

  1. File system - save images and text
  2. Custom Objects + Saving with NSKeyedArchiver
  3. Custom Views and class inheritance
  4. Multiple screens + View Controllers
  5. Table Views, JSON web data, and Dictionaries

#2

Update The videos are on the course website, and I’ve included text descriptions for each video.

Feedback

  1. Please let me know what you think. Are the additional resources and links are helpful?
  2. I posted Code Exercise solution code as well, you can check it for reference. I would recommend that you attempt the exercise before looking at the solution.

#3

Hi Paul, when you talk about getting data from the web can you discuss how to handle multiple simultaneous downloads and how to determine when they are all complete or need to be re-issued?


#4

Hi Paul,

XCode 7.2 has not got the error type in the writeToFilePath function anymore and therefore demands me to handle the error. I tried to do it via do/catch but the problem is that I can’t call the status variable outside the block.

func saveText(text: String, path: String) -> Bool { do { let status = try text.writeToFile(path, atomically: true, encoding: NSUTF8StringEncoding) } catch { print("Error saving file at path: \(path)") } return status }

Since you mentioned in the beginning that we should avoid declaring global variables, I was wondering what the recommend solution would be in this case? (e.g. guard/else statement)

Thanks!

Max


#5

@Philomath , I think Apple keep recommending the use of URLs lately.
Try and change your method to writeToUrl:

writeToURL(someURL,atomically: true, encoding: NSUTF8StringEncoding, error: &error)

You have to declare the error prior: var error: NSError?


#6

Hi

Thanks @ravenshore but the problem is that if I do handle the error as Apple wants me to (with do/try/catch), I have trouble getting a bool value from it (e.g. true if it succeeded or false if it threw in error). I presume that I don’t really need to print the error on top since I can simply print it within the catch block.

However, it would still be nice if I could return whether the function was successful or not.

Best,

Max


#7

@Philomath

You can return Bool if you want to. You just need to declare the status before the do-try-catch…
Look here:

There are a ton of examples like that:

  func doSomethingThatMayCauseError(error: NSErrorPointer) -> Bool {
        // do stuff...
        var success = true
        // if there is an error, then make the error, and set the return to `false`
        if error != nil {
            error.memory = NSError(domain: "SuperSpecialDomain", code: -99, userInfo: [
                NSLocalizedDescriptionKey: "Everything is broken."
                ])
            success = false
        }
        return success
    }

let success = doSomethingThatMayCauseError(&theError)

if !success {
    if let error = theError {
        println(error.localizedDescription) // "Everything is broken."
    }
}

#8

I wanted to use the do/try/catch methodology and was looking at the Bignerdrench blog. However, your post inspired me to simply set my own variable and set it to false in the catch block, therefore yielding the following code:

func saveText(text: String, path: String) -> Bool { var success = true do { let status = try text.writeToURL(NSURL(fileURLWithPath: path), atomically: true, encoding: NSUTF8StringEncoding) } catch let error as NSError { print("Error saving file at path: \(path) with error: \(error.localizedDescription)") success = false } return success }


#9

Exactly :wink: @Philomath


#10

Great work fixing the issue! I have an article coming out soon on using the new error handling. The auto generated code works, but it’s just a very bare bones implementation that could be generated without intelligence.

To really make the solution work you will have to reconfigure the logic that Xcode spits out in the Swift 2 conversion process.