Google Vision - OCR - Request must specify image and features - ios

I am trying to Implement Google Vision OCR Request. Here is My Code,
func performImageRecognition(image: UIImage){
//1. Convert Image into base64 encoding
let imageData: Data = UIImageJPEGRepresentation(image, 1.0)!
let encodedString: String = imageData.base64EncodedString()
//2. Request Body for Vision OCR
let postBody: [String: Any] = getPOSTBody(base64: encodedString)
//3. API Call
AppDelegate.makeRequest(url: Request.url, requestBody: postBody, completionHandler: {
data, response, error in
print(error!)
do{
let dictionary = try JSONSerialization.jsonObject(with: data!, options: [])
print(dictionary)
self.activityindicator.stopAnimating()
}catch{
print("Error Parsing Data: \(error)" )
}
})
}
/*
* Request Body
*/
func getPOSTBody(base64: String) -> [String: Any]{
let json: [String: Any] = [
"requests": [["image": ["content": base64]],
["features": [["type": "TEXT_DETECTION"]]]
]
]
return json
}
Request Handler
class func makeRequest(url: URL, requestBody: [String: Any],completionHandler: #escaping (Data?, Int?, String?) -> Void){
var requestData: Data!
var urlRequest = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 60)
// 1. Serialize the request body to Data
do{
requestData = try JSONSerialization.data(withJSONObject: requestBody, options: [])
}catch{
print("ERROR:: Generating data from JSON Body : \(error) ")
}
// 2. Setting up the required Header Fields
urlRequest.httpBody = requestData
urlRequest.addValue("\(requestData.count)", forHTTPHeaderField: "Content-Length")
urlRequest.addValue("application/json; charset=UTF-8", forHTTPHeaderField: "Content-Type")
urlRequest.httpMethod = "POST"
// 3. Creating the Session
let session = URLSession(configuration: .default)
let dataTask: URLSessionDataTask = session.dataTask(with: urlRequest, completionHandler: {
data, response, error in
if (error != nil){
print("Error is: \(error?.localizedDescription ?? "None")")
return
}
let resp = response as? HTTPURLResponse
DispatchQueue.main.async {
completionHandler(data, resp?.statusCode ?? 0, error?.localizedDescription ?? "None")
}
})
dataTask.resume()
}
Problem is getting "Bad Request, 400 Status, Request must specify image and features.".
I've Checked the Request body for isValidJSONObject, getting true. API is working fine on Postman.
Please let me know if i am missing something, Any Help will be appreciated.
Thank You

You'r sending different array for "image" and "features".
As per the Documentation request body should be as follow,
func getPOSTBody(base64: String) -> [String: Any]{
let json: [String: Any] = [
"requests": ["image": ["content": base64],
"features": [["type": "TEXT_DETECTION"]]
]
]
return json
}

Related

How to Pass Key Value Parameter in JSON POST method in Swift?

This is API http://itaag-env-1.ap-south-1.elasticbeanstalk.com/filter/taggedusers/
its parameter: "contactsList" : ["5987606147", "6179987671", "5082508888"]
its header: ["deviceid": "584D97F-761A-4C24-8C4B-C145A8B8BD75", "userType": "personal", "key": "9609cc826b0d472faf9967370c095c21"]
In my code if i put breakpoint then filtertaggedUser() is calling but i am unable to go inside completionHandler the access is not going inside dataTask
Access going to else part why? the api is working.
i am trying to pass parameter key value in URL string like below
let urlStr = "http://itaag-env-1.ap-south-1.elasticbeanstalk.com/filter/taggedusers/?contactsList=" + "8908908900"
is this correct approch?
code for above API:
func filtertaggedUser() {
print("inside filter taggedusers")
let headers = ["deviceid": "584D97F-761A-4C24-8C4B-C145A8B8BD75", "userType": "personal", "key": "9609cc826b0d472faf9967370c095c21"]
let urlStr = "http://itaag-env-1.ap-south-1.elasticbeanstalk.com/filter/taggedusers/?contactsList=" + "8908908900"
let request = NSMutableURLRequest(url: NSURL(string:urlStr)! as URL,cachePolicy: .useProtocolCachePolicy,timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
// access not coming here
let httpResponse = response as? HTTPURLResponse
if httpResponse!.statusCode == 200 {
print("filter taggedusers inside")
do {
print("filter taggedusers inside do")
let jsonObject = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as! [String :AnyObject]
print("filter taggedusers \(jsonObject)")
} catch { print(error.localizedDescription) }
} else { Constants.showAlertView(alertViewTitle: "", Message: "Something went wrong, Please try again", on: self) }
})
dataTask.resume()
}
OUTPUT:
POSTMAN OUTPUT
POSTMAN Body
why response is not coming, where i did mistake, please help me with the code.
We can call the Post request API like below,
func getPostString(params:[String:Any]) -> String
{
var data = [String]()
for(key, value) in params
{
data.append(key + "=\(value)")
}
print(data.map { String($0) }.joined(separator: "&"))
return data.map { String($0) }.joined(separator: "&")
}
func callPostApi(){
let url = URL(string: "http://itaag-env-1.ap-south-1.elasticbeanstalk.com/filter/taggedusers/")
guard let requestUrl = url else { fatalError() }
var request = URLRequest(url: requestUrl)
request.httpMethod = "POST"
request.setValue("584D97F-761A-4C24-8C4B-C145A8B8BD75", forHTTPHeaderField: "deviceid")
request.setValue("9609cc826b0d472faf9967370c095c21", forHTTPHeaderField: "key")
request.setValue("personal", forHTTPHeaderField: "userType")
let parameters = getPostString(params: ["contactsList":["8908908900"]])
request.httpBody = parameters.data(using: .utf8)
// Perform HTTP Request
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
let httpResponse = response as? HTTPURLResponse
print(httpResponse!.statusCode)
// Check for Error
if let error = error {
print("Error took place \(error)")
return
}
// Convert HTTP Response Data to a String
if let data = data, let dataString = String(data: data, encoding: .utf8) {
print("Response data string:\n \(dataString)")
}
}
task.resume()
}
Output :
{"8908908900":{"userId":"9609cc826b0d472faf9967370c095c21","userName":"Satish Madhavarapu","profilePic":null,"oniTaag":true,"tagged":false,"userType":"personal"}}

How to add post api request in parameters while parsing in swift

This is my api request:
{
"billDetails": {
"billerId":"EPDCLOB00AN232",
"customerParams":[{"name":"Service Number","value":"116515M025033"}]
}
}
here is code:
func billerFetchService(){
let parameters = ["billDetails": {
"billerId" : "EPDCLOB00ANP01",
"customerParams" : [{"name":"Service Number","value":"116515M025007621"}]
}
] as [String : Any]
let url = URL(string: "https://app.com/Fetch/fetch")
var req = URLRequest(url: url!)
req.httpMethod = "POST"
req.addValue("application/json", forHTTPHeaderField: "Contet-Type")
req.addValue("application/json", forHTTPHeaderField: "Accept")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) else {return}
req.httpBody = httpBody
let session = URLSession.shared
session.dataTask(with: req, completionHandler: {(data, response, error) in
if response != nil {
// print(response)
}
if let data = data {
do{
var json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! [String: Any]
print("fetching json \(json)")
}catch{
print("error")
}
}
}).resume()
}
if i add like this in parameters error
Consecutive statements on a line must be separated by ';'
Insert ';'
Expected expression
Where i did mistake, please help me in code
You need
let parameters = ["billDetails": [
"billerId" : "EPDCLOB00ANP01",
"customerParams" : [["name":"Service Number","value":"116515M025007621"]]]]
Please make your parameter as this
let parameters = ["billDetails":
[
"billerId": "EPDCLOB00ANP01",
"customerParams" : ["name":"Service Number","value":"116515M025007621"]
]
] as [String : Any]

Access Magento Rest API in iOS - swift 3.0

I want to access the magenta REST API in my iOS application.
Following is my code to access the API:
func getCustomerTokenusingURLSEssion(){
let url = URL(string: "HTTPURL")!
var urlRequest = URLRequest(
url: url,
cachePolicy: .reloadIgnoringLocalAndRemoteCacheData,
timeoutInterval: 10.0 * 1000)
urlRequest.httpMethod = "POST"
urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")
let json1: [String: Any] = [
"username": "xyz#gmail.com",
"password":"xyz12345"]
let jsonData = try? JSONSerialization.data(withJSONObject: json1, options: .prettyPrinted)
urlRequest.httpBody = jsonData
let config = URLSessionConfiguration.default
let urlsession = URLSession(configuration: config)
let task = urlsession.dataTask(with: urlRequest){ (data, response, error) -> Void in
print("response from server: \(response)")
guard error == nil else {
print("Error while fetching remote rooms: \(error)")
return
}
guard let data = data,
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else {
print("Nil data received from fetchAllRooms service ")
return
}
print("JSON \(json)")
}
task.resume()
}
But I'm getting error message form the server as follow:
["message": Server cannot understand Content-Type HTTP header media type application/x-www-form-urlencoded]
Please help!
Thanks!
Here's working example of token-based authentication from iOS to magento2 using swift:
func restApiAuthorize(completionBlock: #escaping (String) -> Void) {
// Prepare json data
let json: [String: Any] = ["username": “yourusername”,
"password": “yourpassowrd”]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
// Create post request
let url = URL(string: "http://yourmagentodomain.com/index.php/rest/V1/integration/customer/token")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("\(jsonData!.count)", forHTTPHeaderField: "Content-Length")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
// Insert json data to the request
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
return
}
// 1: Check HTTP Response for successful GET request
guard let httpResponse = response as? HTTPURLResponse
else {
print("error: not a valid http response")
return
}
print(httpResponse.statusCode)
switch (httpResponse.statusCode)
{
case 200:
let responseData = String(data: data, encoding: String.Encoding.utf8)!
print ("responseData: \(responseData)")
completionBlock(responseData)
default:
print("POST request got response \(httpResponse.statusCode)")
}
}
task.resume()
}
And usage is like that:
restApiAuthorize() { (output) in
// token data, I found it important to remove quotes otherwise token contains extra quotes in the end and beginning of string
let userToken = output.replacingOccurrences(of: "\"", with: "")
print ("userToken \(userToken)")
}
you can then write your userToken to userDefaults and make feature api calls.
Best Guest you forgot to set your Content-Type, so add this:
urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")

The data couldn’t be read because it isn’t in the correct format - HTTP network

code
let session = URLSession.shared
// prepare json data
let json: [String: Any] = ["email": "test_mobile#mysite.com"]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
let proceedURL = NSURL(string:"https://mysitename.herokuapp.com/api/users/isUser")
//let proceedURL = NSURL(string:"https://google.com")
let request = NSMutableURLRequest(url: proceedURL! as URL)
//HTTP Headers
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/www.inception.v1", forHTTPHeaderField: "Accept")
request.addValue("Authorization", forHTTPHeaderField: "Basic aW5jZXB0aW9uQGZ1cmRvOmljM=")
request.httpMethod = "POST"
//request.httpBody = jsonData
// insert json data to the request
request.httpBody = jsonData
//create dataTask using the session object to send data to the server
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
guard error == nil else {
return
}
guard let data = data else {
return
}
// Print out response string
let responseString = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
print("responseString = \(responseString!)")
do {
//create json object from data
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: AnyObject] {
print(json)
// handle json...
}
} catch let error {
print("error : " + error.localizedDescription)
}
})
task.resume()
error :
The data couldn’t be read because it isn’t in the correct format.
I am beginner in iphone app development, help me on it and give better suggestion for make network connection (like in android i am using Volley library )
Actual Response is :
{
"status": 1,
"http_status_code": 200,
"data": {
"email": "test_mobile#mysite.com",
"phone": "8090909000"
}
}
i am using same on Android and test in postmen.
// Print out response string
let responseString = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
for upper code response is nothing
Using Alamofire.
let json: [String: Any] = ["email": "test_mobile#mysite.com"]
Alamofire.request(.POST, "https://mysitename.herokuapp.com/api/users/isUser" , parameters: json, encoding: .JSON).responseJSON {
Response in
switch Response.result {
case .Success(let _data):
let JsonData = JSON(_data)
print("JsonData : \(JsonData)")
//handle json
case .Failure(let _error):
print(_error)
let AlertBox = UIAlertController(title: "Connection Failed", message: "No Connection", preferredStyle: .Alert)
let ActionBox = UIAlertAction(title: "Ok" , style: .Default, handler: { _ in})
AlertBox.addAction(ActionBox)
self.presentViewController(AlertBox, animated: true, completion: nil)
}
let json: [String: Any] = ["email": "test_mobile#mysite.com"]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
// create post request
let url = URL(string: "http://httpbin.org/post")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
// insert json data to the request
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
return
}
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
print(responseJSON)
}
}
task.resume()

POST w/ JSON Body - Swift3 - fragments?

I'm simply trying to send a JSON string via a Swift3 httprequest.
Tried using a Dictionary, and an escaped string ...
func getToken(successHandler: #escaping (Any) -> Void, errorHandler: #escaping (Any) -> Void) {
var request = URLRequest(url: URL(string: "http://my-api.domain.com/getToken")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
do
{
// try with Dictionary
let bodyJson: [String: String] = [
"username": "theusername"
]
let bodyJsonData = try JSONSerialization.data(withJSONObject: bodyJson, options: [])
// try with escaped String
let jsonString = "{" +
"\"username\": \"theusername\"," +
"}"
let jsonStringData = jsonString.data(using: String.Encoding.utf8)
//request.httpBody = bodyJsonData
request.httpBody = jsonStringData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard error == nil else {
print(error)
errorHandler(error)
return
}
guard let data = data else {
print("Data is empty")
errorHandler("Data is empty")
return
}
var json: Any? = nil
do
{
json = try JSONSerialization.jsonObject(with: data, options: [])
DispatchQueue.main.asyncAfter(deadline: .now()) {
successHandler(json)
}
}
catch let error as NSError {
errorHandler(error)
}
}
task.resume()
}
catch
{
errorHandler(error)
}
}
I keep getting:
Handle Error: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did
not start with array or object and option to allow fragments not set."
UserInfo={NSDebugDescription=JSON text did not start with array or
object and option to allow fragments not set.}
I can't find how to try allowing fragments, all of the examples/tutorials are for Swift2.x :/
Unsure what to do!
// prepare json data
let mapDict = [ "1":"First", "2":"Second"]
let json = [ "title":"ABC" , "dict": mapDict ] as [String : Any]
do {
let jsonData = try JSONSerialization.data(withJSONObject: json, options: .prettyPrinted)
// create post request
let endpoint: String = "https://yourAPI"
let session = URLSession.shared
let url = NSURL(string: endpoint)!
let request = NSMutableURLRequest(url: url as URL)
request.httpMethod = "POST"
// insert json data to the request
request.httpBody = jsonData
let task = session.dataTask(with: request as URLRequest){ data,response,error in
if error != nil{
print(error?.localizedDescription)
return
}
}
task.resume()
} catch {
print("bad things happened")
}

Resources