Human Face Recognition Variable (google-cloud-vision) - google-cloud-vision

I am working on implementing human face recognition into an iOS application. I receive back many tags like 'glasses' or 'smiling' but don't see an actual variable that tells me it is a human face (and with what degree of confidence).
What variable am I missing and how can we use that functionality?

I think that you may not using the correct feature type as it is seems that you are getting labels instead of facial attributes.
I recommend you to check the Detecting Faces and Face Detection Tutorial documentation where you can find detailed information and some useful examples that you can use as a reference to know more about the process of detecting faces with Vision API.

You can follow few steps to detect faces from an image.
Create your URLRequest
func createRequest() -> URLRequest? {
// Create your request URL
if let url = URL(string: "YOUR_API_KEY") {
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue(Bundle.main.bundleIdentifier ?? "", forHTTPHeaderField: "X- Ios-Bundle-Identifier")
let jsonRequest = [
"requests": [
"features": [
[
"type": "FACE_DETECTION",
"maxResults": 10 //change as per your requirement
]
]
]
]
let jsonData = try? JSONSerialization.data(withJSONObject: jsonRequest)
request.httpBody = jsonData
return request
}
return nil
}
Run the request in background thread
let task: URLSessionDataTask = URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "")
return
}
print(data)// Analyze with this data
}
task.resume()
Analyze data (on main thread if you want to update any UI component)
DispatchQueue.main.async(execute: {
do {
guard let json =
try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else { return }
guard let responses = json["responses"] as? NSArray else { return }
if responses.count > 0 {
guard let response = responses.firstObject as? [String: Any] else { return }
guard let faceAnnotations = response["faceAnnotations"] as? NSArray else {
print(false, "No face detected, please try another photo.")
return
}
if faceAnnotations.count > 0 {
print("Face successfully detected: \(faceAnnotations.count)")
} else {
print("No face detected, please try another photo.")
}
} else {
print("Error while face detection process, please try again.")
}
} catch {
print("Error while face detection process, please try again.")
}
})

Related

Error: GeoPoint long and lat is nil not allowing me to send coordinates due to Unwrapping Optional Value

Hello I am stuck and have tried to google and research but am not having any luck. The user location is saying its nil. I am trying to send it to Firebase database to show the users location. When I print out the userLocation.coordinate.latitude manually it shows me the correct coordinates in the console. I have tried to put:
"location": GeoPoint(latitude: userLocation!.coordinate.latitude, longitude: userLocation!.coordinate.longitude)
To possibly unwrap the userlocation but no luck.
I am getting an ERROR:
Fatal error: Unexpectedly found nil while implicitly unwrapping an
Optional value
Current CODE:
// Sending to firebase database the order but location: is giving the optional value fatal error, while everything else is sending correctly
db.collection("Users").document(Auth.auth().currentUser!.uid).setData([
"ordered_weed": details,
"total_cost": calculateTotalPrice(),
"location": GeoPoint(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
]) { (err) in
if err != nil {
self.ordered = false
return
}
print("Success Order")
}
EDIT:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// reading user location and extracting details...
self.userLocation = locations.last!
self.extractLocation()
// after extracting location logging in...
self.login()
}
try something like this:
if let lat = userLocation.coordinate.latitude, let lon = userLocation.coordinate.longitude {
db.collection("Users").document(Auth.auth().currentUser!.uid).setData([
"ordered_weed": details,
"total_cost": calculateTotalPrice(),
"location": {"latitude": lat, "longitude": lon}
]) { (err) in
if err != nil {
self.ordered = false
return
}
print("Success Order")
}
}
Don't put the if let lat = .... inside the json object.
So I figured it out with the help of you #workingdog . The if let gave me the error: Initializer for conditional binding must have Optional type, not 'CLLocationDegrees' (aka 'Double')
So I did some digging on swiftui forums and found this solution for forcing an unwrap. https://forums.swift.org/t/forced-unwrapping/38829/4
db.collection("Users").document(Auth.auth().currentUser!.uid).setData([
"ordered_weed": details,
"total_cost": calculateTotalPrice(),
"location": GeoPoint(latitude: (self.locationManager.location?.coordinate.latitude)!, longitude: (self.locationManager.location?.coordinate.longitude)!)
]) { (err) in
if err != nil {
self.ordered = false
return
}
print("Success Order")
}

Firebase SwiftUI and Firebase Auth - not reading user ID?

Below is the code for my signup page. I want to make it so that when someone creates an account on the sign up page, I create a document in the users collection and include uuid in the document. However, session.session?.uid ends up being nil. Does anyone know why this is?
struct SignUpView: View {
#State var email = ""
#State var password = ""
#State var name = ""
#State var error = ""
#EnvironmentObject var session: SessionStore
func signUp() {
let db = Firestore.firestore()
let user = db.collection("users").document()
let test = db.collection("users").document(user.documentID).collection("routines").document()
session.signUp(email: email, password: password) { (result, error) in
if let error = error {
self.error = error.localizedDescription
print("This is the error \(error)")
return
} else {
self.email = ""
self.password = ""
}
}
user.setData(["id": user.documentID, "email": email]) { (err) in
if err != nil {
print((err?.localizedDescription)!)
return
}
}
print(session.session?.uid)
test.setData(["id:": test.documentID, "msg": "samwell Tarly", "uuid": session.session?.uid]) { (err) in
print("ummmmm test data?")
if err != nil {
print((err?.localizedDescription)!)
return
}
}
}
The Firebase APIs are asynchronous, simply because they access a remote system, across the internet, which takes a little time. The same applies for accessing the local disk, by the way. This blog post explains this in more detail.
Consequently, session.signUp is an asynchronous process. I.e. the call to print(session.session?.uid) is executed before session.signUp returns. Thus, session.session?.uid is still nil.
To work around this, you can nest your calls like this:
session.signUp(email: email, password: password) { (result, error) in
if let error = error {
self.error = error.localizedDescription
print("This is the error \(error)")
return
}
else {
self.email = ""
self.password = ""
user.setData(["id": user.documentID, "email": email]) { (err) in
if err != nil {
print((err?.localizedDescription)!)
return
}
}
}
}
Generally speaking, I would strongly recommend to not perform so much logic in your views, but instead keep your views as anaemic as possible - meaning: put all your logic into view models, and bind the view to the view models by using Combine. This will make your code much cleaner, easier to test, and maintainable.
See https://peterfriese.dev/replicating-reminder-swiftui-firebase-part2/ for how to do this.

Cannot determine type of json object returned from web service

I have an old type of web service built on ASP.Net. With the following function, I was able to fetch some type of data from the asmx web service:
func getJsonData(sql: String, spparamnames: String, spParamValues: String, completeonClosure: #escaping (AnyObject?) -> ()) {
let url = URL(string:"http://www.example.com/MyWebService.asmx/GetDataTableAsJson")
var request = URLRequest(url: url!)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type") // the request is JSON
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept") // the expected response is also JSON
request.httpMethod = "POST"
let dictionary = ["sql" : sql, "spparamnames" : spparamnames, "spparamvalues" : spParamValues] //Parameters are here seperated with comma
request.httpBody = try! JSONSerialization.data(withJSONObject: dictionary)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error.debugDescription) // some fundamental network error
return
}
do {
if response != nil {
let myJson = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:AnyObject]
let isCorectJson = JSONSerialization.isValidJSONObject(myJson)
let charcount = (myJson["d"] as? String)?.characters.count
let cc = charcount ?? 0
if isCorectJson == true && cc > 0 {
completeonClosure(myJson as AnyObject?)
)
} else {
let str2 = "Connection Error"
completeonClosure(str2 as AnyObject?)
}
}
} catch let JsonError {
print(JsonError)
}
}
task.resume()
}
When I run a query with Swift, and cast the object type as NSDictionary, my output result is the following:
getJsonData(sql: "SELECT TOP 3 User_id, LoweredUserName FROM Users", spparamnames: "", spParamValues: "") {
returnJSON in
OperationQueue.main.addOperation {
let mystr = returnJSON as? NSDictionary
print(mystr!)
}
}
Result:
{
d = "[{\"User_id\":102,\"LoweredUserName\":\"abu alay\"},{\"User_id\":90,\"LoweredUserName\":\"ali es\"},{\"User_id\":95,\"LoweredUserName\":\"alper ay\"}]";
}
I think that the result is some kind of dictionary, I was not able to convert the result to an array, therefore I cannot iterate between the rows and use the result efficiently. What should I do in order to read the result like: print(returnJSON[0]["LoweredUserName"]) ? What is the meaning of the letter "d" at the beginning of the result? Many thanks in advance.
It looks like your response is an Array, try to cast to an array of dictionary objects.
if let myJson = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? [[String:AnyObject]] {
// parse each object here
}
This example code I ran in a playground seems to work fine:
let jsonString = "[{\"User_id\":102,\"LoweredUserName\":\"abu alay\"},{\"User_id\":90,\"LoweredUserName\":\"ali es\"},{\"User_id\":95,\"LoweredUserName\":\"alper ay\"}]"
let jsonData = jsonString.data(using: String.Encoding.utf8)
if let json = try? JSONSerialization.jsonObject(with: jsonData!, options: .mutableContainers) as? [[String:AnyObject]] {
print(json)
}
Output:
Optional([["User_id": 102, "LoweredUserName": abu alay], ["User_id": 90, "LoweredUserName": ali es], ["User_id": 95, "LoweredUserName": alper ay]])
If the text you have shown is the entire body of the result you got:
{
d = "[{\"User_id\":102,\"LoweredUserName\":\"abu alay\"},{\"User_id\":90,\"LoweredUserName\":\"ali es\"},{\"User_id\":95,\"LoweredUserName\":\"alper ay\"}]";
}
Then this is not properly formatted JSON. For it to be formatted properly the "d" would have to be shown in double quotes.
It looks like you may need to do some custom parsing on the result to get at the JSON contained in the "d" area.

Trouble uploading videos from iOS using WordPress REST api

I am very new at this, so sorry if I have missed something.
I am trying to upload a video from iOS to WordPress using the WP REST API and Alamofire.
Some videos will upload just fine while other videos get a rest_upload_no_content_disposition status = 400 error.
Here is my code to uploading a video
class func pageVideo(accessToken:String, filePath:NSURL, completion: AnyObject? -> Void) {
let endpoint = "http://XXXXXXXXX.com/wp-json/wp/v2/media/?access_token=\(accessToken)"
let parameters = [
"Content-Type": "multipart/form-data",
"Content-Disposition": "attachment; filename=appVideo.mov",
"media_type": "file"
]
var fileData : NSData?
if let fileContents = NSFileManager.defaultManager().contentsAtPath(filePath.path!) {
fileData = fileContents
}
let mgr = Alamofire.Manager.sharedInstance
mgr.upload(.POST, endpoint, multipartFormData: { multipartFormData in
if let _fileData = fileData {
multipartFormData.appendBodyPart(data: _fileData, name: "file", fileName: "file.mov", mimeType: "file/mov")
}
for (key, value) in parameters {
multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
}
}, encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.response {(request, response, data, error ) in
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments)
if let dict = json as? NSDictionary{
if let url = dict.valueForKeyPath("source_url") as? String{
completion(url)
}
}
} catch let error as NSError{
// completion(error.localizedDescription)
print(error.localizedDescription)
}
}
case .Failure(let encodingError):
print(encodingError)
}
})
}
}
It seems like shorter videos work while anything over 30 seconds fails.
Even shorter videos that do upload take a very long time.
Any help would be greatly appreciated.
Nothing was wrong with my code I just needed to compress the videos. the longer videos were hitting the WordPress upload limit. Also it's always a good idea to compress videos or images that your uploading somewhere.

HTTP POST error Handling in Swift 2

I'm new here, and this is my first question...
I try to write an App in Swift 2 that makes an HTTP POST request but I can't figure out how to use the new error handling of Swift 2. Can anyone tell me please how to implement the "do-try-catch" error handling of Swift 2 to the code snippet below?
(This code snippet uses the old error handling of swift 1.2)
func post(params : Dictionary<String, String>, url : String) {
var request = NSMutableURLRequest(URL: NSURL(string: url)!)
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
var err: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil/*, error: &err*/)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
print("Response: \(response)")
var strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Body: \(strData)")
var err: NSError?
var json = NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves/*, error: &err*/) as? NSDictionary
// Did the JSONObjectWithData constructor return an error? If so, log the error to the console
if(err != nil) {
print(err!.localizedDescription)
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Error could not parse JSON: '\(jsonStr)'")
}
else {
// The JSONObjectWithData constructor didn't return an error. But, we should still
// check and make sure that json has a value using optional binding.
if let parseJSON = json {
// Okay, the parsedJSON is here, let's get the value for 'success' out of it
var success = parseJSON["success"] as? Int
print("Succes: \(success)")
}
else {
// Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Error could not parse JSON: \(jsonStr)")
}
}
})
task!.resume()
}
You presumably want to wrap your NSJSONSerialization calls in do/try/catch logic as shown below.
In Swift 3:
var request = URLRequest(url: URL(string: urlString)!)
let session = URLSession.shared
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.httpBody = try! JSONSerialization.data(withJSONObject: parameters)
// or if you think the conversion might actually fail (which is unlikely if you built `parameters` yourself)
//
// do {
// request.httpBody = try JSONSerialization.data(withJSONObject: parameters)
// } catch {
// print(error)
// }
let task = session.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print("error: \(error)")
return
}
// this, on the other hand, can quite easily fail if there's a server error, so you definitely
// want to wrap this in `do`-`try`-`catch`:
do {
if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
let success = json["success"] as? Int // Okay, the `json` is here, let's get the value for 'success' out of it
print("Success: \(success)")
} else {
let jsonStr = String(data: data, encoding: .utf8) // No error thrown, but not dictionary
print("Error could not parse JSON: \(jsonStr)")
}
} catch let parseError {
print(parseError) // Log the error thrown by `JSONObjectWithData`
let jsonStr = String(data: data, encoding: .utf8)
print("Error could not parse JSON: '\(jsonStr)'")
}
}
task.resume()
Or, in Swift 2
let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(parameters, options: [])
// or if you think the conversion might actually fail (which is unlikely if you built `parameters` yourself)
//
// do {
// request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: [])
// } catch {
// print(error)
// }
let task = session.dataTaskWithRequest(request) { data, response, error in
guard let data = data where error == nil else {
print("error: \(error)")
return
}
// this, on the other hand, can quite easily fail if there's a server error, so you definitely
// want to wrap this in `do`-`try`-`catch`:
do {
if let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? NSDictionary {
let success = json["success"] as? Int // Okay, the `json` is here, let's get the value for 'success' out of it
print("Success: \(success)")
} else {
let jsonStr = String(data: data, encoding: NSUTF8StringEncoding) // No error thrown, but not NSDictionary
print("Error could not parse JSON: \(jsonStr)")
}
} catch let parseError {
print(parseError) // Log the error thrown by `JSONObjectWithData`
let jsonStr = String(data: data, encoding: NSUTF8StringEncoding)
print("Error could not parse JSON: '\(jsonStr)'")
}
}
task.resume()
I'd also suggest being a little more careful about forced unwrapping of data, because you want to detect/handle the errors, not crash. For example, above I use a guard statement to unwrap it.
In general if a function throws you have to write it inside a do catch block or just mark the outer scope function (in this case post) as throws:
func post(params : Dictionary<String, String>, url : String) {
let request = NSMutableURLRequest(URL: NSURL(string: url)!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
do {
request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: .PrettyPrinted)
} catch {
//handle error. Probably return or mark function as throws
print(error)
return
}
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
// handle error
guard error == nil else { return }
print("Response: \(response)")
let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Body: \(strData)")
let json: NSDictionary?
do {
json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves) as? NSDictionary
} catch let dataError {
// Did the JSONObjectWithData constructor return an error? If so, log the error to the console
print(dataError)
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Error could not parse JSON: '\(jsonStr)'")
// return or throw?
return
}
// The JSONObjectWithData constructor didn't return an error. But, we should still
// check and make sure that json has a value using optional binding.
if let parseJSON = json {
// Okay, the parsedJSON is here, let's get the value for 'success' out of it
let success = parseJSON["success"] as? Int
print("Succes: \(success)")
}
else {
// Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Error could not parse JSON: \(jsonStr)")
}
})
task!.resume()
}
If you don't want to handle these errors right in your post function you can just declare it as throws than you don't have to use do catch at all

Resources