If let var - Unwrapping optional value - ios

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

Related

Copy string value to another string?

var phoneUDID: String?
var temporaryUDID: String?
var customUDID: String?
let md5Data = MD5(string: UIDevice.current.identifierForVendor!.uuidString)
let md5Hex = md5Data.map { String(format: "%02hhx", $0) }.joined()
self.phoneUDID = md5Hex
self.temporaryUDID = (md5Hex + "#gmail.com")
self.customUDID = self.temporaryUDID
Information: I am using Swift 3 by the way!
Question: Is the self.customUDID = self.temporaryUDID line correct to use? Since they are both strings, is this a safe way of copying a string's value to another string? I submitted my app to the app store and saw this booboo and thought that errors could arise. Please convince me i'm safe. Thanks
String is a value type in Swift. So no, if you change one, the other won't change.
When you do
self.customUDID = self.temporaryUDID
A new string is created and stored in customUDID.
Example:
var s1 = "Foo"
var s2 = s1
s1 = "Bar"
print(s1,s2) //Prints "Bar Foo"

Swift String operation not working

I am trying to read the string from a Label and remove the last character form it.
This is how I am trying:
#IBAction func del(sender: UIButton) {
let str = telephone.text!;
let newstr = str.remove(at: str.index(before: str.endIndex))
telephone.text = newstr;
}
When I run, I get an error:
"String" does not have a member named "remove"
Can someone help me figure out the problem?
Just started learning swift :(
remove(at:) mutates the receiver which must therefore be a variable
string:
var str = telephone.text!
str.remove(at: str.index(before: str.endIndex))
telephone.text = str
Alternatively use substring(to:), which returns the new string
instead of modifying the receiver:
let str = telephone.text!
let newstr = str.substring(to: str.index(before: str.endIndex))
telephone.text = newstr
remove is defined as follows:
public mutating func remove(at i: String.Index) -> Character
See the mutating modifier? That means it mutates the instance on which the method is called. In your case, the instance is str, a constant. Since constants cannot be mutated, the code does not compile.
And since remove returns the removed character,
let newstr = str.remove(at: str.index(before: str.endIndex))
here newstr will not be storing the string with the last character removed.
You should rewrite the method like this:
telephone.text!.remove(at: telephone.text!.index(before: telephone.text!.endIndex))
You can use:
let idx = str.index(before: str.endIndex) // compute the index
let s = str.substring(to: idx) // get the substring

Error after converting to Swift 3.0

After I converted my project to Swift 3.0, I find error in log from variable:
var arrayOfHours = stringArray.map {String(describing: $0!.characters.prefix(2))}
Error is:
code of error: "Optional(Swift.String.CharacterView(_core: Swift._StringCore(_baseAddress: Optional(0x000060800024ee70), _countAndFlags: 2, _owner: Optional(Swift._HeapBufferStorage<Swift._StringBufferIVars,
Swift.UInt16>))))"
where is my error occuring?
Update:
var stringArray in console: [Optional("1226"), Optional("1249"), Optional("1312"), Optional("1336"), Optional("1359"), Optional("1422"), Optional("1446"), Optional("1509"), Optional("1532"), Optional("1549"), Optional("1607"), Optional("1624"), Optional("1642"), Optional("1659"), Optional("1717"), Optional("1734"), Optional("1752"), Optional("1809"), Optional("1827"), Optional("1844"), Optional("1902"), Optional("1919"), Optional("1954"), Optional("2032"), Optional("2107"), Optional("2142"), Optional("2217"), Optional("2252"), Optional("2327"), Optional("2402"), Optional("2437"), Optional("2512")]
var stringArray: [String?] = ["1226", "1249"]
print(stringArray) // [Optional("1226"), Optional("1249")]
var arrayOfHours = stringArray.map { String($0!.characters.prefix(2)) }
print(arrayOfHours) // ["12", "12"]
Well its giving you an Optional of the String casting because String() will return nil if it found something else rather than a String, So what you'll have to do is unwrap that as in :
stringArray.map {String(describing: $0!.characters.prefix(2))!}
Just added an force unwrap ! to the String() result

I have created one string extension to join string with space in swift 2.0 but its not working in swift 2.1 xcode 7

I am new in swift 2.1 , i have created one extension for string and function name is join, When i converted the code from swift 2.0 to swift 2.1 my code return me error
please help me , i am not able to understand what to do
This is extension
extension String {
func join<S : SequenceType where S.Generator.Element : Printable>(elements: S) -> String {
return self.join(map(elements){ $0.description })
}
}
Here is I am using like this
var channel_string:String!
var languages = [String]()
for var i = 0 ; i < ary_selected_channel.count ; i++
{
let getString_setvalue = ary_selected_channel.objectAtIndex(i) as! String
languages.append(getString_setvalue)
}
channel_string = " ".join(languages)
The output is look like , assume In array i have Three name ["one","two","three"]
then output is
channel_string = "one two three"
The error is
1) Printable has been renamed to customstringconv
2) Type of expression is ambiguous without more context
the error you receive is self-explanatory. by the way, there is easy to do the same without any complication ...
let arr = ["one","two","three"]
let str = arr.joined(separator: " ") // "one two three"

How to cast from string to int

I am trying to get the string from " src".."data-lazy-" in variable str, and it's work when i hard code it...
var str = "<h1 style=\"font-family: Helvetica\">Hello Pizza</h1><p>Tap the buttons above to see <strong>some cool stuff</strong> with <code>UIWebView</code><p><img src=\"https://apppie.files.wordpress.com/2014/09/photo-sep-14-7-40-59-pm_small1.jpg\" data-lazy-src=\"xxxxxxx\">"
str.rangeOfString(" src")?.startIndex
str.rangeOfString("data-lazy-")?.endIndex
let myNSString = str as NSString
myNSString.substringWithRange(NSRange(location: 150, length: 245-150))
Result: src=\"https://apppie.files.wordpress.com/2014/09/photo-sep-14-7-40-59-pm_small1.jpg\" data-lazy-
Here, i'm trying not to hard code it...
var str = "<h1 style=\"font-family: Helvetica\">Hello Pizza</h1><p>Tap the buttons above to see <strong>some cool stuff</strong> with <code>UIWebView</code><p><img src=\"https://apppie.files.wordpress.com/2014/09/photo-sep-14-7-40-59-pm_small1.jpg\" data-lazy-src=\"xxxxxxx\">"
str.rangeOfString(" src")?.startIndex
str.rangeOfString("data-lazy-")?.endIndex
let myNSString = str as NSString
let start = str.startIndex.toInt()
let end = str.endIndex.toInt()
myNSString.substringWithRange(NSRange(location: start, length: end - start))
The code above show error message 'String.index' does not have a member named 'toInt'
My question is how could i solve this problem?
Sorry, i am a fairly new to swift programming language.
Casting is not the problem.
The method substringWithRange() accepts an argument of Range - a Swift range - and a Range can be created with arguments of type String.Index. Thus use:
// I'm ignoring optionals; this code is unsafe and thus only an example
let beg = str.rangeOfString(" src")!
let end = str.rangeOfString("data-lazy-")!
str.substringWithRange(Range(start: beg.endIndex, end: end.startIndex))
Specifically:
15> var str = "abc src=def xyz"
str: String = "abc src=def xyz"
16> var si = str.rangeOfString("src=")!
si: Range<String.Index> = { ... }
17> var ei = str.rangeOfString(" xyz")!
ei: Range<String.Index> = { ... }
18> str.substringWithRange(Range (start: si.endIndex, end: ei.startIndex))
$R3: String = "def"
Don't be confused by the word 'Index' in 'String.Index' - this is not like 'i' in s[i]. A String.Index is an opaque data type; it behaves more like a pointer (in a C-like language). A String.Index has lots to account for in the Unicode world of Swift strings.

Resources