I am having a validation problem creating an URL object in Swift, returning me nil when I attempt to create it by means of this string:
https://maps.googleapis.com/maps/api/staticmap?size=70x70&path=weight:3%7Ccolor:black%7Cenc:oo%60rG%7Bpxm#zHeW%60H%7BDjJPzKwBnKhKzHrVaExa#gWzCeNsO&path=weight:3%7Ccolor:blue%7Cenc:q|_rG%7Dnym#jJPzKwBnKhKzHrV&key=[my api key]
I need to to use Google Maps Static API in order to get an image of the map including a path I pass as argument to the url in the form of an encrypted polyline.
I tried to escape the url using:
addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
Doing this let me create an URL object, though the polyline is altered and the path won't be drawn.
Could you please give me any suggestion?
PS. If I type the url I get without applying addingPercentEncoding in the browser, it shows me the image as expected.
PPS. GMS SDK was not included in the project by choice
-- EDIT --
Hi, I tried URLComponents solution suggested by Duncan C, though I got the same result with the google encoded path being distorted.
var urlComponents = URLComponents()
urlComponents.scheme = "https"
urlComponents.host = "maps.googleapis.com"
urlComponents.path = "/maps/api/staticmap"
urlComponents.setQueryItems(with: params)
print(urlComponents.url?.absoluteString)
if let url = urlComponents.url { // generates wrong url }
Different parts of a URL need different encoding rules.
I suggest creating your URL using the system class URLComponents. That lets you specify that various parts of a URL (without encoding) and then you query the URLComponents object for the URL.
Edit:
It sounds to me like the problem is in the encoding of your polyline parameters, since you say those are not rendering. You should include a link to the section of the Google documentation on the Google static maps API that deals with encoded polylines, as well as showing your code that encodes your polyline parameters.
A quick Google search on "google maps encoded polyline swift" yielded a project on Github that implements Google's Polyline encoder / decoder in Swift
Related
I am developing iOS app, I am using URL Session method for make API calls. Api response gives one property which contains AWS s3 link for pdf document.
What should happen:
So in this app, I am retrieving a PDF document from the server to view in the app, so in the GET URL that I'm sending will give a response of an access link of the pdf document generated through AWS S3.
What is happening now:
Document name: Document/sdd3343-sfnf0asdnd0UserB&ServiceLetter.pdf (notice there is an '&' sign)
In the android and Swagger application, this GET URL is working perfect on any circumstances.
but in the iOS version- in the URL session, when ever when there is a '&' sign inside the document's name, the responding access link gets corrupted.
Now in Android and Swagger, when we are accessing the same document, it works perfectly, but for iOS it doesn't.
URL that doesn't work on iOS but that works in Android and Swagger:
https://domainName/api/FileUpload/GetDocumentUrl?S3Key=**Document/sdd3343-sfnf0asdnd0UserB&ServiceLetter.pdf**&fileCategory=2&userId=9888900000
Above url having parameter name called 'S3Key' value is Document/sdd3343 sfnf0asdnd0UserB&ServiceLetter.pdf and it having an ampersand '&' symbol in middle of the name.
iOS response for the above URL:
{"success":true,"response":"https://samplesite.s3.ap-southwest-2.amazonaws.com/Document/sdd3343-sfnf0asdnd0UserB?X-Amz-Expires=3600&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAWEWNDEFIENS88NKWSWIULHKA/20221010/ap-southwest-2/s3/aws4_request&X-Amz-Date=20221010T011135Z&X-Amz-SignedHeaders=host&X-Amz-Signature=44cab95333c0b5e385959835948539845948023823483","error":null}
In here you can see the response which got by the URL Session. But the reponse url body cut off from ampersand symbol.
Current Response: /Document/sdd3343-sfnf0asdnd0UserB?X-Amz-Expires=3600&X.........
Expected Response: /Document/sdd3343-sfnf0asdnd0UserB&ServiceLetter.pdf?X-Amz-Expires=3600&X.........
How to solve this URL Session problem
Note how & characters are used to separate key/value pairs in a URL. Because of this, you cannot have an & in the middle of a value within a URL, because it is interpreted as a delimiter before the next key/value pair. The answer is to percent-escape the & in the value associated with the S3Key key. To do this, the easiest way is URLComponents:
guard var components = URLComponents(string: "https://domainName/api/FileUpload/GetDocumentUrl") else {
print("URLComponents failure")
return
}
components.queryItems = [
URLQueryItem(name: "S3Key", value: "Document/sdd3343-sfnf0asdnd0UserB&ServiceLetter.pdf"),
URLQueryItem(name: "fileCategory", value: "2"),
URLQueryItem(name: "userId", value: "9888900000")
]
guard let url = components.url else {
print("unable to build url")
return
}
print(url) // https://domainName/api/FileUpload/GetDocumentUrl?S3Key=Document/sdd3343-sfnf0asdnd0UserB%26ServiceLetter.pdf&fileCategory=2&userId=9888900000
There are other ways to manually percent-escape the values in the URL, but URLComponents does it reasonably gracefully.
How to get the URL from the given redirect deeplink string?
For example, if I have a deeplink string as
myapp://open-browser/https://mydaily.dev/JOURNAL/home?id=123e4567-e89b-12d3-a456-426655440000&source=01&channel_id=HOME
I would like to get the return result as
https://mydaily.dev/JOURNAL/home?id=123e4567-e89b-12d3-a456-426655440000&source=01&channel_id=HOME
I tried several methods from Apple documentation
Accessing the Parts of a URL,
the closest one was to combine path and query like below screenshot
Does anyone have a better way to do this?
I get your question, I think you want to get only the url starting from https://, please correct me.
If so I think I could remove the deeplink url scheme myapp:// and the host open-browser/ like
let url = "myapp://open-browser/https://mydaily.dev/JOURNAL/home?id=123e4567-e89b-12d3-a456-426655440000&source=01&channel_id=HOME"
let deeplinkBase = "myapp://open-browser/"
let newUrl = url.absoluteString.replacingOccurrences(of: deeplinkBase, with: "")
Then you could use the newUrl as you like since we got the expected result now
https://mydaily.dev/JOURNAL/home?id=123e4567-e89b-12d3-a456-426655440000&source=01&channel_id=HOME
My example for the deeplinkBase string is hardcoded, but I guess you could use enums or any handlers for it later.
I want to share files from MS OneDrive to a user via MS graph API. And user can view my shared file directly through the link. I have read the Document of Creating a sharing Link for a DriveItem and use this API to create a sharing link for my sharing files.
I wonder how to implement with MS graph API? Any suggestion and tips are welcome. Thanks
According to your description, I assume you want to get the share file by using MS Graph API.
Base on my test, We can create a shareLink for this this file.
Then we can use the following steps to get the file information by converting the shareLink.
Encoding the shareLink by using the following logic:
1)First, use base64 encode the URL.
2)Convert the base64 encoded result to unpadded base64url format by removing = characters from the end of the value, replacing / with _ and + with -.)
3)Append u! to be beginning of the string.
If you want access the shared files, you can use the following API:
GET /shares/{shareIdOrUrl}/driveItem
The shareIdOrUrl parameter is the result in step1.
This API will return all the information about the shared file.
As an example, to encode a URL in C#:
string sharingUrl = "https://onedrive.live.com/redir?resid=1231244193912!12&authKey=1201919!12921!1";
string base64Value = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(sharingUrl));
string encodedUrl = "u!" + base64Value.TrimEnd('=').Replace('/','_').Replace('+','-');
For more detail, we can refer to this document.
I use firebase dynamic links which contain an URL to our webapp.
If the dynamic link is opened, the deep link is fetched.
So far so good. As we use the /#/path pattern in our webapp to redirect a user to different sections, we have a problem now, creating such an url in our iOS application after we have to append a new parameter in the url
If this example URL is in our dynamic link
https://domain/#/main/page?utm_source=app&utm_medium=button&utm_campaign=testcampaign
i get it and have to append a parameter for autologin mechanism in our webapp.
So here is the point where i fail at two different approaches.
Getting the string from the url and appending the token parameter and value.
This approach works fine until I have to parse the urlString back to an URL object. The /#/ inside causes an error when creating a new URL object.
I try to replace /#/ with /%23/ (encoded #), but this does not work on our ngnix / webapp infrastructure.
Appending the token parameter with new URLQueryItem in URLComponents.
This approach leads to a wrong URL resulting in (token is the added parameter)
https://my-stage.bikersos.com/?token=tokrenvalue#/main/premium?utm_source=app&utm_medium=button&utm_campaign=testcampaign
I append the URL Query Item with this extension
extension URL {
func addQueryParams(newParams: [URLQueryItem]) -> URL? {
let urlComponents = NSURLComponents.init(url: self, resolvingAgainstBaseURL: false)
guard urlComponents != nil else { return nil; }
if (urlComponents?.queryItems == nil) {
urlComponents!.queryItems = []
}
urlComponents!.queryItems!.append(contentsOf: newParams)
print(urlComponents!)
return urlComponents?.url
}
}
does anybody has an idea how I could solve this problem? I personally prefer the second approach, if it is possible to append the parameters at the end
I figured it out how it has to be done with firebase and utm parameters (this link can be added as deep link in a dynamic link for firebase)
https://example.domain.com/?utm_source=newsletter&utm_medium=button&utm_campaign=testcampaign#/path1/subpath?webappparam1=1&webappparam2=asdf
This way all utm parameters are applied and the path will be available in the web application too.
You can add new query params using the iOS SDK but be aware, they are added at the utm parameters location.
If you need to add them at the end, check if there already exists an ? in the path and write your own appending at the end of the url.
I'm building an iPhone app that interacts with an api. I was building a class that looked something like this:
class Api {
let base_url = NSURL(string: "http://localhost:3000/api/v1/")
func users(){
let url = NSURL(string: "users", relativeToURL: base_url)
...
}
}
My intent is to have a base URL for the API and then the URLs for all the endpoints in the API are built using that base URL. However, I am finding that even tho I am able to successfully build URLs like I show above in a Playground project (so in the example above url represents "http://localhost:3000/api/v1"), when I try to do this in my app It does not work, it builds a weird url (something like "users --ttp://localhost:3000/api/v1/".
I'm a bit puzzled because it works on the playground project, but if I do the same on my app it doesn't.
Would appreciate some help with this.
It built the right URL, it just displays weird. You can use absoluteURL() (or absoluteString()) to get a version of the URL that prints nicely.
Even though the description() returns a weird string, the correct URL would be used in NSURLRequest or any other object which takes a NSURL.