I have an URL with
https://api.asiancar.com/api/applicationsettings
It is basically a GET url so I need to pass a boolean "isMobile" and timestamp as query parameters . How to achieve this as the ultimate URL after passing the query will look like this:
https://api.asiancar.com/api/applicationsettings?timestamp=111122244556789879&isMobile=true
let queryItems = [
NSURLQueryItem(timestamp: "1234568878788998989", isMobile: true),
NSURLQueryItem(timestamp: "1234568878788998989", isMobile: true)
]
let urlComps = NSURLComponents(string: "www.api.asiancar.com/api/applicationsettings")!
urlComps.queryItems = queryItems
let URL = urlComps.URL!
Am I doing right or any other modification ? please tell.
Unless you have subclassed NSURLQueryItem, then your init method is not correct. Per Apple's documentation for NSURLQueryItem, the init method signature is:
init(name: String, value: String?)
This means your query items should be created like this:
let queryItems = [NSURLQueryItem(name: "timestamp" value: "1234568878788998989"), NSURLQueryItem(name: "isMobile", value: "true")]
This will properly add them to the url in the format you are expecting.
You can try an alternative way by using String
let baseUrlString = "https://api.asiancar.com/api/"
let timeStamp = 1234568878788998989
let isMobile = true
let settingsUrlString = "\(baseUrlString)applicationsettings?timestamp=\(timeStamp)&isMobile=\(isMobile)"
print(settingsUrlString)
let url = URL(string: settingsUrlString)
output : https://api.asiancar.com/api/applicationsettings?timestamp=1234568878788998989&isMobile=true
Try this :
let API_PREFIX = "www.api.asiancar.com/api/applicationsettings"
var url : URL? = URL.init(string: API_PREFIX + queryItems(dictionary: [name: "isMobile", value: "true"] as [String : Any]))
func queryItems(dictionary: [String:Any]) -> String {
var components = URLComponents()
print(components.url!)
components.queryItems = dictionary.map {
URLQueryItem(name: $0, value: $1 as String)
}
return (components.url?.absoluteString)!
}
Related
I have a function that takes an image and a string. When I try to put the string into a longer string using the () ability, it tells me it finds nil while unwrapping an optional. Exception it's not an optional at all, it's a string. I can print the value out and it comes out correctly.
func UpdateBusiness(logo: UIImage, category: String) {
guard let bizID = UserDefaults.standard.string(forKey: defaultKeys.businessID) else {return}
let thisURL = "http://mywebsite.com/api/v0.1/Business/EditBusinessLogoAndCategory?businessID=\(bizID)&category=\(category)"
let combinedURL = URL(string: thisURL)!
}
creating the URL crashes the system. I can see the value of category in the debugger, and I have no optionals in this string. How can it find nil?
This code is crashing due to force unwrapping. In this case can recommend to use URLComponents.This is more readable than the string joining and for large number of parameter string joining is not a good option.
var components = URLComponents()
components.scheme = "http"
components.host = "mywebsite.com"
components.path = "/api/v0.1/Business/EditBusinessLogoAndCategory"
components.queryItems = [
URLQueryItem(name: "businessID", value: bizID),
URLQueryItem(name: "category", value: category)
]
let url = components.url
enter code here
i have to call GET API like
required :
http://ctesterst.net/api/Customers/homeData?lat=12.456&lng=76.786¤t_app_version=123¤t_device=%7B%22Test%22%3A%22123%22%2C%22name%22%3A%22something%22%2C%22tested%22%3Atrue%7D&access_token=Km3R2AbU0yzAcVkp9BCxmCmaoC5k20fBiQxfLhIBIAolwJGgYw5w5E8X0NZzlDh8
like that i have to call.
input parameters how to add ??
i am doing like this :
my json string is : request model
struct RequestData: Codable {
struct Devices: Codable {
let test: String
let name: String
let tested:Bool
}
let current_device: Devices
}
and my url is :
urlAppend = val + "&lat=\(lati)" + "&lng=\(long)" + "¤t_app_version=\(appVersion)" + "¤t_device=\(jsonString)"
its getting crash .. please give me solution .
Thanks
You can use URLComponents for this, URLComponents is defined in Foundation.
var components = URLComponents()
components.scheme = "http"
components.host = "ctesterst.net"
components.path = "/api/Customers/homeData"
let queryItemLat = URLQueryItem(name: "lat", value: "12.456")
let queryItemLong = URLQueryItem(name: "lng", value: "76.786")
let queryItemAppVersion = URLQueryItem(name: "current_app_version", value: "123")
let queryItemDevice = URLQueryItem(name: "current_device", value: "something")
let queryItemToken = URLQueryItem(name: "access_token", value: "Km3R2AbU0yzAcVkp9BCxmCmaoC5k20fBiQxfLhIBIAolwJGgYw5w5E8X0NZzlDh8")
components.queryItems = [queryItemLat, queryItemLong,queryItemAppVersion,queryItemDevice,queryItemToken]
print(components.url)
I am trying to form an URL dynamically.
where I am using Struct to construct it form resultant url
Constants.Swift
import Foundation
private struct Domains {
static let Local = "localhost IP"
static let QA = "QA.Environment"
static let UAT = "http://test-UAT.com"
}
// HardCoded URLRoutes
private struct URLRoutes{
static let query = "query=bitcoin&"
static let date = "date=2019-04-04&"
static let sortBy = "sortBy=Date&"
}
private static let constructionURL = Domain.local+URLRoutes.query + URLRoutes.date + URLRoutes.sortBy + API.Key
static var ResultantURL: String {
return constructionURL
}
I am trying to make this dynamic to pass value from other class to form the dynamic url.
private struct URLRoutes{
var query : String
var date : String?
var sortBy : String?
}
From another Class trying to access the resultant URL
url = URL(string: URLRoutes.ResultantURL)!
but how can I construct the formate of url from the another class?
static let query = "query=bitcoin&"
static let date = "date=2019-04-04&"
static let sortBy = "sortBy=Date&"
Your inputs will guide me.
Here's playground code that does what you want:
struct API {
static let Key = "ABC123"
}
struct URLRoutes{
var query : String
var date : String?
var sortBy : String?
var constructionURL: String {
return query + (date ?? "") + (sortBy ?? "") + API.Key
}
}
let query = "query=bitcoin&"
let date = "date=2019-04-04&"
let sortBy = "sortBy=Date&"
let myRoute = URLRoutes(query: query, date: date, sortBy: sortBy)
print(myRoute.constructionURL)
However, this isn't really ideal and doesn't use the constructs that Apple provides. Here's another approach:
struct URLRoute {
var queryItems:[URLQueryItem]
init(query: String, date:String?, sortBy:String?) {
queryItems = [
URLQueryItem(name: "query", value: query),
URLQueryItem(name: "date", value: date),
URLQueryItem(name: "sortBy", value: sortBy),
URLQueryItem(name: "api_key", value: API.Key)
]
}
var constructionURL:String {
get {
var component = URLComponents(string: "")
component?.queryItems = queryItems
return component?.string ?? ""
}
}
}
let betterRoute = URLRoute(query: "bitcoin", date: "2019-04-04", sortBy: "Date")
print(betterRoute.constructionURL)
You can use URLComponents to do lots of heavy lifting for you in creating valid URLs.
I have the string below and I would like to remove this part "https://drive.google.com/open?id=" so that my string only has "1FN7S3N_9IAkWYMjLnqh4BKsh8_YT0Zma" Any suggestions? Thanks!
let string = "https://drive.google.com/open?id=1FN7S3N_9IAkWYMjLnqh4BKsh8_YT0Zma"
URL could have other parameters so just replacing string might not be a good solution. URLComponents comes in handy for this.
func getQueryStringParameter(url: String, param: String) -> String? {
return URLComponents(string: url)?.queryItems?.first{ $0.name == param }?.value
}
And use it like this.
let string = "https://drive.google.com/open?id=1FN7S3N_9IAkWYMjLnqh4BKsh8_YT0Zma"
if let id = getQueryStringParameter(url: string, param: "id") {
print(id)
}
Get 2nd component separated by google drive part:
let string = "https://drive.google.com/open?id=1FN7S3N_9IAkWYMjLnqh4BKsh8_YT0Zma"
let id = string.components(separatedBy: "https://drive.google.com/open?id=")[1]
Replace google drive part with empty string:
let string = "https://drive.google.com/open?id=1FN7S3N_9IAkWYMjLnqh4BKsh8_YT0Zma"
let id = string.replacingOccurrences(of: "https://drive.google.com/open?id=", with: "")
So I am messing around with the iMessages Framework, and in order to send data to another user the data must be sent as a URLComponents URL. However I can't figure out how to send a dictionary to use as the messages.url value.
func createMessage(data: dictionary) {
/*
The Dictionary has 3 values, 1 string and two arrays.
let dictionary = ["title" : "Title Of Dictionary", "Array1" : [String](), "Array2" : [String]() ] as [String : Any]
*/
let components = URLComponents()
let layout = MSMessageTemplateLayout()
layout.image = UIImage(named: "messages-layout.png")!
layout.imageTitle = "\(dictionary["title"])"
let message = MSMessage()
message.url = components.url!
message.layout = layout
self.activeConversation?.insert(message, completionHandler: { (error: Error?) in
print("Insert Message")
})
}
Does anybody know how I can send the dictionary values as URLQueryItems in the URLComponents to save as the message.url ?
PS: I was wondering wether it would be possible to create an extension for the URL to store the dictionary in, that is what I am unsuccessfully trying atm.
Here is a code snippet to convert dictionary to URLQueryItems:
let dictionary = [
"name": "Alice",
"age": "13"
]
func queryItems(dictionary: [String:String]) -> [URLQueryItem] {
return dictionary.map {
// Swift 3
// URLQueryItem(name: $0, value: $1)
// Swift 4
URLQueryItem(name: $0.0, value: $0.1)
}
}
var components = URLComponents()
components.queryItems = queryItems(dictionary: dictionary)
print(components.url!)
You can use the following URLComponents extension:
extension URLComponents{
var queryItemsDictionary : [String:Any]{
set (queryItemsDictionary){
self.queryItems = queryItemsDictionary.map {
URLQueryItem(name: $0, value: "\($1)")
}
}
get{
var params = [String: Any]()
return queryItems?.reduce([:], { (_, item) -> [String: Any] in
params[item.name] = item.value
return params
}) ?? [:]
}
}
}
And set the url components:
var url = URLComponents()
url.queryItemsDictionary = ["firstName" : "John",
"lastName" : "Appleseed"]
You can use iMessageDataKit library. It's a tiny, useful MSMessage extension for setting/getting Int, Bool, Float, Double, String and Array values for keys.
It makes setting and getting data really easy like:
let message: MSMessage = MSMessage()
message.md.set(value: 7, forKey: "user_id")
message.md.set(value: "john", forKey: "username")
message.md.set(values: ["joy", "smile"], forKey: "tags")
print(message.md.integer(forKey: "user_id")!)
print(message.md.string(forKey: "username")!)
print(message.md.values(forKey: "tags")!)
(Disclaimer: I'm the author of iMessageDataKit)