0

Look at this code:

let url = NSURL(string: physicst.image as String)
        if let url = url {
            let request = NSMutableURLRequest(URL: url)
            let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
                if let data = data {
                    cell.imageView?.image = UIImage(data: data)
                }
            })
            task.resume()
        }else {
            print ("nill URL \(physicst.image)")
        }

so I have a string, and that string is a url, and I want to load it.

that code is in a table view cells, so it is being called for each cell.

as you see, i am checking if the url is nil or not, and if not, i am making a print statement. almost all the urls are not nil, exception the following ones (which are complemetly valid)

http://commons.wikimedia.org/wiki/Special:FilePath/Kai_Manne_Börje_Siegbahn.jpg?width=300

http://commons.wikimedia.org/wiki/Special:FilePath/Виталий_Лазаревич_Гинзбург.jpg?width=300

http://commons.wikimedia.org/wiki/Special:FilePath/赤崎記念研究館.jpg?width=300

http://commons.wikimedia.org/wiki/Special:FilePath/Kai_Manne_Börje_Siegbahn.jpg?width=300

http://commons.wikimedia.org/wiki/Special:FilePath/赤崎記念研究館.jpg?width=300

The first thing you may argue is to encode the url, and that is what I did like this:

var image = oneBinding["p"]!!["value"] as! NSString
                        image = image.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())!

but then even the urls that were working, stopped working. what i am missing please ?

Update

Here is the whole code of my UITableViewController (it is easy)

class PhysicistTableViewController: UITableViewController {

    var physicsts : [Physicst]?

    @IBOutlet var physicstsTableView: UITableView!



    override func viewDidLoad() {
        super.viewDidLoad()
        loadDataFromDBPedia()
    }

    func loadDataFromDBPedia()  {
        let session = NSURLSession.sharedSession()
        var url = "http://dbpedia.org/sparql/"
        let query = "http://dbpedia.org&query=select * {?o  dbo:thumbnail ?p . ?o dbo:award dbr:Nobel_Prize_in_Physics}"
        url = url + "?default-graph-uri=" + query.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())!
        url = url + "&format=JSON&CXML_redir_for_subjs=121&CXML_redir_for_hrefs=&timeout=30000&debug=on"
        let request = NSMutableURLRequest(URL: NSURL(string: url)!)
        let task = session.dataTaskWithRequest(request, completionHandler: {(data, response ,error) in
            if let error = error {
                print ("\(error)")
            }
            if let response = response {
                let httpResponse = response as! NSHTTPURLResponse
                let statusCode = httpResponse.statusCode
                print("Status code = \(statusCode)")
            }
            if let data = data  {
                do {
                    let jsonResponse = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions())
                    let binding = jsonResponse["results"]!!["bindings"] as! NSArray
                    for oneBinding in binding {
                        let name = oneBinding["o"]!!["value"] as! NSString
                        let image = oneBinding["p"]!!["value"] as! NSString
                        //image = image.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())!
                        let physicst = Physicst(image: image, name: name)
                        if self.physicsts == nil {
                            self.physicsts = [Physicst]()
                        }
                        self.physicsts!.append(physicst)
                    }
                    self.physicstsTableView.reloadData()
                }catch _ {
                    print ("not well json-formatted response")
                }
            }
        })
        task.resume()
    }

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if self.physicsts == nil {
            return 0
        }else {
            return self.physicsts!.count
        }
    }


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("physicstCell")! as UITableViewCell
        let row = indexPath.row
        let physicst = self.physicsts![row]
        cell.textLabel?.text = physicst.name as String
        if (physicst.imageData == nil) {
            let session = NSURLSession.sharedSession()
            let url = NSURL(string: physicst.image as String)
            if let url = url {
                let request = NSMutableURLRequest(URL: url)
                let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
                    if let data = data {
                        let imageData = UIImage(data: data)
                        cell.imageView?.image = imageData
                        physicst.imageData = imageData
                        self.physicstsTableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
                    }
                })
                task.resume()
            }else {
                print ("nill URL \(physicst.image)")
            }
        }else {
            cell.imageView?.image = physicst.imageData!
        }
        return cell
    }
}
sarah
  • 1,201
  • 1
  • 9
  • 29

2 Answers2

1

The method you should use is

stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())

Taken from the playground:

NSURL(string:"http://commons.wikimedia.org/wiki/Special:FilePath/Kai_Manne_Börje_Siegbahn.jpg?width=300".stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!)

Gives the result

http://commons.wikimedia.org/wiki/Special:FilePath/Kai_Manne_B%C3%B6rje_Siegbahn.jpg?width=300

Which is valid :)

Adapted to your code it gives:

let url = NSURL(string: (physicst.image as String).stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet()!)

Beware of the forced unwrapping tho !

Antzi
  • 12,831
  • 7
  • 48
  • 74
  • well interestinly the else statment wasn't called at all. but yet, your code is using a deprecated function. any alternative please ? – sarah Jun 01 '16 at 09:48
  • You need to use a different character set for each part of the url – Leo Dabus Jun 01 '16 at 09:51
  • Btw i think that method still available if you cast it to NSString – Leo Dabus Jun 01 '16 at 09:53
  • +1 for your efforts, if i get another answer with not depressed code, i will check, otherwise, i will accept your answer, appreciate the efforts – sarah Jun 01 '16 at 10:01
  • @sarah you are right, I edited the code. This is not perfect since we should split query string and host string, but it should work anyway. – Antzi Jun 01 '16 at 10:02
1

URLHostAllowedCharacterSet only contains this "#%/<>?@\^{|}

And your URL string contains : .. So make custom set for this

 let yourString = "http://commons.wikimedia.org/wiki/Special:FilePath/Kai_Manne_Börje_Siegbahn.jpg?width=300"
 let customSet =  NSCharacterSet(charactersInString:"=\"#%/:<>?@\\^`{|}").invertedSet
 let finalString = yourString.stringByAddingPercentEncodingWithAllowedCharacters(customSet)   

For more info. check this answer

Community
  • 1
  • 1
Bhavin Bhadani
  • 22,224
  • 10
  • 78
  • 108