Swift geolocation latitude and longitude separation and making into a CLLocation2DMake - swift

func forwardGeocoding(address: String) {
CLGeocoder().geocodeAddressString(address, completionHandler: { (placemarks, error) in
if error != nil {
print(error)
return
}
if placemarks?.count > 0 {
let placemark = placemarks?[0]
let location = placemark?.location
let coordinate = location?.coordinate
print("\nlat: \(coordinate!.latitude), long: \(coordinate!.longitude)")
if placemark?.areasOfInterest?.count > 0 {
let areaOfInterest = placemark!.areasOfInterest![0]
print(areaOfInterest)
} else {
print("No area of interest found.")
}
}
})
var INITIAL_DESTINATION = forwardGeocoding(initialDestination)
var DESIRED_DESTINATION = forwardGeocoding(desiredDestination)
var location = CLLocationCoordinate2DMake(<#T##CLLocationDegrees#>, <#T##CLLocationDegrees#>)
Hello, I am trying to make a mapping app, and am having trouble with this part. What I want to do is be able to separate the INITIAL_DESTINATION latitude and longitudes. I have to do this to create a CLLocationCoordinate2DMake. What I have been trying to do is just use INITIAL_DESTINATION.latitude and INITIAL_DESTINATION.longitude, but I am continuingly facing the same error which is "Value of tuple type "()" has no member "latitude". This is also strange because it does not give that error for INITIAL_DESTINATION.longitude.
Any help or suggestions are greatly appreciated, and thank you for reading and taking the time to respond.

Your function returns nothing, and does nothing with the value returned in the asynchronous completion handler. You need to take the asynchronous result and use it in some fashion.
Try this: Put prints at the end of the function, and inside the completion handler, then run the code. What you'll see is that the function is done before the completion handler runs, because the code inside the block does not run until the remote web site returns an answer across the network. At that time Alamofire hands the result to your code in the completion block.
You'll also need to be aware that there are multiple queues in iOS, and UI changes can only be done on the main queue. The completion block does not run on the main queue, however, so likely to use the information returned from the network you'll need to use the dispatch_async function to call a function in your program and have it execute on the main queue.

Related

Wait for WKWebView evaluateJavaScript to finish

I have a problem that's been irritating me for a couple of days now. I'm trying to work with a WKWebView in my Swift project. Below is my code:
var items: [String] = []
for i in 0...8 {
web_view.evaluateJavaScript("document.getElementsByClassName('channels-content-item yt-shelf-grid-item')[\(i)].innerHTML") { (result, error) in
//print(result ?? "nil")
//print(error ?? "nil")
let string_result: String = String(describing: result!)
items.append(string_result)
num += 1
//print(string_result)
}
}
print(items)
My problem is the fact that the program won't wait for the evaluateJavaScript functions to finish before going to the print(items), even though the items array gets populated via these functions. Any way I can get this to work?
Any help would be greatly appreciated, thanks in advance
What is inside of your completion handler I think runs on a different thread, meaning it is running AFTER your print happens. Since injecting javascript takes longer, your print is most likely always going to happen first.

Swift canceling rest of function

Remember the good old days when End would stop everything and goto would take you somewhere without coming back? Well, "End" is essentially what I am trying to do, is cancel the rest of a function.
ie.
func function () {
x = 5
//code to cancel and stop function
x = 0
}
I want this to readout x = 5. The reason I want to do this is because I have numerous functions called from within functions. To keep it simple, is there anyway for this to happen?
From Apple (search for guard):
Early Exit
A guard statement, like an if statement, executes statements depending
on the Boolean value of an expression. You use a guard statement to
require that a condition must be true in order for the code after the
guard statement to be executed.
That would be:
func function() {
x = 5
guard <yourConditionToContinue> else {
return
}
// Code to be executed if <yourConditionToContinue> is met.
}

Unable to access variable outside of query function even though variable is declared after class

I have a few queries running to load variables with data from a Parse server into variables that are declared right below class. When I print the variable to the console within the query function, it prints correctly, but when I call it outside of the function or print it, it is empty. Any idea where I'm going wrong?
Variable declaration:
class AddTaskViewController: UIViewController, UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate {
var varCost = ""
Query loading variable:
let varCostQuery = PFQuery(className: "Class1")
varCostQuery.findObjectsInBackground(block: { (objects, error) in
if error != nil {
print(error!)
} else {
varCostQuery.whereKey("Header", equalTo: self.HeaderSelection.text)
varCostQuery.findObjectsInBackground(block: { (objects, error) in
for object in objects! {
self.varCost = object["pricePerUnit"] as! String
print(self.varCost) //Option1
}
})
}
})
print(varCost) //Option2
When I print Option1, I get the data exactly like I'm looking for, but when I print Option2 or try to do anything with the varCost variable at this level, I get "" like the variable has never been updated.
This occurs because the code being passed to the findObjectsInBackground method is code that is run only once all the objects have been found.
Because this code will only be called when the objects have been found, this may take a bit of time, so this code is send to a background queue to wait for the objects to be found.
We don't want the rest of our code to pause and wait for this though! That would slow our program down a lot. So the program continues past this block until it completes. That's why Option 2 is empty, because findObjectsInBackground hasn't had time to get the objects yet so the code has jumped straight to where Option 2 is.
When the objects have finally been found, the block of code is called and Option 1 is printed.
This means that you can only be sure self.varCost will have the right value from within this block (or closure, as it is called in Swift).

Using guard keyword

I have encountered numerous situations where a coder have used the guard keyword. And then later, in a seemingly almost identical situation the same coder in the same code does not use the guard keyword. I am aware that this may be a stupid question, so please don't bash it. When should I use the guard keyword and where shouldn't I?
Here is an example (there are many more). This is part of a script that is requesting data form an API.
//Here I am using guard
guard let json = json else {
//Now I am not using guard
if let error = error {
completion(.Failure(error))
} else {
//Error handling
}
return
}
Why not use the:
if let var1 = var1 {
//Keep on going
} else {
//Don't crash
}
syntax all the time instead of the guard syntax? At first glance it even seems to have more functionality, but I am certain that does not have to be the case.
One great benefit of the guard statement is that you know that if the condition is not satisfied then the execution flow gets stopped.
This is important for several reasons
Unwrapping
You can define unwrapped values which don't need a new scope { ... } to be available
func next(num:Int?) -> Int? {
guard let num = num else { return nil }
return num + 1
}
Readability
When you read the code you know that if the guard condition is not satisfied then the following lines won't be executed.
Semantics
You know a guard statement is there to check conditions required for the following block of code.
But I can replace every guard with an if
Sure. We could also replace every while and for with a goto in some languages. And we could always replace recursion with iteration (and viceversa).
But this doesn't necessarily means it is always a good idea.
Despite we can implement some behaviours with more then one programming "tool", we should still use the one that better fits that specific scenario.

How to make a serial queue with GCD

I tried to make a serial queue for network operations with GCD like this:
let mySerialQueue = dispatch_queue_create("com.myApp.mySerialQueue", dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INITIATED, 0))
func myFunc() {
dispatch_async(mySerialQueue) {
do {
// Get object from the database if it exists
let query = PFQuery(className: aClass)
query.whereKey(user, equalTo: currentUser)
let result = try? query.getFirstObject()
// Use existing object or create a new one
let object = result ?? PFObject(className: aClass)
object.setObject(currentUser, forKey: user)
try object.save()
} catch {
print(error)
}
}
}
The code first looks for an existing object in the database.
If it finds one, it updates it. If it doesn't find one, it creates a new one. This is using the Parse SDK and only synchronous network functions (.getFirstObject, .save).
For some reason it seems that this is not executed serially, because a new object is sometimes written into the database, although one existed already that should have been updated only.
Am I missing something about the GCD?
From the documentation on dispatch_queue_attr_make_with_qos_class:
relative_priority: A negative offset from the maximum supported scheduler priority for the given quality-of-service class. This value must be less than 0 and greater than MIN_QOS_CLASS_PRIORITY
Therefore you should be passing in a value less than 0 for this.
However, if you have no need for a priority, you can simply pass DISPATCH_QUEUE_SERIAL into the attr argument when you create your queue. For example:
let mySerialQueue = dispatch_queue_create("com.myApp.mySerialQueue", DISPATCH_QUEUE_SERIAL)