Swift 1.2 lowercaseString crashes with enumerateSubstringInRange - ios

Just converted my code to Swift 1.2. I'm getting a BAD_EXEC_ACCESS with the below code:
var wordsBeingTyped = NSString()
var lastWord = String()
wordsBeingTyped = proxy.documentContextBeforeInput // Gets the string being typed
let range = NSMakeRange(0, (wordsBeingTyped).length)
wordsBeingTyped.enumerateSubstringsInRange(range, options: NSStringEnumerationOptions.ByWords) { (substring, substringRange, enclosingRange, stop) -> () in
lastWord = substring // The last word in the string wordsBeingTyped
}
let lastWordLowercase = lastWord.lowercaseString
The crash is happening on the last line. For testing purposes I changed that line to:
let lastWordLowercase = wordsBeingTyped.lowercaseString
And it works just fine. The strange thing is it only crashes when I'm typing the first word in a string. After a space character there is no crashing.
Update: The work around I came up with is to make a new let to convert wordsBeingTyped to lowercase before using enumerateSubstringsInRange. So:
let lowercaseWordsBeingTyped = wordsBeingTyped.lowercaseString
// ..enumerate string to get last word typed
let lastWordLowercase = lastWord
Hope that helps someone.

This was a bug in Xcode 6.3 beta 1. It's fixed in Xcode 6.3 beta 2.

Related

Usage of String.range in Swift 3.0

let us = "http://example.com"
let range = us.rangeOfString("(?<=://)[^.]+(?=.com)", options:.RegularExpressionSearch)
if range != nil {
let found = us.substringWithRange(range!)
print("found: \(found)") // found: example
}
This code extracts substring between backslashes and dot com in Swift 2. I searched Internet and I found that rangeOfString changed to range().
But still I could not make the code work in Swift 3.0. Could you help me ?
edit : I'm using swift 3 07-25 build.
In swift 3.0 rangeOfString syntax changed like this.
let us = "http://example.com"
let range = us.range(of:"(?<=://)[^.]+(?=.com)", options:.regularExpression)
if range != nil {
let found = us.substring(with: range!)
print("found: \(found)") // found: example
}
In latest swift 3.0 using Xcode 8 Beta 6 (latest updates to SDK):
let us = "http://example.com"
let range = us.range(of: "(?<=://)[^.]+(?=.com)", options: .regularExpression)
if range != nil {
let found = us.substring(with: range!)
print("found: \(found)") // found: example
}

How to take NSRange in swift?

I am very much new to swift language. I am performing some business logic which needs to take NSRange from given String.
Here is my requirement,
Given Amount = "144.44"
Need NSRange of only cent part i.e. after "."
Is there any API available for doing this?
You can do a regex-based search to find the range:
let str : NSString = "123.45"
let rng : NSRange = str.range("(?<=[.])\\d*$", options: .RegularExpressionSearch)
Regular expression "(?<=[.])\\d*$" means "zero or more digits following a dot character '.' via look-behind, all the way to the end of the string $."
If you want a substring from a given string you can use componentsSeparatedByString
Example :
var number: String = "144.44";
var numberresult= number.componentsSeparatedByString(".")
then you can get components as :
var num1: String = numberresult [0]
var num2: String = numberresult [1]
hope it help !!
Use rangeOfString and substringFromIndex:
let string = "123.45"
if let index = string.rangeOfString(".") {
let cents = string.substringFromIndex(index.endIndex)
print("\(cents)")
}
Another version that uses Swift Ranges, rather than NSRange
Define the function that returns an optional Range:
func centsRangeFromString(str: String) -> Range<String.Index>? {
let characters = str.characters
guard let dotIndex = characters.indexOf(".") else { return nil }
return Range(dotIndex.successor() ..< characters.endIndex)
}
Which you can test with:
let r = centsRangeFromString(str)
// I don't recommend force unwrapping here, but this is just an example.
let cents = str.substringWithRange(r!)

Swift advancedBy can't handle newline character "\r\n" [duplicate]

This question already has answers here:
NSRange to Range<String.Index>
(16 answers)
Closed 7 years ago.
I ran into a very strange problem today with Swift 2.
I have this simple method to extract a substring based on NSRange:
func substringWithRange(string: String, range: NSRange) -> String {
let startIndex = string.startIndex.advancedBy(range.location)
let endIndex = startIndex.advancedBy(range.length)
let substringRange = Range<String.Index>(start: startIndex, end: endIndex)
return string.substringWithRange(substringRange)
}
With ordinary strings or strings containing unicode characters everything works fine. But one string contains the newline characters "\r\n" and suddenly
let startIndex = string.startIndex.advancedBy(range.location)
is always 1 greater than it should be.
let string = "<html>\r\n var info={};</html>"
let range = NSMakeRange(9, 12)
let substring = substringWithRange(string, range: range)
//Expected: var info={};
//Actual: ar info={};<
//string.startIndex = 0
//range.location = 9
//startIndex after advancedBy = 10
Does anyone know why advancedBy is acting that way and how I can solve this problem?
The reason is that Swift treats \r\n as one character
let cr = "\r"
cr.characters.count // 1
let lf = "\n"
lf.characters.count // 1
let crlf = "\r\n"
crlf.characters.count // 1

iOS Swift manipulate/parse string

I'm not sure how to do this in iOS Swift
let test = "fnfsjflsjlkdkfj?v=904kg4"
// search test for ?v= and store everything after ?v= into a new string
let newString = "904kg4"
I want everything after ?v= into a new string, is this possible? if so, how can I accomplish this
Use rangeOfString to find the range of ?v= and then use substringFromIndex to get the rest of the string:
let test = "fnfsjflsjlkdkfj?v=904kg4"
if let range = test.rangeOfString("?v=") {
let newString = test.substringFromIndex(range.endIndex)
}

If let var - Unwrapping optional value

There is some ways to unwrap an optional value:
// 1st way
var str: String? = "Hello, playground"
if let strUnwrapped = str {
// strUnwrapped is immutable
println(strUnwrapped)
}
// 2nd way
var str: String? = "Hello, playground"
if var strUnwrapped = str {
// strUnwrapped is mutable
strUnwrapped = "Toldino"
println(strUnwrapped)
}
But I recently test this following one...
// The strangest one
var str: String? = "Hello, playground"
if let var strUnwrapped = str {
// strUnwrapped is mutabe
strUnwrapped = "yolo"
println(strUnwrapped)
}
Can you explain me why does it work ?
It is a bug or a functionality ?
EDIT
As niñoscript said, it was a bug.
It is resolved in Swift 2.0, I tried it with the new version and it doesn't compile anymore.
Now Xcode throw this following error for "if let var"
This answer is only valid for Xcode 6, the bug was fixed in Xcode 7 as noted by the OP's edit and Paul Jarysta's answer
In this case:
if let var strUnwrapped = str {}
let var works the same way as just var, so either it is a bug or it's just the same thing. But if you try the following simple code:
let var n = 3
It throws this error:
'var' cannot appear nested inside another 'var' or 'let' pattern
So we can safely assume that it is a bug. We should be good developers and report it!
This problem was solved in xcode 7 ;-)

Resources