1

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!

3 Answers 3

1
override func viewDidLoad() {
    super.viewDidLoad()
    let baseUrlString = "http://myUrl/"
    var currentUrl = baseUrlString 
}

func cellTapped() {
    currentUrl += tappedRow
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your reply, @Swinny89! This is almost working for me! I'm using your structure to append the tappedRow to the currentUrl (which is working), but it's only appending the most recently tapped row, overwriting the previously tapped row. So my URL starts as "myUrl" and after the first row is tapped, I'm getting "myUrl/tappedRow" but after the second row is tapped, I'm still just getting "myUrl/tappedRow" instead of "myUrl/tappedRow/tappedRow".
0

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.

10 Comments

I like this approach, @appzYourLife, but I have two questions. I keep receiving a "Stack<T>.Type does not have a member named 'sharedInstance'" when I try to call "Stack.sharedInstance.push(myString)" or "Stack.sharedInstance.toURL().absoluteString". Additionally, since I am defining my base URL as "address" in the class definition, how can I reference that URL later on so it can be passed to my NSURLRequest?
About the first problem it's probably because I edited the code after the post and you got the old version. Just copy the new code of the Stack and it will work :)
For the second issue, if you need to reference your base URL you can just add a property to Stack containing the base address. I am going to update the code right now adding the baseURL property.
Done, now you can get your base URL writing Stack.sharedInstance.baseURL. Let me know if everything works fine.
Thanks for your help, @appzYourLife. I see your changes and understand them, though I'm still getting the "Stack<T>.Type does not have a member named 'sharedInstance'" whenever I try to call it. I have your Stack class defined at the top of my TableViewController.swift file; should I be declaring it elsewhere?
|
0

Declare urlString as instance variable outside any method

var urlString = "http://myurl"

Define a function addPathComponent() and call it every time a row is tapped passing the folder name as the parameter. Using the method stringByAppendingPathComponent avoids confusion with the slash path separators.

func addPathComponent(component : String)
{
  urlString = urlString.stringByAppendingPathComponent(component)
  // do something with the new urlString value
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.