how i get an int from string? - ios

am working on a weather app and i want to generate the image according to the degrees number witch is in a string so how can i extract the number from string
this is the string:
Mostly dry. Very mild (max 19ºC on Sat afternoon, min 15ºC on Sunnight). Wind will be generally light.
#IBAction func weatherButton(sender: UIButton) {
let url = NSURL(string: "http://www.weather-forecast.com/locations/" + cityNameTextField.text.stringByReplacingOccurrencesOfString(" ", withString: "-") + "/forecasts/latest")
if url != nil {
let task = NSURLSession.sharedSession().dataTaskWithURL(url!){ (data, response, error) in
var urlError = false
var weather = ""
if error == nil {
var urlContent = NSString(data: data, encoding: NSUTF8StringEncoding)
var urlContentArray = urlContent!.componentsSeparatedByString("<span class=\"phrase\">")
if urlContentArray.count > 0 {
var weatherArray = urlContentArray[1].componentsSeparatedByString("</span>")
weather = weatherArray[0] as! String
weather = weather.stringByReplacingOccurrencesOfString("°", withString: "º")
println(weather)
}
else {
urlError = true
}
}
else {
urlError = true
}
dispatch_async(dispatch_get_main_queue()) {
if urlError == true {
self.showError()
}
else {
self.weatherFact.text = weather
}
}
}
task.resume()
}
else {
showError()
}
}

Another solution using NSRegularExpression.
The result is an Array of the numbers and the regex considers also temperatures below zero
For Swift 1.2:
let string = "Mostly dry. Very mild (max -19ºC on Sat afternoon, min 15ºC on Sunnight). Wind will be generally light."
let regex = NSRegularExpression(pattern: "-?[0-9]{1,3}", options: NSRegularExpressionOptions(), error: nil)
if let matches = regex?.matchesInString(string, options: NSMatchingOptions(), range: NSRange(location:0, length:count(string))) {
let degrees = matches.map {return (string as NSString).substringWithRange($0.range).toInt()! }
println(degrees) // -> [-19, 15]
}
For Swift 2.0:
let string = "Mostly dry. Very mild (max -19ºC on Sat afternoon, min 15ºC on Sunnight). Wind will be generally light."
do {
let regex = try NSRegularExpression(pattern: "-?[0-9]{1,3}", options: NSRegularExpressionOptions())
let matches = regex.matchesInString(string, options: NSMatchingOptions(), range: NSRange(location: 0, length: string.characters.count))
let degrees = matches.map {Int((string as NSString).substringWithRange($0.range))!}
print(degrees) // -> [-19, 15]
}
catch {
print("NSRegularExpression threw error: \(error)")
}

Related

Split HTML String between strings Swift

Is it possible to take just a part of the HTML string that I have obtained passing the URL?
Example code below:
let myURLString = "https://myUrl.something"
guard let myURL = NSURL(string: myURLString) else {
print("Error: \(myURLString) doesn't seem to be a valid URL")
return
}
do {
let myHTMLString = try String(contentsOf: myURL as URL)
let htmlString = String(myHTMLString)
print("HTML: \(myHTMLString)")
} catch let error as NSError {
print("Error: \(error)")
}
I want to take what's inside the tag <h3 class="post-title"> to </h3>.
I know that I should use the regular expressions but I don't really know how to set it in the right way. I tried something like this:
let myURLString = "https://www.fvgtech.it/category/podcast/"
guard let myURL = NSURL(string: myURLString) else {
print("Error: \(myURLString) doesn't seem to be a valid URL")
return
}
do {
let myHTMLString = try String(contentsOf: myURL as URL)
let htmlString = String(myHTMLString)
if let match = htmlString.range(of: "(<h3.+)", options: .regularExpression) {
print("Found",htmlString.substring(with: match))
}
print("HTML: \(myHTMLString)")
} catch let error as NSError {
print("Error: \(error)")
}
But it's printing just <h3 class="post-title"> and not what's in the middle. Thanks in advance!
Just we need to search all substrings between start String and end String See Extension of String
let myURLString = "https://www.fvgtech.it/category/podcast/"
guard let myURL = NSURL(string: myURLString) else {
print("Error: \(myURLString) doesn't seem to be a valid URL")
return
}
do {
let myHTMLString = try String(contentsOf: myURL as URL)
let htmlString = String(myHTMLString)
print(htmlString.allStringsBetween("<h3 class=\"post-title\">", andString: "</h3>"))
} catch let error as NSError {
print("Error: \(error)")
}
Extension for String
extension String{
func allStringsBetween(start: String, end: String) -> [Any] {
var strings = [Any]()
var startRange: NSRange = (self as NSString).range(of: start)
while true {
if startRange.location != NSNotFound {
var targetRange = NSRange()
targetRange.location = startRange.location + startRange.length
targetRange.length = self.count - targetRange.location
let endRange: NSRange = (self as NSString).range(of: end, options: [], range: targetRange)
if endRange.location != NSNotFound {
targetRange.length = endRange.location - targetRange.location
strings.append((self as NSString).substring(with: targetRange))
var restOfString = NSRange()
restOfString.location = endRange.location + endRange.length
restOfString.length = self.count - restOfString.location
startRange = (self as NSString).range(of: start, options: [], range: restOfString)
}
else {
break
}
}
else {
break
}
}
return strings
}
}

GET request on new Alamofire Swift 3

So I decided to migrate my App to Swift 3.0 but now I am seeing myself unable to solve a problem I´m facing with a .GET request with the new Alamofire. This is the request right now:
func getAlbums(_ ID: String, ANN: String, completed: #escaping DownloadComplete) {
let searchFT = ID.replacingOccurrences(of: " ", with: "+", options: NSString.CompareOptions.literal, range: nil)
let urlPath = ""
let url = URL(string: urlPath)
Alamofire.request(url!, method: .get).responseJSON { response in
if let JSON = response.result.value as! [String: AnyObject]! {
if let dict = JSON["results"] as! NSArray! {
AlbumsArtist.removeAll()
AlbumsArtist = [String]()
ImagesArtist.removeAll()
ImagesArtist = [String]()
for items in dict {
if let AT = items["artistName"] as? String {
if AT == ANN {
if let TN = items["collectionName"] as? String {
AlbumsArtist.append(TN)
} else {
AlbumsArtist.append("")
}
if let IM = items["artworkUrl100"] as? String {
let newString = IM.stringByReplacingOccurrencesOfString("100", withString: "600", options: NSStringCompareOptions.LiteralSearch, range: nil)
ImagesArtist.append(newString)
} else {
ImagesArtist.append("")
}
}
}
}
completed()
}
}
}
}
The problem that I am getting is with if let AT = items["artistName"] as? String the error says this: Type 'NSFastEnumerationIterator.Element (aka: 'Any') has no subscript members
Thank you very much!
As mentioned in the comment you should change your code to:
if let AT = items["artistName"] as? [[String:Any]]
But to make your code more safe you should use the following:
if let AT = items["artistName"] as? [[String:Any]] {
if AT == ANN {
guard let TN = items["collectionName"] as? String,
let IM = items["artworkUrl100"] as? String else { // Some error occurred }
AlbumsArtist.append(TN);
let newString = IM.stringByReplacingOccurrencesOfString("100", withString: "600", options: NSStringCompareOptions.LiteralSearch, range: nil)
ImagesArtist.append(newString)
}
}

Regex used in swift to check decimal input

In my application, there are a few textfields with decimal keyboard input. So I need a function to validate the number.
func valueCheck(check: Double) -> Double{
let myRegex = "^(?:|0|[1-9]\\d*)(?:\\.\\d*)?$"
if check != nil && let match = check.rangeOfString(myRegex, options: .RegularExpressionSearch){
return check
}else{
return 0.0
}
}
If the number is not nil or invalid such as a few dots, then return the number. If the number is nil or invalid then return 0.0
I want to use regex but I have no idea how to use it in swift. Any help appreciated.
class func regexMatch(source:String,regexStr:String) -> Bool{
let regex: NSRegularExpression?
do{
try regex = NSRegularExpression(
pattern: regexStr,
options: .CaseInsensitive)
}catch{
return false
}
if let matches = regex?.matchesInString(source,
options: NSMatchingOptions(rawValue: 0),
range: NSMakeRange(0, source.characters.count)) {
return matches.count > 0
} else {
return false
}
}
Swift 2
import Foundation
func valueCheck(d: Double) -> Double {
var result = 0.0
do {
let regex = try NSRegularExpression(pattern: "^(?:|0|[1-9]\\d*)(?:\\.\\d*)?$", options: [])
let results = regex.matchesInString(String(d), options:[], range: NSMakeRange(0, String(d).characters.count))
if results.count > 0 {result = d}
} catch let error as NSError {
print("invalid regex: \(error.localizedDescription)")
}
return result
}
Swift 3
import Foundation
func valueCheck(_ d: Double) -> Double {
var result = 0.0
do {
let regex = try RegularExpression(pattern: "^(?:|0|[1-9]\\d*)(?:\\.\\d*)?$", options: [])
let results = regex.matches(in: String(d), options: [], range: NSMakeRange(0, String(d).characters.count))
if results.count > 0 {result = d}
} catch let error as NSError {
print("invalid regex: \(error.localizedDescription)")
}
return result
}

How read text file on server?

I use this code to read a local text file, it's work!
class StreamReader {
let encoding : UInt
let chunkSize : Int
var fileHandle : NSFileHandle!
let buffer : NSMutableData!
let delimData : NSData!
var atEof : Bool = false
init?(path: String, delimiter: String = "\n", encoding : UInt = NSUTF8StringEncoding, chunkSize : Int = 4096) {
self.chunkSize = chunkSize
self.encoding = encoding
if let fileHandle = NSFileHandle(forReadingAtPath: path),
delimData = delimiter.dataUsingEncoding(encoding),
buffer = NSMutableData(capacity: chunkSize)
{
self.fileHandle = fileHandle
self.delimData = delimData
self.buffer = buffer
} else {
self.fileHandle = nil
self.delimData = nil
self.buffer = nil
return nil
}
}
deinit {
self.close()
}
/// Return next line, or nil on EOF.
func nextLine() -> String? {
precondition(fileHandle != nil, "Attempt to read from closed file")
if atEof {
return nil
}
// Read data chunks from file until a line delimiter is found:
var range = buffer.rangeOfData(delimData, options: nil, range: NSMakeRange(0, buffer.length))
while range.location == NSNotFound {
let tmpData = fileHandle.readDataOfLength(chunkSize)
if tmpData.length == 0 {
// EOF or read error.
atEof = true
if buffer.length > 0 {
// Buffer contains last line in file (not terminated by delimiter).
let line = NSString(data: buffer, encoding: encoding)
buffer.length = 0
return line as String?
}
// No more lines.
return nil
}
buffer.appendData(tmpData)
range = buffer.rangeOfData(delimData, options: nil, range: NSMakeRange(0, buffer.length))
}
// Convert complete line (excluding the delimiter) to a string:
let line = NSString(data: buffer.subdataWithRange(NSMakeRange(0, range.location)),
encoding: encoding)
// Remove line (and the delimiter) from the buffer:
buffer.replaceBytesInRange(NSMakeRange(0, range.location + range.length), withBytes: nil, length: 0)
return line as String?
}
/// Start reading from the beginning of file.
func rewind() -> Void {
fileHandle.seekToFileOffset(0)
buffer.length = 0
atEof = false
}
/// Close the underlying file. No reading must be done after calling this method.
func close() -> Void {
fileHandle?.closeFile()
fileHandle = nil
}
}
Usage
var path_up1 = "/Users/rrr/Desktop/up/1.txt"
if let aStreamReader = StreamReader(path: path_up1) {
while let line = aStreamReader.nextLine() {
println(line)
}
}
But I have to read a file on the server (ex: http://www.1111.com/1.txt).
Help me, plz!
You can read the file directly via NSURLConnection
let url = NSURL(string:"http://www.1111.com/1.txt")!
let request = NSURLRequest(URL: url)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.currentQueue()) { (response, data, error) -> Void in
if error != nil {
println(error!)
} else {
if let textFile = NSString(data: data, encoding: NSUTF8StringEncoding) {
println(textFile)
}
}
}
The example assumes that the text file is UTF-8 encoded.
Or if you want to read the data sequentially implement the delegate methods of NSURLConnection and use init?(request:delegate:startImmediately:)

Regular expression to get URL in string swift with Capitalized symbols

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))
}
}

Resources