Google Maps API Directions in Swift 3 - ios

As I start to use Swift 3, I've got a problem with building a route with Google Maps API directions.
My route has several waypoints and in Swift 3 the URL:
https://maps.googleapis.com/maps/api/directions/json?origin=48.4843822562792,35.0635632500052&destination=48.4893899423081,35.0640017911792&waypoints=48.4833428800255,35.0710221379995|48.4887622031403,35.0573639944196&key=AIzaSyAWpBT3uxovKLqdWIiwa29a4AcgtspAA1k
Doesn't work because of "|". Any suggestions?

For those who wants to use directions googlemaps api, you have to send your waypoints in a parameters array. So the pipe doesn't cause problem anymore.
var wayPointsString = "optimize:true"
if waypointsForRequest.count > 0 {
for location in waypointsForRequest {
wayPointsString = "\(wayPointsString)|\(location.coordinate.latitude),\(location.coordinate.longitude)"
}
}
let parameters : [String : String] = ["key" : self.directionsApikey, "sensor" : "false", "mode" : "driving", "alternatives" : "true", "origin" : "\(origin.coordinate.latitude),\(origin.coordinate.longitude)", "destination" : "\(destination.coordinate.latitude),\(destination.coordinate.longitude)", "waypoints" : wayPointsString]
let url = URL(string: "https://maps.googleapis.com/maps/api/directions/json?")
Alamofire.request(url!, method:.get, parameters: parameters)
.validate(contentType: ["application/json"])
.responseJSON { response in
if response.value != nil {
let json = JSON(response.value!)
}
}
Interesting answer here : https://stackoverflow.com/a/40126476/3173405

Hi i didn't know much about swift., but i had the same problem in objective C and I did something below and worked for me,
NSMutableCharacterSet *alphaNumSymbols = [NSMutableCharacterSet characterSetWithCharactersInString:#"~!##$&*()-_+=[]:;',/?."];
[alphaNumSymbols formUnionWithCharacterSet:[NSCharacterSet alphanumericCharacterSet]];
urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:alphaNumSymbols];
NSURL *directionsURL = [NSURL URLWithString:urlString];
Hope this will help
in Swift,
var alphaNumSymbols = CharacterSet(charactersInString: "~!##$&*()-_+=[]:;',/?.")
alphaNumSymbols!.formUnion(CharacterSet.alphanumerics)
urlString = urlString.addingPercentEncoding(withAllowedCharacters: alphaNumSymbols)!
var directionsURL = NSURL(string: urlString)!

In Swift 3, the following helped
let url_string = "URL STRING"
let url = URL(string:url_string.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed))

Related

How to make a route in google map with url and parameters between origin and destination?

I want to open a url in web and automatically make a route between two points. I can't find correct url and params in google map document.
And for Swift 4 and swift 5
let apiKey = "https://www.google.com/maps/dir/" + userCurrentLocation.coordinate.latitude + "," + userCurrentLocation.coordinate.longitude + "/" + nextCurrentLocation.coordinate.latitude + "," + nextCurrentLocation.coordinate.longitude
var url = URL(string: apikey)
For objective c use
NSString *apikey = [NSString stringWithFormat:#"https://www.google.co.in/maps/dir/%f,%f/%f,%f",userCurrentLocation.coordinate.latitude,userCurrentLocation.coordinate.longitude,nextCurrentLocation.coordinate.latitude,nextCurrentLocation.coordinate.longitude;
NSURL *url = [NSURL URLWithString:apikey];
[[UIApplication sharedApplication] openURL:url];
You can do it like this in Swift 4 :
let url = URL(string: "https://maps.google.com")
if (UIApplication.shared.canOpenURL(url!))
{
let originLat:String = String(locationManager.location!.coordinate.latitude)
let originLong:String = String(locationManager.location!.coordinate.longitude)
let destLat:String = String(locationObj.latitude)
let destLong:String = String(locationObj.longitude)
let openUrlString:String = String(format:"https://www.google.com/maps/dir/?api=1&origin=%#,%#&destination=%#,%#&travelmode=driving",originLat,originLong,destLat,destLong)
print("openUrlString is : \(openUrlString)")
let openUrl = URL(string: openUrlString)
UIApplication.shared.open(openUrl!, options: [:]) { (res:Bool) in
}
}

Unable to encode String for URL in Swift 3

I used to develop iOS Apps using Objective-C. Now I have recently migrated to Swift. In my app, I have a button that opens MS Outlook App with the pre-filled Subject and Body.
I did a similar App in Objective-C and used the below code to Encode my String for URL.
NSString *emailSubject = #"Test Subject";
NSString *encodedSubject = [emailSubject stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
Now I am unable to do the same in Swift 3. Below is the code that I tried.
var subjectText: String = "Test Subject"
var encodedSubject = subjectText.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
var stringURL: String = "ms-outlook://compose?subject=" + subjectText + "&body=TestingEmailNow"
// Convert the string to a URL.
var url = URL(string: stringURL)
// Open the app that responds to the URL scheme (should be Outlook).
UIApplication.shared.openURL(url!)
The error that I am getting is below.
fatal error: unexpectedly found nil while unwrapping an Optional value
2017-06-07 04:29:35.158030+0400 My App[1286:405793] fatal error: unexpectedly found nil while unwrapping an Optional value
I know that this error is coming due to the space in my Subject. I can say this because if I remove the space, I don't even have to encode it. It works directly. What am I doing wrong over here?
You made a simple mistake.
check your line
var stringURL: String = "ms-outlook://compose?subject=" + subjectText + "&body=TestingEmailNow"
you are using subjectText instead of encodedSubject
Complete code:
var subjectText: String = "Test Subject"
var encodedSubject = subjectText.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
if let encodedSubject = encodedSubject {
var stringURL: String = "ms-outlook://compose?subject=" + encodedSubject + "&body=TestingEmailNow"
// Convert the string to a URL.
var url = URL(string: stringURL)
if let url = url {
// Open the app that responds to the URL scheme (should be Outlook).
UIApplication.shared.openURL(url)
}
}
Variable used was the problem but I'd also suggest using URLComponents instead of building the URL as string.
var subjectText: String = "Test Subject"
var components = URLComponents()
components.scheme = "ms-outlook"
components.host = "compose"
components.queryItems = [
URLQueryItem(name: "subject", value: subjectText),
URLQueryItem(name: "body", value: "TestingEmailNow")
]
if let url = components.url {
UIApplication.shared.openURL(url)
}

The '#' char gets converted to %23 causing the GET Request to fail

I am a new Swift developer using Swift 3 developing an iOS app. I need to make a URL Request to get some data from the web. That URL contains a # character.
I use URLComponents with URLQueryItems to build the request URL. During this process the # char gets converted to %23 which I think is valid utf8 encoding. Unfortunately, this causes the GET to fail.
To test I pasted the URL into my browser and changed %23 back to # and it worked just fine.
How can I fix this so it does not change # to URL. I did find a post from a couple years ago but it was using old framework items so it does not apply to me.
Below is the playground I made to illustrate and test this.
// ------------------------------------------------------------------
//: Playground - TestBuildURLWithParameters
//
// I am using this playground to build the proper
// URL for the GET request to get the detailed
// rtesults for a specific athlete where the "Key"
// is their Bib Nbr. If the GET cant find the specific
// Atlete with that URL it redirects you to the list
// of athlete results (which is no go to me in this case)
//
// Currently, there is a big "gotcha". In building the URL
// using component and query items, the foundation classes
// replace the '#' sign in the URL with the %23 which represents
// the pound sign. Unfortunately, the causes the GET to fail
// and redirects to athlete list which is not helpful
// I am still trying to figure out how to FORCE it to keep
// the '#" character in the URL so it will work
//
// ------------------------------------------------------------------
import Foundation
import UIKit
let baseURLString = "http://www.ironman.com/triathlon/events/americas/ironman-70.3/augusta/results.aspx"
let rd = "20150927"
let race = "augusta70.3"
let bibID = "93"
var detail = "1#axzz4FGGcjBOn"
print("Detail w/o unicocde: \(detail)")
detail = "1\u{0023}axzz4FGGcjBOn"
print("Detail with unicocde: \(detail)")
var components = URLComponents(string: baseURLString)!
var queryItems: [URLQueryItem] = [] // All Items after the "?"
let baseParams =
[
"rd": rd,
"race": race,
"bidID": bibID, // Note: HTML mispelled bib with bid so "bidID" is the URL search
"detail": detail
]
for (key, value) in baseParams
{
let item = URLQueryItem(name: key, value: value)
queryItems.append(item)
}
components.queryItems = queryItems // what does this look like
print("components: \(components)") // see it
It is not a good way to include fragment part of URL into query items.
Try this:
import Foundation
let baseURLString = "http://www.ironman.com/triathlon/events/americas/ironman-70.3/augusta/results.aspx"
let rd = "20150927"
let race = "augusta70.3"
let bibID = "93"
var detail = "1"
//# split the last query item and the fragment
let fragment = "axzz4FGGcjBOn"
var components = URLComponents(string: baseURLString)!
var queryItems: [URLQueryItem] = []
let baseParams =
[
"rd": rd,
"race": race,
"bidID": bibID,
"detail": detail
]
for (key, value) in baseParams
{
let item = URLQueryItem(name: key, value: value)
queryItems.append(item)
}
components.queryItems = queryItems
components.fragment = fragment
print("components: \(components)")
If you need you can choose the character that will receive the encoding.
In the charactersIn: you put all characters you want to encode.
Then you use the .inverted so all the others characters will go normal like this:
let customAllowedSet = NSCharacterSet(charactersIn:"=\"%/<>?#\\^`{|}").inverted
let encondedString = originalString.addingPercentEncoding(withAllowedCharacters: customAllowedSet)
print("enconded string: \(encondedString)")
Encode your parameters and then add it to URL, this will encode # before hitting API and you'll get desired result.
To encode parameters, you can use below code.
var parameterString = "your parameter string"
var encodedString = parameterString .addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
print(encodedString !)
I did get an answer via email from a friend that works for now. Basically, I added the query items manually to the URL using the URL extension below so it didn't monkey with the '#' char:
extension URL {
func appendingNonEscapedQueryItems(_ queryItems: [URLQueryItem]) -> URL {
let url = self
var urlString = url.absoluteString
for queryItem in queryItems {
let queryName = queryItem.name
guard let queryValue = queryItem.value else {
continue
}
let query = queryName + "=" + queryValue
if queryItem == queryItems.first {
urlString = urlString + "?" + query
}
else
{
urlString = urlString + "&" + query
}
}
return URL(string: urlString)!
}
}
...
let requestURL = components.url!.appendingNonEscapedQueryItems(queryItems)
print("URL \(requestURL)")

Simple Post Request with Alamofire

It's my first post here, I'm trying to do this with Alamofire:
Swift code:
let name = "Taza"
let description = "50cl"
let parameters = ["name": name, "description": description]
Alamofire.request(.POST, "http://xxxxx.es/JSONpresenter.php?op=5", parameters: parameters, encoding: .JSON);
PHP code:
$op=$_GET['op'];
else if($op == 5)
{
// Get user id
$name = isset($_POST['name']) ? mysql_real_escape_string($_POST['name']) : “”;
$description = isset($_POST['description']) ? mysql_real_escape_string($_POST['description']) : “”;
add($name,$description);
}
But only get a register with "" in all cells. What am I doing wrong?
You need to use the URLEncoding instead of JSONEncoding for this particular case

Replace occurrences of space in URL

I have a URL in an iPhone application to work with. But the problem is that it has some spaces in the URL. I want to replace the spaces with '%20'. I know that there are the stringByReplacingOccurencesOfString and stringByAddingPercentEscapesUsingEncoding methods. I also have used them. But they are not working for me. The spaces are replaced by some unusual values.
I'm applying those methods on an instance of NSString.
The correct format for replacing space from url is :
Swift 4.2 , Swift 5
var urlString = originalString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
Swift 4
var urlString = originalString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
Objective C
NSString *urlString;//your url string.
urlString = [originalUrl stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
or
urlString = [originalUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
iOS 9 and later
urlString = [originalUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
Swift 2.0
let originalUrl = "http://myurl.com/my photo.png"
let urlNew:String = urlReq.stringByAddingPercentEncodingWithAllowedCharacters( NSCharacterSet.URLQueryAllowedCharacterSet())!
Output:
http://myurl.com/my%20photo.png
To replace occurence in SWIFT 3 :
let updatedUrl = originalUrl.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)
Swift 4
Another way to replace an empty space with replacingOccurrences method:
let yourString = "http://myurl.com/my photo.png"
let urlNew:String = yourString.replacingOccurrences(of: " ", with: "%20").trimmed
That will replace the empty space (" ") with '%20'
Swift 5
var urlString = originalString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
Swift 5.3, clear space your string,
let str = " www.test.com "
let trimmed = str.trimmingCharacters(in: .whitespacesAndNewlines)
print(str) // "www.test.com"
var urlString :String = originalUrl.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)!
Hope this will work
let url = "https:youtube.56432fgrtxcvfname=xyz&sname=tuv"
let urlNew:String = url.replacingOccurrences(of: " ", with: "%20")
Alamofire.request(urlNew, method: .get, headers: headers).responseJSON{
response in
print(response)
}
It will remove all kind of spaces from the url.
The quickest solution: just use the stringy method...
.replacingOccurrences(of: " ", with: "%20")
...at the end of your string, and it will do as it says.
Apple should be EMBARRASSED that their URL(string: ) method doesn't automatically do this (and more). It's 2023 and I wasted 3 hours finding this half-assed solution.
My specific example was inside cellForItemAt and having to do with optionals.
let stringOfImageURLFromFirebase = wordController?.word?.images[indexPath.item].imgUrl
let stringWithNoSpaces = string?.replacingOccurrences(of: " ", with: "%20")
if let imageURLString = stringWithNoSpaces,
let imageURL = URL(string: imageURLString) {
cell.definitionImageView.loadImageFromFirebase(url: imageURL)
} else {
cell.definitionImageView.image = UIImage(named: "slictionarylogo")
}
You can fuddle with .addingPercentEncoding for a long time, try NSURL nonsense, and you'll just be faster with using the obvious. Apple sucks, and should've made this painfully easy since it's such a common problem. Again, they are asleep at the wheel, and their documentation is AWFUL too.
SWIFT 3.1
Simple way to replace an empty space with replacingOccurrences:
URL = URL.replacingOccurrences(of: " ", with: "", options: .literal, range: nil)
Swift 4, iOS-9
let **urlSearchVal**:String = "top 10 movies"
let urlString =
"https://www.googleapis.com/youtube/v3/search?part=snippet&q=\(urlSearchVal)&key=......&type=video"
//replace ...... above with your youtube key
// to ignoring white space in search
let UrlString :String = urlString.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)!
A Swift 4 solution. You simply pass through a string and it fills spaces with %20 and adds "http://" to the beginning to the string. Pretty sweet!
URL(fileURLWithPath: String)

Resources