UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Day 68: Documents Directory challenge

Forums > 100 Days of SwiftUI

Hello,

i tryed to solve this challange but I don´t get it so far. Can someone share there solution with me and tell me how you did it?

Kind regards Maxi

2      

This was my solution to that:

extension FileManager {
    func getDocumentsDirectory() -> URL {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        return paths[0]
    }

    func decode<T: Codable>(_ fromFile: String) -> T? {
        let url = getDocumentsDirectory().appendingPathComponent(fromFile)
        let decoder = JSONDecoder()

        do {
            let savedData = try Data(contentsOf: url)
            do {
                let decodedData = try decoder.decode(T.self, from: savedData)
                return decodedData
            } catch {
                print(error.localizedDescription)
                print("Decoding Failed!")
            }
        } catch {
            print(error.localizedDescription)
            print("Read Failed!")
        }
        return nil
    }

    func encode<T: Codable>(_ data: T, toFile fileName: String) {
        let encoder = JSONEncoder()

        do {
            let encoded = try encoder.encode(data)
            let url = getDocumentsDirectory().appendingPathComponent(fileName)
            do {
                try encoded.write(to: url)
            } catch {
                print(error.localizedDescription)
                print("Write Failed!")
            }
        } catch {
            print(error.localizedDescription)
            print("Encoding Failed!")
        }
    }
}

I found this to be difficult to figure out as well. I used Paul's Bundle-Decodable that he had given us previously as template:

extension Bundle {
    func decode<T: Codable>(_ file: String) -> T {
        guard let fileUrl = self.url(forResource: file, withExtension: nil) else {
            fatalError("Failed to find \(file) in bundle.")
        }
        guard let data = try? Data(contentsOf: fileUrl) else {
            fatalError("Failed to load \(file) from bundle.")
        }
        guard let decodedData = try? JSONDecoder().decode(T.self, from: data) else {
            fatalError("Failed to decode \(file) from bundle.")
        }
        return decodedData
    }
}

I took it one step at a time and figured out the code for performing the encode and decode without using generics and without using an extension. Once I got that working, I implemented the generics. Once I got that working I implemented the extension. This is not a totally complete solution if you're decoding dates but that wasn't part of this particular challenge either. I also don't think you need to nest one do try catch inside the other but it was helpful to me to get the specific print messages that were more helpful to me than the error.localizedDescription.

That's another thing I did when I was trying to figure it out. I had print statements all over the place to see what was working and what wasn't working.

4      

This is another version of it I had done:

extension FileManager {
    func getDocumentsDirectory() -> URL {
        let paths = Self.default.urls(for: .documentDirectory, in: .userDomainMask)
        return paths[0]
    }
    func encode<T: Codable>(_ file: String, data: T) {
        if let encoded = try? JSONEncoder().encode(data) {
            let url = Self.default.getDocumentsDirectory().appendingPathComponent(file)
            do {
                try encoded.write(to: url)
            } catch {
                print(error.localizedDescription)
            }
        }
    }
    func decode<T: Codable>(_ file: String) -> T? {
        let url = Self.default.getDocumentsDirectory().appendingPathComponent(file)
        if let savedItems = try? Data(contentsOf: url) {
            if let decodedItems = try? JSONDecoder().decode(T.self, from: savedItems) {
                return decodedItems
            }
        }
        return nil
    }
}

This version doesn't give much error information if something goes wrong though.

4      

Thank you very much. I like the solution with many print statemants. Like you said you see exactly which line cause the program to crash and which line is good.

2      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.