iOS - Swift - Parse - Twitter Profile Photo - swift

1) I am trying to access twitter profile photo and upload it to the parse user object
2) Below is the code I am using.
if PFTwitterUtils.isLinkedWithUser(user){
//copy data to parse user
let screenName = PFTwitterUtils.twitter()?.screenName!
let requestString = ("https://api.twitter.com/1.1/users/show.json?screen_name=" + screenName!)
let verify: NSURL = NSURL(string: requestString)!
let request: NSMutableURLRequest = NSMutableURLRequest(URL: verify)
PFTwitterUtils.twitter()?.signRequest(request)
var response: NSURLResponse?
var error: NSError?
let data: NSData = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)!
if error == nil {
let result: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error: &error)
//let names: String! = result?.objectForKey("name") as! String
//let separatedNames: [String] = names.componentsSeparatedByString(" ")
//var firstName = separatedNames.first!
//var 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!)
if(imageData != nil) {
let profileFileObject = PFFile(data:imageData!)
user.setObject(profileFileObject, forKey: "profilePicture")
}
user.saveInBackgroundWithBlock({ (success:Bool, error:NSError?) -> Void in
if(success) {
//println("User details are now updated")
user.pinInBackgroundWithBlock({ (pinUserSuccess:Bool, pinUserError:NSError?) -> Void in
if (pinUserSuccess){
println("User successfully pinned in twitter")
}else {
println("Error in pining the user")
}
})
}
})
} else {
println(error?.description)
}
3) I am using Parse User Interface to sign in using twitter. That is working. I am able to access the screen name
4) I am testing this on a simulator
Question 1 -
In the above code I am getting an error for the below code. Please help!
let data: NSData = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)!
Error Domain=NSURLErrorDomain Code=-1012 \"The operation couldn’t be completed. (NSURLErrorDomain error -1012.)\" UserInfo=0x7fd11aab87a0 {NSErrorFailingURLStringKey=https://api.twitter.com/1.1/users/show.json?screen_name=jayskapadia, NSUnderlyingError=0x7fd11aab51b0 \"The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1012.)\", NSErrorFailingURLKey=https://api.twitter.com/1.1/users/show.json?screen_name=jayskapadia}
Question 2 - I also want to access the email id from the twitter profile. How do I do that?

the photo part now works with the below code
if PFTwitterUtils.isLinkedWithUser(user){
//copy data to parse user.
let screenName = PFTwitterUtils.twitter()?.screenName!
let verify = NSURL(string: "https://api.twitter.com/1.1/account/verify_credentials.json")
var request = NSMutableURLRequest(URL: verify!)
PFTwitterUtils.twitter()!.signRequest(request)
var response: NSURLResponse?
var error: NSError?
var data:NSData = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)!
if error == nil {
let result: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error: &error)
//let names: String! = result?.objectForKey("name") as! String
//let separatedNames: [String] = names.componentsSeparatedByString(" ")
//var firstName = separatedNames.first!
//var 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!)
if (screenName != nil){
user.setObject(screenName!, forKey: "username")
}
if(imageData != nil) {
let profileFileObject = PFFile(data:imageData!)
user.setObject(profileFileObject, forKey: "profilePicture")
}
user.saveInBackgroundWithBlock({ (success:Bool, error:NSError?) -> Void in
if(success) {
//println("User details are now updated")
user.pinInBackgroundWithBlock({ (pinUserSuccess:Bool, pinUserError:NSError?) -> Void in
if (pinUserSuccess){
println("User successfully pinned in twitter")
}else {
println("Error in pining the user")
}
})
}
})
} else {
println(error?.description)
}
}

Related

Extra argument 'error' in call in swift

I am new to swift so please treat me as beginner.
I am following tutorial, this is pretty old tutorial and it has used GoogleMap framework whereas I am doing it with pod. In func geocodeAddress in MapTasks.swift file I am getting error called
Extra argument 'error' in call
func geocodeAddress(address: String!, withCompletionHandler completionHandler: ((status: String, success: Bool) -> Void)) {
if let lookupAddress = address {
var geocodeURLString = baseURLGeocode + "address=" + lookupAddress
geocodeURLString = geocodeURLString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
let geocodeURL = NSURL(string: geocodeURLString)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let geocodingResultsData = NSData(contentsOfURL: geocodeURL!)
let request = NSMutableURLRequest(URL: geocodingResultsData)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
(let data, let response, let error) in
if let _ = response as? NSHTTPURLResponse {
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
if error != nil {
print("error=\(error!)")
return
}
if let parseJSON = json {
}
} catch {
print(error)
}
}
}
task.resume()
else {
// Get the response status.
let status = dictionary["status"] as! String
if status == "OK" {
let allResults = dictionary["results"] as! Array<Dictionary<NSObject, AnyObject>>
self.lookupAddressResults = allResults[0]
// Keep the most important values.
self.fetchedFormattedAddress = self.lookupAddressResults["formatted_address"] as! String
let geometry = self.lookupAddressResults["geometry"] as! Dictionary<NSObject, AnyObject>
self.fetchedAddressLongitude = ((geometry["location"] as! Dictionary<NSObject, AnyObject>)["lng"] as! NSNumber).doubleValue
self.fetchedAddressLatitude = ((geometry["location"] as! Dictionary<NSObject, AnyObject>)["lat"] as! NSNumber).doubleValue
completionHandler(status: status, success: true)
}
else {
completionHandler(status: status, success: false)
}
}
})
}
else {
completionHandler(status: "No valid address.", success: false)
}
}
So far I know is I am getting this error because of the diffrent version of swift. Tutorial I am following is written in old version of swift and I am doing it in new
In Swift 2.0, you cannot add 'error' argument in NSJSONSerialization method, you need to use try-catch statement as follows:
func geocodeAddress(address: String!, withCompletionHandler completionHandler: ((status: String, success: Bool) -> Void)) {
if let lookupAddress = address {
var geocodeURLString = baseURLGeocode + "address=" + lookupAddress
geocodeURLString = geocodeURLString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
let geocodeURL = NSURL(string: geocodeURLString)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let geocodingResultsData = NSData(contentsOfURL: geocodeURL!)
let request = NSMutableURLRequest(URL: geocodeURL!)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
(let data, let response, let error) in
if let _ = response as? NSHTTPURLResponse {
do {
let dictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
if error != nil {
print("error=\(error!)")
return
}
if let parseJSON = dictionary {
let status = dictionary["status"] as! String
if status == "OK" {
let allResults = dictionary["results"] as! Array<Dictionary<NSObject, AnyObject>>
self.lookupAddressResults = allResults[0]
// Keep the most important values.
self.fetchedFormattedAddress = self.lookupAddressResults["formatted_address"] as! String
let geometry = self.lookupAddressResults["geometry"] as! Dictionary<NSObject, AnyObject>
self.fetchedAddressLongitude = ((geometry["location"] as! Dictionary<NSObject, AnyObject>)["lng"] as! NSNumber).doubleValue
self.fetchedAddressLatitude = ((geometry["location"] as! Dictionary<NSObject, AnyObject>)["lat"] as! NSNumber).doubleValue
completionHandler(status: status, success: true)
}
else {
completionHandler(status: status, success: false)
}
}
} catch {
print(error)
}
}
}
task.resume()
})
}
}

String(data: data, encoding: NSUTF8StringEncoding) return nil

I am using JSQMessage and pare to send and save video files
if (mediaType == kUTTypeVideo as String) || (mediaType == kUTTypeMovie as String) {
let movieURL = info[UIImagePickerControllerMediaURL] as? NSURL
let videoMediaItem = JSQVideoMediaItem.init(fileURL: movieURL, isReadyToPlay: true)
let message = JSQMessage(senderId: self.senderId, senderDisplayName: senderDisplayName, date: NSDate(), media: videoMediaItem)
self.saveMediaToParse(message, data: NSData(contentsOfURL: movieURL!)!, fileName:"videoFile")
self.messages += [message]
self.publishMessageToChannel(message)
self.finishSendingMessage()
}
func saveMediaToParse(message:JSQMessage, data:NSData, fileName:String) {
let imageFile = PFFile.init(data: data)
let msg = PFObject(className: "test")
msg["senderId"] = message.senderId
msg[fileName] = imageFile
msg["senderDisplayName"] = message.senderDisplayName
msg["user"] = PFUser.currentUser()
msg.saveInBackgroundWithBlock { (success, error) -> Void in
if(error != nil) {
NSLog("error: %#",(error?.localizedDescription)!)
}
}
}
when I am trying to get the video URL from the data as String I get back nil value. What am I doing wrong?
message["videoFile"].getDataInBackgroundWithBlock({ (data, error) -> Void in
if let data = data where error == nil {
**let dataStr = String(data: data, encoding: NSUTF8StringEncoding)**
let movieUrl = NSURL(string: dataStr!)
let videoMediaItem = JSQVideoMediaItem.init(fileURL: movieUrl, isReadyToPlay:true)
jsqMessage = JSQMessage(senderId:message["senderId"] as! String, displayName: message["senderDisplayName"] as! String, media: videoMediaItem)
self.messages.append(jsqMessage)
self.collectionView?.reloadData()
self.scrollToBottomAnimated(true)
}
})
}
self.messages.append(jsqMessage)
Ended up doing
let dataStr = NSTemporaryDirectory() + "temp.mov"
data.writeToFile(dataStr, atomically: true)
let movieUrl = NSURL(fileURLWithPath: dataStr)
Instead of
let dataStr = String(data: data, encoding: NSUTF8StringEncoding)**

swift - CoreData EXC_BAD_ACCESS(code=1, address=0x0))

I am getting EXC_BAD_ACCESS error when I try to access my author item in my CoreData.
I am gettin the error when I try to access author.authorName
func setupAuthorList(){
var error: NSError?
let request = NSFetchRequest(entityName: "AuthorList")
let results = self.context!.executeFetchRequest(request, error: &error) as! [AuthorList]
if let _error = error {
println("\(_error.localizedDescription)")
} else {
for author in results {
println("\(author.authorName)")
}
}
self.authorLabel.text = author!.authorName
let urlString = author!.authorImage
let url = NSURL(string: urlString)
self.avatarImageView.layer.cornerRadius = self.avatarImageView.frame.size.width/2
self.avatarImageView.clipsToBounds = true
self.avatarImageView.hnk_setImageFromURL(url!)
self.newspaperLabel.text = author!.newspaperName
}

In iOS swift Json Parsing How to Pass Parameters in post method

Here I have Tried to Sign Up the App Using Mobile Number but I cant do in correct format,I have error in Json parsing for signup the app.
Here I give the code what i am tried,
var request = NSMutableURLRequest(URL: NSURL(string: "http://app.mycompany.in/gcm/test_slim.php/register")!, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 5)
var response: NSURLResponse?
var error: NSError?
var reponseError: NSError?
var urlData: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&reponseError)
// create some JSON data and configure the request
let jsonString = "json=[{\"gsm_number\":\(Mobile),\"name\":\(Name),\"email\":\(Email),\"status\":\(Status),\"ver_code\":,\"profile_picture\":,\"device_id\":,\"gcm\":,\"is_register\":,\"thumb_image\":,\"user_baground_img\":}]"
request.HTTPBody = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
// send the request
NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)
// look at the response
if let httpResponse = response as? NSHTTPURLResponse {
println("HTTP response: \(httpResponse.statusCode)")
println("jsonString: \(jsonString)")
var responseData:NSString = NSString(data:urlData!, encoding:NSUTF8StringEncoding)!
let VerificationcodeViewController = self.storyboard?.instantiateViewControllerWithIdentifier("verificationcodeViewController") as UIViewController
self.navigationController?.pushViewController(VerificationcodeViewController, animated: true)
} else {
println("No HTTP response")
var alertView:UIAlertView = UIAlertView()
alertView.title = "Error!"
alertView.message = "Error. & Some Problem was Found"
alertView.delegate = self
alertView.addButtonWithTitle("OK")
alertView.show()
}
You can't have empty keys, try this :
let parameters = [
"gsm_number" : Mobile,
"name" : Name,
"email" : Email,
"status" : Status,
]
let jsonData = NSJSONSerialization.dataWithJSONObject(parameters, options: NSJSONWritingOptions.allZeros, error: nil)
let jsonString = "json=\(NSString(data: jsonData!, encoding: NSUTF8StringEncoding)!)"
You jsonString does not conform to the JSON syntax.
You can't have json= at the beginning, = isn't an allowed separator in JSON, use :
You need to wrap the string variables with double quotes (and escape them)
You can't have empty keys like that with just the value missing, you have to use null
Example of valid string for your variables:
let jsonString = "[{\"gsm_number\":\(Mobile),\"name\":\"\(Name)\",\"email\":\"\(Email)\",\"status\":\(Status),\"ver_code\":null}]"
Or with a 'json' key at the beginning like you had:
let jsonString = "{\"json\":[{\"gsm_number\":\(Mobile),\"name\":\"\(Name)\",\"email\":\"\(Email)\",\"status\":\(Status),\"ver_code\":null}]}"
Put this in a Playground and show the Assistant Editor in the "View" menu, it will help you understand:
let Mobile = 42
let Name = "James"
let Email = "test#test.com"
let Status = 200
let jsonString = "[{\"gsm_number\":\(Mobile),\"name\":\"\(Name)\",\"email\":\"\(Email)\",\"status\":\(Status),\"ver_code\":null}]"
let data = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
Swift 1
var err: NSError?
let json = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.allZeros, error: &err) as? [[String:AnyObject]]
if err != nil {
println(err)
} else {
println(json![0]["status"]!)
}
Swift 2
do {
if let data = data,
let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [[String:AnyObject]] {
if let status = json[0]["status"] as? Int {
print(status)
}
}
} catch let error as NSError {
print(error.localizedDescription)
}

Getting the JSON data from cloudant

I have a database created in Cloudant and I am trying to parse that data in my Swift project. I have imported the Cloudant libraries, but I am not able to parse the data.
Here is the code that I Have been using till now
var url = "https://username:password#cloudant.com/dashboard.html#/database/db_2/login_details"
var request = NSMutableURLRequest()
request.URL = NSURL(string: url)
request.HTTPMethod = "GET"
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: error) as? NSDictionary
if jsonResult != nil {
if let item = json[0] {
if let student_name = item["Student_name"] {
if let pasword = student_name["password"] {
println("Login Successfull")
}
}
}
}
}
Can somebody tell me where am I going wrong?
You should use stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding) to convert any special characters your link may have. Also NSURL may return nil so you need to use if let to handle it as follow :
if let link = "https://username:password#cloudant.com/dashboard.html#/database/db_2/login_details".stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding) {
if let checkedUrl = NSURL(string: link) {
println("valid Url")
// your code
} else {
println("invalid Url")
}
}