I'm trying to get user image from twitter(parse- twitter login) using this code :
if PFTwitterUtils.isLinkedWithUser(PFUser.currentUser()!) {
let screenName = PFTwitterUtils.twitter()?.screenName!
let requestString = NSURL(string: "https://api.twitter.com/1.1/users/show.json?screen_name=" + screenName!)
let request = NSMutableURLRequest(URL: requestString!, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 5.0)
PFTwitterUtils.twitter()?.signRequest(request)
let session = NSURLSession.sharedSession()
session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
print(data)
print(response)
print(error)
if error == nil {
var result: AnyObject?
do {
result = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments)
} catch let error2 as NSError? {
print("error 2 \(error2)")
}
let names: String! = result?.objectForKey("name") as! String
let separatedNames: [String] = names.componentsSeparatedByString(" ")
//self.firstName = separatedNames.first!
//self.lastName = separatedNames.last!
let urlString = result?.objectForKey("profile_image_url_https") as! String
let hiResUrlString = urlString.stringByReplacingOccurrencesOfString("_normal", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
let twitterPhotoUrl = NSURL(string: hiResUrlString)
let imageData = NSData(contentsOfURL: twitterPhotoUrl!)
let twitterImage: UIImage! = UIImage(data:imageData!)
self.userImg = UIImageView(image: twitterImage)
}
}).resume()
}
but it imageData is nil
let imageData = NSData(contentsOfURL: twitterPhotoUrl!)
let twitterImage: UIImage! = UIImage(data:imageData!)
twitterphotoUrl actually have the link
any help???
I would guess that you're getting an ATS exception from the pbs.twimg.com URL, so you're not getting the data, so you fall over when you force unwrap it. You should add that domain to the list of ATS exceptions as shown here, [documented here] (https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html) (search for NSExceptionDomain on that page) and discussed in many other places.
In addition to that, force unwrapping the results of URL calls is always a bad idea, since any number of things could prevent a data object being created. You should be using guard or if let statements in this case.
Try with below code,
if let imageData = NSData(contentsOfURL: twitterPhotoUrl!)
{
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.userImg.image = UIImage(image: imageData!)
})
}
Hope this will work
Related
I am trying to show an image into my table cell view from an API. But it has given a partial link there, as a result, I am getting NSURL connection error code -1002.
Here is my API link: https://api.opendota.com/api/heroStats
I am trying to parse "icon" among them:
"img": "/apps/dota2/images/heroes/antimage_full.png?",
"icon": "/apps/dota2/images/heroes/antimage_icon.png",
My code:
// Generating imageview
if let imageURL = URL(string: heroes[indexPath.row].icon){
print (imageURL)
DispatchQueue.global().async {
let data = try? Data (contentsOf: imageURL)
if let data = data {
let image = UIImage(data: data)
DispatchQueue.main.async {
cell.charIcon.image = image
} //end of 2nd dispatch
}//end of if
}//end of 1st dispatch
}// end of imageURL
How can I solve this problem? Any easy way for swift 4?
You can get the url components of your api link and use your icon "partial link" to set the path property of the URL components. After that you just need to get the resulting url of the url components:
let apiLink = "https://api.opendota.com/api/heroStats"
let apiURL = URL(string: apiLink)!
if var urlComponents = URLComponents(url: apiURL, resolvingAgainstBaseURL: false) {
let iconString = "/apps/dota2/images/heroes/antimage_icon.png"
urlComponents.path = iconString
if let iconURL = urlComponents.url {
print(iconURL.absoluteString)
}
}
This will print
https://api.opendota.com/apps/dota2/images/heroes/antimage_icon.png
You can create a custom method to return a new URL based on the new path string as follow:
extension URL {
var urlComponents: URLComponents? {
return URLComponents(url: self, resolvingAgainstBaseURL: false)
}
func bySettingNew(path: String) -> URL? {
guard var urlComponents = urlComponents else { return nil }
urlComponents.path = path
return urlComponents.url
}
}
let apiLink = "https://api.opendota.com/api/heroStats"
let apiURL = URL(string: apiLink)!
let iconString = "/apps/dota2/images/heroes/antimage_icon.png"
if let iconURL = apiURL.bySettingNew(path: iconString) {
print(iconURL.absoluteString)
}
You can also add this helper to your project to make it easier for you to download an image asynchronously into your image view:
extension UIImageView {
func downloaded(from url: URL, contentMode mode: UIView.ContentMode = .scaleAspectFit) {
URLSession.shared.dataTask(with: url) { data, response, error in
guard
let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
let data = data, error == nil,
let image = UIImage(data: data)
else { return }
DispatchQueue.main.async() { [weak self] in
self?.contentMode = mode
self?.image = image
}
}.resume()
}
}
if let imageURL = apiURL.bySettingNew(path: heroes[indexPath.row].icon) {
cell.charIcon.downloaded(from: imageURL)
}
let imgURL:NSURL = NSURL(string: "\(ImageName)")!
at the above line,i'm getting fatal error
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)
Code :
let ImageName = obj["image"] as! String
let imgURL:NSURL = NSURL(string: "\(ImageName)")!
let request: NSURLRequest = NSURLRequest(URL: imgURL)
let session = NSURLSession.sharedSession()
let Imgtask = session.dataTaskWithRequest(request){
(data, response, error) -> Void in
if (error == nil && data != nil)
{
func display_image()
{
pointAnnoation.DisplayImage = UIImage(data: data!)
}
dispatch_async(dispatch_get_main_queue(), display_image)
}
}
Imgtask.resume()
From the above code im trying to store my image from database in annotation
if i printed the 'ImageName' it returns the name from the database correctly, but unable to retain the image
it resulting in the error while running.
You say that
if i printed the 'ImageName' it returns the name from the database correctly
Then that must mean that the ImageName is not valid for a URL
If you look at the description of NSURL(string:) it says:
The URL string with which to initialize the NSURL object. This URL string must conform to URL format as described in RFC 2396, and must not be nil. This method parses URLString according to RFCs 1738 and 1808.
So the question is...how does ImageName look? And can you create a URL from it?
Apart from that, it is always a good idea to use ? instead of ! as #PhillipMills says
Update: I can see that you have posted an example of your URL now. If I do this in a playground:
let url = NSURL(string: " goo.gl/pBmA0d")
I get nil in return, so it would seem that short URLs and NSURLaren't the best of friends.
Update 2: hmm, guess I spoke to quickly, if you look at the above you can see that I have a space before the goo.gl part, if I change that to:
let url = NSURL(string: "goo.gl/pBmA0d")
it actually works, I get a NSURL object.
But another thing I stumbled upon in your code. You declare ImageName as a String here:
let ImageName = obj["image"] as! String
So you don't have to wrap it in \() later on
let imgURL:NSURL = NSURL(string: "\(ImageName)")!
You could simply say:
let imageURL = NSURL(string: ImageName)
And then...as others has said, it is always a good idea to use ? instead of !
So you could write:
if let imageName = obj["image"] as? String,
let imageURL = NSURL(string: imageName) {
//we're in business :-)
}
and be safe and sound
Try to use guard or if let for helping yourself.
let ImageName = obj["image"] as! String
if let imgURL = NSURL(string: ImageName) {
let request: NSURLRequest = NSURLRequest(URL: imgURL)
let session = NSURLSession.sharedSession()
let Imgtask = session.dataTaskWithRequest(request){ (data, response, error) -> Void in
if (error == nil && data != nil)
{
// What's that func??
func display_image()
{
pointAnnoation.DisplayImage = UIImage(data: data!)
}
dispatch_async(dispatch_get_main_queue(), display_image)
}
}
}
Imgtask.resume()
Don't make force unwrap...use if let to avoid crash ...
if let img = obj["image"] as? String,
imgURL = NSURL(string: img) {
// ... continue with your code ...
}
Please try the following code:
//ImageName is a String type.
guard let ImageName = obj["image"] as? String , let imgURL = NSURL(string: ImageName) else{
return
}
let request: NSURLRequest = NSURLRequest(URL:imgURL)
let session = NSURLSession.sharedSession()
let Imgtask = session.dataTaskWithRequest(request){
(data, response, error) -> Void in
if (error == nil && data != nil)
{
func display_image()
{
pointAnnoation.DisplayImage = UIImage(data: data!)
}
dispatch_async(dispatch_get_main_queue(), display_image)
}
Imgtask.resume()
I want to Load image using JSON parsing in collectionView. I'm getting array of image URLs, but images are not shown on UIImageView. I have used this code after getting JSON array and displaying it in UICollectionView's UIImageView.
if let url = NSURL(string: self.Products[indexPath.row].image) {
if let data = NSData(contentsOfURL: url){
cell.product_image.contentMode = UIViewContentMode.ScaleAspectFit
cell.product_image.image = UIImage(data: data)
}
}
But I am not able to load image, but text is displayed. I have used this code in cellForItemAtIndexPath method.. Can anyone suggest me what am I doing wrong?
func jsonParsingFromURL(){
// 1
let reposURL = NSURL(string: "http://api.room2shop.com/api/product/GetProducts?categoryId=24&filter=2&pageNumber=1")
// 2
if let JSONData = NSData(contentsOfURL: reposURL!) {
// 3
do
{
if let json = try NSJSONSerialization.JSONObjectWithData(JSONData, options: .AllowFragments) as? NSDictionary {
// 4
if let reposArray = json["ProductList"] as? [NSDictionary] {
// 5
for item in reposArray {
Products.append(ProductList(json: item))
}
}
}
}
catch {
print("Error with Json: \(error)")
}
}
}
This is my JSON parsing code
to reflect changes, you need to use
self.collectionView?.reloadData()
EDIT
1- please replace this block with this, and tell me if you get the urls normally, for me I get the urls normally
for item in reposArray
{
//ProductList(json: item)
//Products.append(ProductList(json: item))
//print(item)
print("__________")
print(item["Image"]!)
}
2- i was getting
Transport Security has Blocked a cleartext HTTP
solution was here.
Transport security has blocked a cleartext HTTP
use this
// taking the URL , then request image data, then assigne UIImage(data: responseData)
let imgURL: NSURL = NSURL(string: "www.example.com/image.jpg")!
let request: NSURLRequest = NSURLRequest(URL: imgURL)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) {
(data,response,error) -> Void in
if ( error == nil && data != nil ) {
func display_image() {
// imageView.post.image = your UIImage
self.imageViewPost.image = UIImage(data: data!)
}
dispatch_async(dispatch_get_main_queue(), display_image)
}
}
task.resume()
// end of loading img
The image is a URL which is not saved locally inside the image.xassets, so you need to parse the URL using the extension given below.
// add the extension
extension UIImageView {
func loadImage(urlString: String) {
let url = URL(string: urlString)!
URLSession.shared.dataTask(with: url, completionHandler: { (data, respones, error) in
if error != nil {
print(error ?? "")
return
}
DispatchQueue.main.async {
self.image = UIImage(data: data!)
}
}).resume()
}
}
// call this statement in your vc (where you polpulate)
yourImageView.loadImage(urlString:yourUrl)
When I run the application Xcode told me that
unexpectedly found nil while unwrapping an Optional value
at the url but the url isn't nil, can someone help?
here is the code
import Foundation
protocol WeatherUndergroundServiceByGeographicalDelegate{
func setWeatherByGeographical(weather:WeatherUnderground)
}
class WeatherUndergoundServiceByGeographical{
var delegate:WeatherUndergroundServiceByGeographicalDelegate?
func getWeatherFromWeatherUnderground(latitude:Double, longitude:Double){
let path = "http://api.wunderground.com/api/48675fd2f5485cff/conditions/geolookup/q/\(latitude,longitude).json"
let url = NSURL(string: path)
//session
let session = NSURLSession.sharedSession()
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Error is at here~~~~~~~~~~~~~~~~~~~~~~~~~
let task = session.dataTaskWithURL(url!) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
let json = JSON(data: data!)
//parsing json weather condition from weather api. using swiftyJson
let name = json["current_observation"]["display_location"]["city"].string
let temp = json["current_observation"]["temp_c"].double
let windsp = json["current_observation"]["wind_mph"].double
//prasing the weather data
let weather = WeatherUnderground(cityName: name!, temperature: temp!, windSpeed: windsp!)
if self.delegate != nil{
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.delegate?.setWeatherByGeographical(weather)
})
}
}
task.resume()
}
}
You probably have error in your path string, try this:
let path = "http://api.wunderground.com/api/48675fd2f5485cff/conditions/geolookup/q/\(latitude),\(longitude).json"
The reason is that you are interpolating tuple value \(latitude,longitude) in the string, which adds extra space and makes url string invalid because space is not percent-escaped.
Instead you have to interpolate each value with a comma between them: \(latitude),\(longitude)
let path = "http://api.wunderground.com/api/48675fd2f5485cff/conditions/geolookup/q/\(latitude,longitude).json"
I think you mean:
let path = "http://api.wunderground.com/api/48675fd2f5485cff/conditions/geolookup/q/\(latitude),\(longitude).json"
i am storing my data in file manager in my app. now i want to delete specific data by code so how can i do this?
here is my code which i used for store data
var localURL : String
init()
{
let urls = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
localURL = urls.first!.URLByAppendingPathComponent("podcasts").path!
createDirectory(localURL)
}
func downloadShow(slug: String, show: NSDictionary) {
SVProgressHUD.showWithStatus("Downloading...")
let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)
let url = NSURL(string: show["file"] as! String)
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "GET"
let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
if (error == nil) {
let showFileName = url?.lastPathComponent
let programMP3Path = self.localURL + "/" + slug + "/" + showFileName!
let programDataPath = programMP3Path + ".dat"
data?.writeToFile(programMP3Path, atomically: true)
show.writeToFile(programDataPath, atomically: true)
print("Success")
print(showFileName)
SVProgressHUD.dismiss()
}
else {
// Failure
print("Faulure: \(error)");
}
})
task.resume()
}}
Not sure about session methods. Here's how to delete file in user temp directory, if that helps
let myFileName = "myFile.txt"
var fileManager = NSFileManager()
var tempDirectory = NSTemporaryDirectory()
let filePath = tempDirectory.stringByAppendingPathComponent(myFileName)
var error: NSError?
// also good idea to check before if the file is in the directory
let path = tmpDir.stringByAppendingPathComponent(isFileInDir)
fileManager.removeItemAtPath(path, error: &error)