I'm trying to run this function when a button is tapped:
#IBAction func openLink(_ sender: UIButton) {
let link1 = "https://www.google.com/#q="
let link2 = birdName.text!
let link3 = link2.replacingOccurrences(of: " ", with: "+") //EDIT
let link4 = link1+link3
guard
let query = link4.addingPercentEncoding( withAllowedCharacters: .urlQueryAllowed),
let url = NSURL(string: "https://google.com/#q=\(query)")
else { return }
UIApplication.shared.openURL(URL(url))
}
However, the last line is flagged as "cannot call value of non-function type "UIApplication". This syntax is from here, so I'm not sure whats going on.
Use guard to unwrap the textfield text property, replacing the occurrences, add percent encoding to the result and create an URL from the resulting string:
Try like this:
guard
let text = birdName.text?.replacingOccurrences(of: " ", with: "+"),
let query = text.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
let url = URL(string: "https://google.com/#q=" + query)
else { return }
if #available(iOS 10.0, *) {
UIApplication.shared.open(url)
} else {
UIApplication.shared.openURL(url)
}
Related
This question already has answers here:
Swift - encode URL
(19 answers)
Closed 1 year ago.
I have a string that can include any characters, from alphanumeric to special chars like "&,.:/!" etc. I need to encode that string and send it to twitter. I tried the following but as soon as theres an & character in text, it doesn't work properly:
static func shareToTwitter(text: String) {
guard let urlEscaped = text.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {
return
}
guard let url = URL(string: "twitter://post?message=\(urlEscaped)") else {
return
}
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
} else {
guard let twitterUrl = URL(string: "https://twitter.com/intent/tweet?text=\(urlEscaped)") else {
return
}
UIApplication.shared.open(twitterUrl)
}
}
So an example sentence might be: "I'm here & there". Instead, Twitter will receive "I'm here". How can I fix this?
As suggested by Alexander the most reliable way is to use URLComponents and URLQueryItem
static func shareToTwitter(text: String) {
var components = URLComponents(string: "twitter://post")!
components.queryItems = [URLQueryItem(name: "message", value: text)]
if let url = components.url, UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
} else {
components = URLComponents(string: "https://twitter.com/intent/tweet")!
components.queryItems = [URLQueryItem(name: "text", value: text)]
guard let twitterUrl = components.url else { return }
UIApplication.shared.open(twitterUrl)
}
}
I am using amazon product advertising api for search product. Installed awscore and alamofire cocopods. Done functionality for getting signature and added parameters for item search to get product images, title and description in table view list.
Here is the code i tried for getting amazon search:
private func signedParametersForParameters(parameters: [String: String]) -> [String: String] {
let sortedKeys = Array(parameters.keys).sorted(by: <)
let query = sortedKeys.map { String(format: "%#=%#", $0, parameters[$0] ?? "") }.joined(separator: "&")
let stringToSign = "GET\nwebservices.amazon.in\n/onca/xml\n\(query)"
print("stringToSign::::\(stringToSign)")
let dataToSign = stringToSign.data(using: String.Encoding.utf8)
let signature = AWSSignatureSignerUtility.hmacSign(dataToSign, withKey: CameraViewController.kAmazonAccessSecretKey, usingAlgorithm: UInt32(kCCHmacAlgSHA256))!
var signedParams = parameters;
signedParams["Signature"] = urlEncode(signature)
print("urlencodesignature::\(urlEncode(signature))")
return signedParams
}
public func urlEncode(_ input: String) -> String {
let allowedCharacterSet = (CharacterSet(charactersIn: "!*'();:#&=+$,/?%#[] ").inverted)
if let escapedString = input.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) {
return escapedString
}
return ""
}
func send(url: String) -> String {
// activityIndicator.startAnimating()
guard let url = URL(string: url) else {
print("Error! Invalid URL!") //Do something else
// activityIndicator.stopAnimating()
return ""
}
print("send URL: \(url)")
let request = URLRequest(url: url)
let semaphore = DispatchSemaphore(value: 0)
var data: Data? = nil
URLSession.shared.dataTask(with: request) { (responseData, _, _) -> Void in
data = responseData
print("send URL session data: \(String(describing: data))")
let parser = XMLParser(data: data!)
parser.delegate = self as? XMLParserDelegate
if parser.parse() {
print(self.results ?? "No results")
}
semaphore.signal()
}.resume()
// activityIndicator.stopAnimating()
semaphore.wait(timeout: .distantFuture)
let reply = data.flatMap { String(data: $0, encoding: .utf8) } ?? ""
return reply
}
public func getSearchItem(searchKeyword: String) -> [String:AnyObject]{
let timestampFormatter: DateFormatter
timestampFormatter = DateFormatter()
timestampFormatter.timeZone = TimeZone(identifier: "GMT")
timestampFormatter.dateFormat = "YYYY-MM-dd'T'HH:mm:ss'Z'"
timestampFormatter.locale = Locale(identifier: "en_US_POSIX")
// let responsegroupitem: String = "ItemAttributes"
// let responsegroupImages:String = "Images"
// activityIndicator.startAnimating()
let operationParams: [String: String] = [
"Service": "AWSECommerceService",
"Operation": "ItemSearch",
"ResponseGroup": "Images,ItemAttributes",
"IdType": "ASIN",
"SearchIndex":"All",
"Keywords": searchKeyword,
"AWSAccessKeyId": urlEncode(CameraViewController.kAmazonAccessID),
"AssociateTag": urlEncode(CameraViewController.kAmazonAssociateTag),
"Timestamp": urlEncode(timestampFormatter.string(from: Date()))]
let signedParams = signedParametersForParameters(parameters: operationParams)
let query = signedParams.map { "\($0)=\($1)" }.joined(separator: "&")
let url = "http://webservices.amazon.in/onca/xml?" + query
print("querydata::::\(query)")
let reply = send(url: url)
print("reply::::\(reply)")
// activityIndicator.stopAnimating()
return [:]
}
Created bridging header file #import .
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
getSearchItem(searchKeyword: searchKeyword)
}
Here is my console output:
My issue is when tapping search button product searched was not listing. What mistake done i don't know. Can anyone help me out of this pls..
According to the documentation:
The HTTPRequestURI component is the HTTP absolute path component of the URI up to, but not including, the query string. If the HTTPRequestURI is empty, use a forward slash ( / ).
HTTPRequestURI is always "/onca/xml" for Product Advertising API. HTTPVerb is either GET or POST.
Try just setting requestURL to "/onca/xml" instead of the full URL you shouldn't be sending the full URL or the query string in this part.
Also you need to percent encode the values that you are sending. You are sending commas in the response group property which should be percent encoded
let operationParams: [String: String] = [
"Service": "AWSECommerceService",
"Operation": "ItemSearch",
"ResponseGroup": urlEncode("Images,ItemAttributes"),
"IdType": "ASIN",
"SearchIndex":"All",
"Keywords": urlEncode(searchKeyword),
"AWSAccessKeyId": urlEncode(CameraViewController.kAmazonAccessID),
"AssociateTag": urlEncode(CameraViewController.kAmazonAssociateTag),
"Timestamp": urlEncode(timestampFormatter.string(from: Date()))]
let stringToSign = "GET\n/onca/xml\n\(query)"
Note: You should be using https instead of http
I think so This question is not duplicate one.
Call to phone number when touching cancel Action my app throws app to initial screen instead of displaying current screen.
Is this a bug in iOS11 or is there something that I am doing wrong from following code. this is my code.
#objc func CallAction(_ sender : UIButton)
{
var localDic :NSDictionary!
if is_searching {
localDic = searchingDataArray.object(at: sender.tag) as! NSDictionary
}else
{
localDic = myStudentsArray.object(at: sender.tag) as! NSDictionary
}
let phoneNumber=localDic["contact_no"] as! String
print("phoneNumber",phoneNumber )
guard let number = URL(string: "tel://" + phoneNumber) else { return }
UIApplication.shared.open(number)
}
Use the following code
guard let telNumber = URL(string: "telprompt://" + "+1234-567-89") else { return }
if #available(iOS 10.0, *) {
UIApplication.shared.open(telNumber)
} else {
// Fallback on earlier versions
}
hope its works..
I have a URL String "http:///blaBla?id=Testid851211" and I just want to get "851211".
Below is my code :-
let url: NSURL = NSURL(string: urlString)!
Helper.sharedInstance.Print(url.query as AnyObject)
if (url.query?.localizedStandardContains("testKey"))! {
//TestKey
Helper.sharedInstance.Print(url.query as AnyObject)
let testValue = getQueryStringParameter(url: urlString, param: "testKey")
Helper.sharedInstance.Print(testValue as AnyObject)
}
else if (url.query?.localizedStandardContains("testID"))! {
//TestID
Helper.sharedInstance.Print(url.query as AnyObject)
}
func getQueryStringParameter(url: String, param: String) -> String? {
guard let url = URLComponents(string: url) else { return nil }
return url.queryItems?.first(where: { $0.name == param })?.value
}
I am getting id = Testid851211 but I want only "851211".
Use a regular expression filtering out numbers only:
let urlString = "http:///blaBla?id=Testid851211"
let pattern = "[0-9]+"
if let matchRange = urlString.range(of: pattern, options: .regularExpression) {
print(urlString[matchRange])
}
Works as long as your URLs don’t have numbers anywhere else.
Try this extension:
extension String {
func getNeededText(for url: String) -> String {
guard range(of: url) != nil else { return "" }
return replacingOccurrences(of: url, with: "")
}
}
Usage:
let predefinedHost = "http:///blaBla?id=Testid"
let url = "http:///blaBla?id=Testid851211"
url.getNeededText(for: predefinedHost) // prints "851211"
I try to get URLs in text. So, before, I used such an expression:
let re = NSRegularExpression(pattern: "https?:\\/.*", options: nil, error: nil)!
But I had a problem when a user input URLs with Capitalized symbols (like Http://Google.com, it doesn't match it).
I tried:
let re = NSRegularExpression(pattern: "(h|H)(t|T)(t|T)(p|P)s?:\\/.*", options: nil, error: nil)!
But nothing happened.
You turn off case sensitivity using an i inline flag in regex, see Foundation Framework Reference for more information on available regex features.
(?ismwx-ismwx)
Flag settings. Change the flag settings. Changes apply to the portion of the pattern following the setting. For example, (?i) changes to a case insensitive match.The flags are defined in Flag Options.
For readers:
Matching an URL inside larger texts is already a solved problem, but for this case, a simple regex like
(?i)https?://(?:www\\.)?\\S+(?:/|\\b)
will do as OP requires to match only the URLs that start with http or https or HTTPs, etc.
Swift 4
1. Create String extension
import Foundation
extension String {
var isValidURL: Bool {
guard !contains("..") else { return false }
let head = "((http|https)://)?([(w|W)]{3}+\\.)?"
let tail = "\\.+[A-Za-z]{2,3}+(\\.)?+(/(.)*)?"
let urlRegEx = head+"+(.)+"+tail
let urlTest = NSPredicate(format:"SELF MATCHES %#", urlRegEx)
return urlTest.evaluate(with: trimmingCharacters(in: .whitespaces))
}
}
2. Usage
"www.google.com".isValidURL
Try this - http?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?
let pattern = "http?://([-\\w\\.]+)+(:\\d+)?(/([\\w/_\\.]*(\\?\\S+)?)?)?"
var matches = [String]()
do {
let regex = try NSRegularExpression(pattern: pattern, options: NSRegularExpressionOptions(rawValue: 0))
let nsstr = text as NSString
let all = NSRange(location: 0, length: nsstr.length)
regex.enumerateMatchesInString(text, options: NSMatchingOptions.init(rawValue: 0), range: all, usingBlock: { (result, flags, _) in
matches.append(nsstr.substringWithRange(result!.range))
})
} catch {
return [String]()
}
return matches
Make an exension of string
extension String {
var isAlphanumeric: Bool {
return rangeOfString( "^[wW]{3}+.[a-zA-Z]{3,}+.[a-z]{2,}", options: .RegularExpressionSearch) != nil
}
}
call using like this
"www.testsite.edu".isAlphanumeric // true
"flsd.testsite.com".isAlphanumeric //false
My complex solution for Swift 5.x
ViewController:
private func loadUrl(_ urlString: String) {
guard let url = URL(string: urlString) else { return }
let request = URLRequest(url: url)
webView.load(request)
}
UISearchBarDelegate:
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
guard let text = searchBar.text else { return }
if !text.isUrl() {
let finalUrl = String(format: "%#%#", "https://www.google.com/search?q=", text)
loadUrl(finalUrl)
return
}
if text.starts(with: "https://") || text.starts(with: "http://") {
loadUrl(text)
return
}
let finalUrl = String(format: "%#%#", "https://", text)
loadUrl(finalUrl)
}
String extension:
extension String {
func isUrl() -> Bool {
guard !contains("..") else { return false }
let regex = "((http|https)://)?([(w|W)]{3}+\\.)?+(.)+\\.+[A-Za-z]{2,3}+(\\.)?+(/(.)*)?"
let urlTest = NSPredicate(format:"SELF MATCHES %#", regex)
return urlTest.evaluate(with: trimmingCharacters(in: .whitespaces))
}
}