Search code examples
swiftnsurl

Appending Data To URL In Swift


This may be a rudimentary question, but I am trying to figure out how to "append" strings to a URL, and have them maintain, through View Controllers. More specifically;

I am building a basic File Browser app that is getting its data from a web service (in XML) form. Each time the user taps on a "folder" (which is being displayed as a list of folders in a Table View), another request is made via a NSURL session to get the contents of that folder.

My issue is that the URL string is only appending the name of the row the user tapped on, but I am unsure how to have it populate all rows the user tapped.

let urlString = "http://myurl/"

After the user taps the desired folder...

let urlString = "http://myurl/\(tappedRow)"
// This prints as http://myurl/firstfoldername/

After the user taps the next desired folder...

let urlString = "http://myurl/\(tappedRow)"
// This prints as http://myurl/secondfoldername/
// But I want http://myurl/firstfoldername/secondfoldername/

Since I am just segueing from the TableViewController to itself, and reloading the table, I assume this is working as its supposed to, but I seek to have the url string keep appending the tapped rows to the end, rather than forgetting each time. I was thinking of using NSUserDefaults to keep the last URL, but I realized this must be a common occurrence and perhaps there's a better way. Thanks!


Solution

  • You could use a Stack of Strings. I prepared this singleton class.

    class StackFolder {
        private var path = [String]()
        static let sharedInstance = StackFolder()
        private init() {}
        static private let basePath = "http://myurl"
        var baseURL = NSURL(string: basePath + "/")!
    
        func push(folder: String) {
            path.append(folder)
        }
    
        func pop() {
            path.removeLast()
        }
    
        func toURL() -> NSURL {
            let folders = path.reduce("/") { $0 + $1 + "/" }
            let adddress = Stack.basePath + folders
            return NSURL(string: adddress)!
        }
    }
    

    You just need to retrieve the shared instance of Stack and:

    1. invoke push when you want to add a folder to the path
    2. invoke pop when you want to remove the last added folder.

    Here it is an example:

    StackFolder.sharedInstance.push("folder1")
    StackFolder.sharedInstance.toURL().absoluteString // "http://myurl/folder1/"
    StackFolder.sharedInstance.push("folder2")
    StackFolder.sharedInstance.toURL().absoluteString // "http://myurl/folder1/folder2/"
    StackFolder.sharedInstance.pop()
    StackFolder.sharedInstance.toURL().absoluteString // "http://myurl/folder1/"
    

    Since Stack is a Singleton you don't need to pass a reference to the same Stack object from one view controller to the other. Each time you write Stack.sharedInstance in your app you automatically get the reference to the only instance of Stack.

    Hope this helps.