Swift 4: 'init(_offset:)' is unavailable - swift4

Swift 4 : 'init(_offset:)' is unavailable
I am trying to expand variable names (enclosed by curly braces).
let message = "Hello {what}".expand(["what" : "world"])
print(message) // Hello World
I used this for dynamic URL construction.
Up to Swift 3.2, it was working fine. When I tried to convert it to Swift 4, it's throwing the error mentioned above for this line:
let templateStartChar = "{".utf16[String.UTF16View.Index(_offset: 0)]

If anyone is stuck with this, below is the solution :
In place of _offset I use encodedOffset
let templateStartChar = "{".utf16[String.UTF16View.Index(encodedOffset: 0)]

Related

How do you format floats into strings in Swift 5?

I am trying to format a float into a string with a set number of digits. All the examples I have seen use something like this:
let thisString = String(format: "%2.4f" , 3.14159262)
However, when I try this I get:
Argument labels '(format:, _:)' do not match any available overloads
. Like it doesn't even recognize "format" as a valid way to initialize a string. I am using Swift 5 on Xcode 10.2 on Mojave, if that makes a difference. Am I missing some framework or something? Did the initializer change?
Your code should be working correctly. Can you please try the following:
import Foundation
let firstString = String(format: "%2.4f", arguments: [3.14159262])
print(firstString)
let secondString = String(format: "%2.4f", 3.14159262)
print(secondString)
I have this code running fine in a playground using Swift 5.
Removing the Foundation import gives the same error you described in your question.

Converting Swift 2.0 to Swift 3.0

I am currently writing a iOS App using AWS Mobile Hub and the AWS services. I'm in the middle of implementing API Gateway into my app after connecting it with an AWS Lambda function. After doing all that, AWS generated an SDK for me to implement into my project but the problem is, is that the code is in Swift 2.0. I am trying to convert it into Swift 3.0 but I have no idea what this code is supposed to do/trying to do, so I don't know how to convert it.
My question is, how do I convert this line into Swift 3.0?
var URLString: String = "https://XXXXX.execute-api.XXXX.amazonaws.com/prod"
if URLString.hasSuffix("/") {
URLString = URLString.substringToIndex(URLString.startIndex.advancedBy(URLString.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) - 1))
}
The problem is the line of code in the "if" statement.
Thank you.
Swift 3 version:
var URLString: String = "https://XXXXX.execute-api.XXXX.amazonaws.com/prod"
if URLString.hasSuffix("/") {
let index = URLString.index(URLString.startIndex, offsetBy: (URLString.characters.count - 1))
URLString = URLString.substring(to: index)
}
Please use camelcase starting from small letter with naming your variables within Swift. More convenient way:
var urlString: String = "https://XXXXX.execute-api.XXXX.amazonaws.com/prod"
if urlString.hasSuffix("/") {
urlString = String(urlString.characters.dropLast())
}

Xcode 8.0 and Swift 3.0 conversion: Looking for explanation for a particular conversion error

I am a little confused about a conversion error.
I migrated my project form Swift 2.3 to Swift 3.0
func updateCelsiusLabel() {
if let value = celsiusValue {
//This was the original code (that worked but is) failing after migration
//due to: Argument labels do not match any available overloads
celsiusLabel.text = numberFormatter.string(from: NSNumber(value))
//This is my code trying to fix this issue and the project is now compiling
//and everything is fine
celsiusLabel.text = numberFormatter.string(from: value as NSNumber)
}
else { celsiusLabel.text = "???"
}
}
At first I thought that in Swift 3.0 the cast Type(value) was now forbidden, but I checked and I get absolutely no compiler warning. Can somebody tell me what the problem with NSNumber(value) is?
As far as I understand value as NSNumber and NSNumber(value) should be the same thing.
In Swift 3, NSNumber(value) won't work. Let's say that your value is an Int. In that case, you'd need NSNUmber(value: yourIntValue). In Swift 3, you must have the name of the first (and in this case the only) parameter in the function call. So, your usage of
value as NSNumber
works, but
NSNumber(value: yourNumberValue)
works too.
First of all I have taken some assumption here, I have assumed that -
numberFormatter = NSNumberFormatter() // Now it has been renamed to NumberFormatter
celsiusLabel.text I am taking text as optional string just for example you can use label.text for same.
After the above assumption please see below code which will work in Swift 3 -
var celsiusValue:Double?
var numberFormatter = NumberFormatter()
var text:String?
func updateCelsiusLabel() {
if let value = celsiusValue {
//This was the original code (that worked but is) failing after migration due to: Argument labels do not match any available overloads
text = numberFormatter.string(from: NSNumber(value: value))!
}
else {
text = "???"
}
}
Hope it help feel free to leave comment in case you have any doubt.

Swift 2 #convention use error

I have a problem with Swift 2, I'm not able to convert this part of my code:
let intTran = UnsafeMutablePointer<Int>(bitPattern: -1)
let tranPointer = COpaquePointer(intTran)
let transient = CFunctionPointer<((UnsafeMutablePointer<()>) -> Void)>(tranPointer)
I receive this error:
'CFunctionPointer' is unavailable: use a function type '#convention(c) (T) -> U'
I am trying to change it for this way:
let intTran = UnsafeMutablePointer<Int>(bitPattern: -1)
let tranPointer = COpaquePointer(intTran)
typealias transient2 = #convention(c) (UnsafeMutablePointer<()>) -> Void
But I am not able to use transient2 and I am not sure why.
Than you
I have been playing around with your code inside a Swift playground and noticed that this piece of code (your substitution to the original one) fails due to the bitPattern when it's set to -1 (notice that I've been getting a runtime exception - not a compiler error). When I replaced it with something appropriate (e.g. with 1, as bitPattern must represent a valid address inside you virtual address space and, as implied, must be a non-negative integer) it worked out. I managed to make it up and running with the following code:
import Foundation
let intTran = UnsafeMutablePointer<Int>(bitPattern: 1)
let tranPointer = COpaquePointer(intTran)
typealias transient2 = #convention(c) (UnsafeMutablePointer<()>) -> Void
let abc: transient2? = nil
Good luck, hope this solves your problem.

Why is this guard statement throwing me an error?

So I'm following a tutorial form Lynda.com for making a iOS app with Swift and when I plug this line of code in, it's throwing me errors:
guard let text:String = addressBar.text else
The error I get is:
Consecutive statements on line must be separated by ';'
Once I have Xcode fix it, these are the errors I get:
Expected expression.
Use of unresolved identifier 'guard'.
Expression resolves to an unused function.
Braced block of statements is an unused closure.
I'm really new to Xcode and Swift so any help would be awesome! Thanks!
Because you using outdated xcode and swift language. Latest version is xcode 7 and swift 2.
https://developer.apple.com/xcode/
May be you are using a wrong version of Xcode(version 7.0)
Try it too:
Be certain you are using guard statement in the right conditions. E.g:
class AddressBar {
var text: String? = ""
}
var addressBar = AddressBar()
addressBar.text = nil
//addressBar.text = "text"
func test() {
guard let _text: String = addressBar.text else {
print("Nothing")
return
}
print("I reach this point")
}
test()