I'm working on an app where I need to query places from the google places API and save the nearest place to the user's google account (they sign into the app through GIDSignIN). The Places API is activated in the console and they key is correct, however, the URL might be problematic and I keep getting this error...
Optional(["error_message": This IP, site or mobile application is not
authorized to use this API key. Request received from IP address
2607:f598:b349:fd01:94f8:7386:d82c:1b29, with empty referer,
"results": ( ), "status": REQUEST_DENIED, "html_attributions": ( )])
The method that is called to query the API, the current lat and on long come from the location manager (working fine)
func saveCurrentLocation() {
//API CALL
let latString = String(currentLat)
let longString = String(currentLong)
let apiString = NSString(format: "https://maps.googleapis.com/maps/api/place/search/json?location=%f,%f&radius=500&types=food&sensor=true&key=AIzaSyDH0jNx1WJw0pkCzbc0xaHumDoDAYYWvtk", latString, longString)
let url = NSURL(string: apiString as String)
let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithURL(url!) { (data, response, error) -> Void in
if let urlContent = data {
do {
let jsonDictionary = try NSJSONSerialization.JSONObjectWithData(urlContent, options: NSJSONReadingOptions.AllowFragments) as? [String:AnyObject]
print(jsonDictionary)
}
catch {
print("JSON error")
}
}
}
dataTask.resume()
}
Anyone able to help? Thanks!
This type of error usually comes when you not enable your Api on Google console. So please make your Api enable on Console.
Related
So my ultimate goal is to be able to just make test payments with Apple Pay on Stripe, whether that be with a token or something else.
**EDIT **I have this function I use to gather card info from the stored card in the Wallet:
func applePayContext(_ context: STPApplePayContext, didCreatePaymentMethod paymentMethod: STPPaymentMethod, paymentInformation: PKPayment, completion: #escaping STPIntentClientSecretCompletionBlock) {
guard let paymentIntentClientSecret = paymentIntentClientSecret else {
return;
}
let backendUrlForToken = "https://us-central1-xxxxxx-41f12.cloudfunctions.net/createStripeToken"
let url = URL(string: backendUrlForToken)
let pkToken = String(data: paymentInformation.token.paymentData, encoding: .utf8)
guard let name = paymentInformation.billingContact?.name else { return }
let nameFormatter = PersonNameComponentsFormatter()
nameFormatter.string(from: name)
let json: [String: Any] = [
"card": [
"address_city": paymentInformation.billingContact?.postalAddress?.city,
"address_country": paymentInformation.billingContact?.postalAddress?.country,
"address_line1": paymentInformation.billingContact?.postalAddress?.street,
"address_state": paymentInformation.billingContact?.postalAddress?.state,
"address_zip": paymentInformation.billingContact?.postalAddress?.postalCode,
"name": name
],
"muid": UIDevice.current.identifierForVendor?.uuidString,
"pk_token": pkToken,
"pk_token_instrument_name": paymentInformation.token.paymentMethod.displayName,
"pk_token_payment_network": paymentInformation.token.paymentMethod.network?.rawValue,
"pk_token_transaction_id": paymentInformation.token.transactionIdentifier
]
var request = URLRequest(url: url!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: json)
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let response = response as? HTTPURLResponse,
response.statusCode == 200,
let data = data,
let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
let token = json["id"] as? String else {
print("Error getting Stripe token")
return
}
print("\(token)")
self.stripeToken = token
}
task.resume()
let error = NSError()
completion(paymentIntentClientSecret, error)
}
I didn't have an endpoint for the API call so I created this request for a token. This is the function I have at my API endpoint:
exports.createStripeToken = functions.https.onRequest(async (req, res) => {
var cardAddressCity = req.body.card.address_city;
var cardAddressCountry = req.body.card.address_country;
var cardAddressLine = req.body.card.address_line1;
var cardAddressProvince = req.body.card.address_state;
var cardAddressPostalCode = req.body.card.address_zip;
var cardHolderName = req.body.card.name;
var muid = req.body.muid;
var pkToken = req.body.pk_token;
var pkTokenInstrument = req.body.pk_token_instrument_name;
var pkTokenNetwork = req.body.pk_token_payment_network;
var pkTokenTransactionID = req.body.pk_token_transaction_id;
const token = await stripe.tokens.create({
card: {
"address_city": cardAddressCity,
"address_country": cardAddressCountry,
"address_line1": cardAddressLine,
"address_state": cardAddressProvince,
"address_zip": cardAddressPostalCode,
"name": cardHolderName
},
"muid": muid,
"pk_token": pkToken,
"pk_token_instrument_name": pkTokenInstrument,
"pk_token_payment_network": pkTokenNetwork,
"pk_token_transaction_id": pkTokenTransactionID
});
res.send({
id: token.id,
});
});
I'm not sure if this is the correct way, I can't find much on the internet about this at all.
I figured this was the parameters I seen in my api logs so I used the same ones and I also seen a rare post on gist.github of a guy making an API call similar to this one, but for some reason it still doesn't work at all.
Your statements/logs aren't being hit because Token creation internally in STPApplePayContext is failing. For background, STPApplePayContext does:
Create a Token from the Apple Pay encrypted card details.
Using the Token, creates a PaymentMethod object.
Then triggers the didCreatePaymentMethod() delegate implementation.
And step 1 is failing.
Typically when I've seen a Token creation request 500, that typically means there might be a mismatch on the merchant ID used on XCode vs the certificate set up on Stripe account. Or it could be some combination of a PKPaymentNetwork not being supported on a Stripe account country.
I would re-do the steps of setting up the merchant ID and Apple Pay certificate, ideally on a fresh project to do away with any confusion or conflicts etc.
Since this was a 500, Stripe Support would be the right people to deal with that, as the error possibly lies on their end. I would provide them request IDs for your /v1/tokens creation request.
U P D A T E D... The function with what works!
I would like to incorporate the yelp api into an app but can't successfully pass my authorization token on the URL string. Do I need to do something to connect the URLRequest to the URLSessoin call and its not using the header? Maybe the key value pairs is wrong? The below function returns:
error = {
code = "TOKEN_MISSING";
description = "An access token must be supplied in order to use this endpoint.";
};
I was able to use postman to get the yelp API call working, but only by clicking the "Header" section on postman and putting in Bearer and then my yelp key. I googled around a bit and found some links that indicate that you can add a header to the URLSession that I assume would work the way postman does but I haven't been able to get it to work.
I know there are some githubs with yelp API repos but I am trying to not install a large set of code that I don't understand into my app, when all I want is the JSON that I can see is coming through on postman. Can anyone help me understand how I would edit code similar to the Here example below so that I can get the Authorization/Bearer that yelp requires?
func getYelp() {
let appSecret = "Bearer <YELP APIKEY>"
let link = "https://api.yelp.com/v3/businesses/search?latitude=37.786882&longitude=-122.399972"
if let url = URL(string: link) {
// Set headers
var request = URLRequest(url: url)
request.setValue("Accept-Language", forHTTPHeaderField: "en-us")
request.setValue(appSecret, forHTTPHeaderField: "Authorization")
print("Attempting to get places around location from Yelp")
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if error != nil {
print(error!)
} else {
if let urlContent = data {
do {
let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject // Added "as anyObject" to fix syntax error in Xcode 8 Beta 6
print("Printing all JSON/n/n//n--------------------------")
print(jsonResult)
print("Printing from results/n/n//n--------------------------")
if let description = ((jsonResult["search"] as? NSDictionary)?["context"] as? NSDictionary)?["href"] as? String {
} else {
print("JSON pull failed/n/n//n--------------------------")
}
} catch {
print("JSON Processing Failed/n/n//n--------------------------")
}
}
}
}
task.resume()
} else {
resultLabel.text = "Couldn't get results from Here"
}
}
You're mixing up between the headers and the url, you need to set your headers correctly
if let url = URL(string: "https://places.cit.api.here.com/places/v1/discover/around?at=37.776169%2C-122.421267&app_id=\(app_id)&app_code=\(app_code)") {
var request = URLRequest(url: url)
// Set headers
request.setValue("Accept-Language", forHTTPHeaderField: "en-us")
request.setValue("Authorization", forHTTPHeaderField: "Bearer " + token // Token here)
print("Attempting to get places around location")
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
// ...
Lets say you have an api with "https://google.com" (this is just an example with fake keys)
and an api key that is "ApiKey: 92927839238293d92d98d98d92".
You would then take this information and do this.
let uri = URL(string:"https://google.com")
if let unwrappedURL = uri {
var request = URLRequest(url: unwrappedURL)request.addValue("92927839238293d92d98d98d92", forHTTPHeaderField: "ApiKey")
let dataTask = URLSession.shared.dataTask(with: request) { (data, response, error) in
// you should put in error handling code, too
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
// HERE'S WHERE YOUR DATA IS
print(json)
} catch {
print(error.localizedDescription)
}
}
}
dataTask.resume()
}
Please remember that you would replace the google.com with your GET address and the APIKey header with your own api key values.
Also, this will print out all the JSON like in PostMan.
If this works for you, then I also have a link on accessing the JSON Objects.
At an earlier point today, I was able to use this API and get a response in my iPhone app. The fact that I have been trying to debug this for so long is making be believe that I'm crazy! Attached is a screenshot of my console...
Here is my code pertaining to my API call. Using Apple's URLSession and following many stack overflow questions / Tutorials I can not get this thing to work.
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print("request failed \(error)")
return
}
do {
if let json = try JSONSerialization.jsonObject(with: data) as? [String: String], let result = json["result"] {
// Parse JSON
}
} catch let parseError {
print("parsing error: \(parseError)")
let responseString = String(data: data, encoding: .utf8)
print("raw response: \(responseString)")
}
}
task.resume()
Every time I get this interesting [BoringSSL] Error and the searching I've done regarding that has not produced effective in fixing whatever bug I have.
Like I said, earlier today I had this app working using the same API. I have tried the key that the website gave me and the test key they use on their site. Now that I think of it, I am going to use the exact URL from my code and the screenshot and take a screenshot from the response I get in my browser. See below:
Received above response with the exact URL being used in my app.
tried your API in my project. It worked. You can check the difference below:
let urlTest = URL(string: "https://www.zipcodeapi.com/rest/wvyR5aWjHNUF80Z6kmr1bTuNojfzhmvtcmfBD8QNo9qbNAHy9FvBISINKF3W5i9J/multi-distance.json/99501/99501,%2085001,%2072201/km")
var request = URLRequest(url: urlTest!)
request.httpMethod = "GET"
let session = URLSession(configuration: .default)
let task : URLSessionDataTask = session.dataTask(with: request) { (data, response, error) in
let statusCode = (response as! HTTPURLResponse).statusCode
if statusCode == 200{
do {
let json = try JSON(data:data!)
}
catch {
print("Could not convert JSON data into a dictionary.")
}
}
}
task.resume()
Printing description of json:
▿ {
"distances" : {
"85001" : 4093.922,
"72201" : 4962.6189999999997
}
}
May be you have to turn off Transport Layer Security, because that worked for me.
Go to your info.plist file and add a property named App Transport Secrity Settings and set its Allow Arbitrary loads option to NO
Hope this helps.
I'm trying to integrate a login API in my iOS project. When i hit that API in browser it gives me correct JSON response. Whereas, when i call it in my app, i'm unable to read JSON. Code is as:
let url = NSURL(string: "myURL")
let request = NSURLRequest(URL: url!)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
if error != nil {
print (error)
}
do {
//jsonDict is always nil
if let jsonDict = try self.jsonFromData(data!) {
print (jsonDict)
}
}
catch {
print ("hi")
}
}
jsonFromData is as:
private func jsonFromData(jsonData: NSData) throws -> [NSDictionary]?
{
var jsonDict: [NSDictionary]? = nil
do
{
jsonDict = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.AllowFragments) as? [NSDictionary]
}
catch
{
throw(error)
}
return jsonDict
}
Response of API, when hit in browser is as:
Please help me, what i am doing wrong. Thanks.
UPDATE:
I just checked that if i convert data to String, it gives correct value. i.e.
let string = NSString(data: jsonData, encoding: NSASCIIStringEncoding)
print (string)
//OUTPUT: Optional({"Authenticated":true,"CustomerID":000,"CustomerName":"TEMP","Members":[{"MemberID":000,"MemberNumber":"000","MembershipID":00,"MembershipExpiration":"\/Date(1517464799000-0600)\/","ValidBuyerTypes":[0]}]})
Look at your code where you decode the JSON and the as? statement. You are trying to get an array of NSDictionary. Your JSON as printed contains a single dictionary, not an array.
This looks right to me. The only thing I can think is that (despite what the string output looks like) the top level container of your response is NOT an NSDictionary. In your jsonFromData function, instead of assuming the result of JSONObjecWithData will be an NSDictionary, I would say:
let iDunnoWhatThisIs = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.AllowFragments) // don't cast this to NSDictionary
and see what you get back. It should either be a dictionary or an array, however, since you have NSJSONReadingOptions.AllowFragments set for the options, it's possible that it could be something else entirely. Start with making SURE you're actually getting back what you're assuming you are and go from there.
Try using NSKeyedUnarchiver instead:
jsonDict = NSKeyedUnarchiver.unarchiveObjectWithData(jsonData)! as NSDictionary
First of all I created an account at https://www.fitbit.com
Then I careated an app at https://dev.fitbit.com
then installed OAuthSwift using cocoa pods and implemented this method in my AppDelegate
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
if (url.host == "oauth-callback") {
OAuthSwift.handleOpenURL(url)
}
return true
}
now i want to get the data (Name, Steps taken etc) of user account I created at https://www.fitbit.com
how can I do that ? I searched but was not able to find any tutorial on fitbit integration. And where to use this information in my code?
So please guide me about next step what should I do to get the data.
FitBit work with OAuth 2.0 API which require Client ID and Secret key. You need these client id and secret key to authenticate with OAuth 2.0 API.
There is a blog post related to FitBit integration in iOS with Swift.
Lets checkout and learn "How to implement fitbit in iOS"
https://appengineer.in/2016/04/30/fitbit-aouth-in-ios-app/
ex:
let oauthswift = OAuth2Swift(
consumerKey: fitbit_clientID,
consumerSecret: fitbit_consumer_secret,
authorizeUrl: "https://www.fitbit.com/oauth2/authorize",
accessTokenUrl: "https://api.fitbit.com/oauth2/token",
responseType: "token"
)
Any chance you could do it with basic auth as opposed to OAuth? I had a similar problem trying to POST to MailGun for some automated emails I was implementing in an app.
I was able to get this working properly with a large HTTP response. I put the full path into Keys.plist so that I can upload my code to github and broke out some of the arguments into variables so I can have them programmatically set later down the road.
// Email the FBO with desired information
// Parse our Keys.plist so we can use our path
var keys: NSDictionary?
if let path = NSBundle.mainBundle().pathForResource("Keys", ofType: "plist") {
keys = NSDictionary(contentsOfFile: path)
}
if let dict = keys {
// variablize our https path with API key, recipient and message text
let mailgunAPIPath = dict["mailgunAPIPath"] as? String
let emailRecipient = "bar#foo.com"
let emailMessage = "Testing%20email%20sender%20variables"
// Create a session and fill it with our request
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: NSURL(string: mailgunAPIPath! + "from=FBOGo%20Reservation%20%3Cscheduler#<my domain>.com%3E&to=reservations#<my domain>.com&to=\(emailRecipient)&subject=A%20New%20Reservation%21&text=\(emailMessage)")!)
// POST and report back with any errors and response codes
request.HTTPMethod = "POST"
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if let error = error {
print(error)
}
if let response = response {
print("url = \(response.URL!)")
print("response = \(response)")
let httpResponse = response as! NSHTTPURLResponse
print("response code = \(httpResponse.statusCode)")
}
})
task.resume()
}
The Mailgun Path is in Keys.plist as a string called mailgunAPIPath with the value:
https://API:key-<my key>#api.mailgun.net/v3/<my domain>.com/messages?
Hope this helps!