get user's location info using facebook ios sdk in swift - xcode

I couldn't find any info about getting user's location info in swift and xcode 6
I tried
var fbcity = user.objectForKey("location")
var fbcountry = user.objectForKey("country")
But didn't work.
Any idea how to achieve this ?

Perhaps you could supply us with a little more information, e.g. which Facebook SDK you are using and what parameters FBSDKGraphRequest has to return user. Note that there is no specific information about country, the location field in the user node when your send a graph request for the user profile. It will return the subfields: id and name, where name is
With the latest Facebook iOS SDK 4.0 you can do something like:
override func viewDidLoad() {
super.viewDidLoad()
self.loginView.delegate = self
if FBSDKAccessToken.currentAccessToken() != nil {
fetchUserData()
} else {
loginView.readPermissions = ["public_profile", "email", "user_friends"]
}
}
func fetchUserData() {
let graphRequest: FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: nil)
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if error != nil {
// Process error
println("Error: \(error)")
} else {
let location: NSDictionary! = result.valueForKey("location") as NSDictionary
let city: NSString = location.valueForKey("name") as NSString
}
})
}
More detailed info can be found on Facebook Graph API User page.

Related

Square Connect SDK opens a blank page

I am attempting to implement Square Connect iOS SDK, and after implementing and clicking the pay button it opens up the Square Payment app and redirects to a blank page .. have you guys had the same issues ?
My App delegate has the proper section:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
guard let sourceApplication = options[.sourceApplication] as? String,
sourceApplication.hasPrefix("com.squareup.square") else {
return false
}
do {
let response = try SCCAPIResponse(responseURL: url)
if let error = response.error {
// Handle a failed request.
print(error.localizedDescription)
} else {
// Handle a successful request.
}
} catch let error as NSError {
// Handle unexpected errors.
print(error.localizedDescription)
}
return true
}
I have created a proper URL scheme inside the Square portal. Also my view controller has the correct code:
func charge()
{
// connect v1
if let callbackURL = URL(string: "myscheme://")
{
do
{
SCCAPIRequest.setClientID("xxxxxxxxxxx")
let amount = try SCCMoney(amountCents: 100, currencyCode: "USD")
let request = try SCCAPIRequest(
callbackURL: callbackURL,
amount: amount,
userInfoString: nil,
locationID: nil,
notes: "Purchase for cleaning",
customerID: nil, supportedTenderTypes: .all,
clearsDefaultFees: true,
returnAutomaticallyAfterPayment: true)
try SCCAPIConnection.perform(request)
}
catch let error as NSError {
print(error.localizedDescription)
}
}
}
https://snag.gy/R4A30L.jpg
Andrei
You need to make sure you delete all apps from the phone with having duplicate bundle ids. This way you will make sure you go back to the original app which triggered the payment.

Swift 2 Mapkit Get City from user location

Is it possible to get the name of the city and put that one into an array of strings from the user location, using Mapkit?
I already know how to get the user location so you dont have to go into that.
Yes you can with using CLGeocoder class try to use this code
CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: newCoordinates.latitude, longitude: newCoordinates.longitude),
completionHandler: {(placemarks, error) -> Void in
if error != nil {
print("Reverse geocoder failed with error" + error!.localizedDescription)
return
}
if placemarks!.count > 0 {
let pm = placemarks![0]
let c = pm.locality // city of place mark
}
else {
annotation.title = "Unknown Place"
self.outletOfMapView.addAnnotation(annotation)
print("Problem with the data received from geocoder")
}
})

Facebook Friend List Save As Array to Parse - Swift

I want to convert the friend list ids that I am getting from facebook as an array to save in parse. My code is as below but I am getting a "unexpectedly found nil while unwrapping an Optional value" error. What should I do to save the result to parse and retrieve it as array when required?
let fbRequest = FBSDKGraphRequest(graphPath:"/me/friends", parameters: nil);
fbRequest.startWithCompletionHandler { (connection : FBSDKGraphRequestConnection!, result : AnyObject!, error : NSError!) -> Void in
if error == nil {
print("Friends are : \(result)")
if let dict = result as? Dictionary<String, AnyObject>{
let profileName:NSArray = dict["name"] as AnyObject? as! NSArray
let facebookID:NSArray = dict["id"] as AnyObject? as! NSArray
print(profileName)
print(facebookID)
}
}
else {
print("Error Getting Friends \(error)");
}
}
When I use the code below in print() I get the result below:
Friends are : {
data = (
{
id = 138495819828848;
name = "Michael";
},
{
id = 1105101471218892;
name = "Johnny";
}
);
The issue is that you are trying to access the name and id elements from the top-level dictionary, where you need to be accessing data.
When you call the FB Graph API for friends it will return an array of dictionaries (one per friend).
Try this:
let fbRequest = FBSDKGraphRequest(graphPath:"/me/friends", parameters: nil)
fbRequest.startWithCompletionHandler { (connection : FBSDKGraphRequestConnection!, result : AnyObject!, error : NSError!) -> Void in
if error == nil {
print("Friends are : \(result)")
if let friendObjects = result["data"] as? [NSDictionary] {
for friendObject in friendObjects {
println(friendObject["id"] as NSString)
println(friendObject["name"] as NSString)
}
}
} else {
print("Error Getting Friends \(error)");
}
}
You should also check out this SO post with more information on the FB Graph API. Here's a brief snippet.
In v2.0 of the Graph API, calling /me/friends returns the person's
friends who also use the app.
In addition, in v2.0, you must request the user_friends permission
from each user. user_friends is no longer included by default in every
login. Each user must grant the user_friends permission in order to
appear in the response to /me/friends. See the Facebook upgrade guide
for more detailed information, or review the summary below.

Continuously update a UILabel in Swift

I have a function, shown below, that I would like to continuously update. It is taking data from a webpage, and every so often that webpage is updated to reflect current information. Is there a way that I can catch this update and reflect that in my application? I'm pretty new to Swift and iOS programming. Some of the code made seem very bizarre, but it currently works for whatever song is playing when you first open the app (that is, it updates the text to show that song playing but doesn't update later).
let url = NSURL(string: "http://api.vicradio.org/songs/current")!
let request = NSMutableURLRequest(URL: url)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) { (data: NSData?, response: NSURLResponse?, error: NSError?) in
if error != nil {
return
}
let name = NSString(data: data!, encoding: NSUTF8StringEncoding) as! String
var songName = ""
var artistName = "by "
var quoteNumber = 0
for character in name.characters {
if character == "\"" {
quoteNumber++
}
if quoteNumber == 3 && character != "\"" {
songName += String(character)
} else if quoteNumber == 7 && character != "\"" {
artistName += String(character)
}
}
if (songName != "no song metadata provided") {
self.SongNowText.text = songName
self.ArtistNowText.text = artistName
self.SongNowText.setNeedsDisplay()
self.ArtistNowText.setNeedsDisplay()
} else if (songName == "no song metadata provided") {
self.SongNowText.text = "The Best of What's Next!"
self.ArtistNowText.text = "only on VIC Radio"
}
}
task!.resume()
It looks like the URL you're accessing there is an API endpoint putting out JSON. I highly recommend using NSJSONSerialization.JSONObjectWithData to parse the response body into a dictionary and use that instead of rolling your own solution by counting quote marks.
The callback to dataTaskWithURL is executed on a background thread. Avoid updating the UI on anything besides the main thread because it can cause problems. Use dispatch_async to execute your UI update function on the main thread as in the example.
All you can do with this API is send it requests and read the responses. You can poll the endpoint at a regular interval while the app is open and get decent results from that. NSTimer is one way to do that, and it requires you put the method you want to execute repeatedly in a class inheriting from NSObject because it depends on Objective-C style message sending.
Throw this in a playground and try it:
import Cocoa
import XCPlayground
XCPSetExecutionShouldContinueIndefinitely()
class RadioDataAccessor : NSObject {
private let callback: [String : AnyObject] -> Void
init(callback: [String : AnyObject] -> Void) {
self.callback = callback
super.init()
NSTimer.scheduledTimerWithTimeInterval(5.0, target: self,
selector: "updateData", userInfo: nil, repeats: true)
// just so it happens quickly the first time
updateData()
}
func updateData() {
let session = NSURLSession.sharedSession()
let url = NSURL(string: "http://api.vicradio.org/songs/current")!
session.dataTaskWithURL(url) { data, response, error in
if error != nil {
return
}
var jsonError = NSErrorPointer()
let json = NSJSONSerialization.JSONObjectWithData(data,
options: NSJSONReadingOptions.allZeros,
error: jsonError) as? [String : AnyObject]
if jsonError != nil {
return
}
dispatch_async(dispatch_get_main_queue()) { self.callback(json!) }
}.resume()
}
}
RadioDataAccessor() { data in
println(data)
}
You may want to save the timer to a variable and expose a function that lets you invalidate it.

Parse.com Refresh User Info

I have written an iOS app that uses Parse.com. When I need to change the information about a user I use refreshInBackgroundWithBlock. I am now writing the app for Mac OS X but I do not seem to be able to use refreshInBackgroundWithBlock. Any Suggestions?
Here is the code below.
//Refresh the User Info
currentUser.refreshInBackgroundWithBlock { (object, error) -> Void in
//Fetch the User Info
currentUser.fetchIfNeededInBackgroundWithBlock { (result, error) -> Void in
//Check if the comments read is nil
if object.objectForKey("commentsRead") === nil {
println("Comments Read is empty")
} else {
var currentRead:[Int] = []
//If not empty assign the array to the value
currentRead = object.objectForKey("commentsRead") as Array
currentRead.append(0)
var user = PFUser.currentUser()
user.setObject(currentRead, forKey: "commentsRead")
user.saveInBackgroundWithBlock { (result, error) -> Void in
println("Completed!")
}
}
According to the parse doc, refreshInBackgroundWithBlock is deprecated and replaced by fetchInBackgroundWithBlock (See this)
So you don't need to call refreshInBackgroundWithBlock.

Resources