Error after converting to Swift 3.0 - ios

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

Related

Swift Struct unable to set array elements above 0

I have following Swift struct:
struct MainStruct : Decodable{
var array : [InternalArray]?
}
struct InternalArray : Decodable{
var firstName : String?
var lastName : String?
var Number : Int?
}
And this is how I'm using it:
var testing: MainStruct? = MainStruct()
testing?.array = []
testing?.array!.append(InternalArray())
testing?.array![0].firstName = "TEST"
testing?.array![1].firstName = "TEST 1" - error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION
It seems to work fine when I'm setting array element [0] but when I try to set element [1] I get an error. Maybe somebody know what is wrong with my implementation ?
The problem is you only have 1 item (index 0).
Let's unpack this, first we unwrap your option MainStruct in the testing variable, and unwrap the optional array:
if let unwrappedTestingMainStruct = testing,
let unwrappedArray = unwrappedTestingMainStruct.array {
unwrappedArray.count // = 1
}
You then try to access testing?.array![1] which would be the second item in the array… which doesn't exist.
If you just had the line:
testing?.array![1]
you would see the same error

Swift, EXC_BAD_Instruction

My program should fitch the data from an array, and put it in a tableView
var rideTime: String!
var rideLocation: String!
var RideDriver: String!
rideTime = RidestList[indexPath.row].TimeX!
rideLocation = RidestList[indexPath.row].LocationX!
RideDriver = RidestList[indexPath.row].DriverNameX!
cell.DriverX.text = rideTime;
cell.TimeX.text = rideLocation;
cell.LocationX.text = RideDriver;
return cell
In the cell.DriverX.text=rideTime it gives me EXC_BAD_Instraction
And a "atal error: unexpectedly found nil while unwrapping an Optional value
(lldb) " error appears, can anyone help?
if let ride_time = RidestList[indexPath.row].TimeX
{
cell.DriverX.text = ride_time
}
if let ride_location =RidestList[indexPath.row].LocationX
{
cell.TimeX.text = ride_location
}
if let river_driver =RidestList[indexPath.row].DriverNameX
{
cell.LocationX.text = river_driver
}
this could help you with your problem
The crash is basically due to no value coming to your variable rideTime. Best practice is use of optional binding var rideTime: String? to the variables which can expect null values. This will restrict the crash that you faced.

Multidimensional Array Unwrapping an Optional

so I'm having this problem where I can't unwrap an optional for outputting it into the label, I've even tried just printing it in the console and it still gives me an optional
The code and array are in different files.
Code It's in a VC:
for var i = 0; i < stateName.count; i++ {
if tax.state == stateName[i][0] {
stateName[i][1] = Double(taxNumb.text!)!
print(stateName[i][1])
output.text = String(stateName[i][1])
}
}
Array Code I made this in an empty swift file:
var tax : Taxes? = nil
var stateName = [
["AK - Alaska", tax?.alaska!],
["AL - Alabama", tax?.alabama!],
["AR - Arkansas", tax?.arkansas!],
["AZ - Arizona", tax?.arizona!],
["CA - California", tax?.california!]
]
As I wrote in my comment to your previous question use the "Nil Coalescing" ?? operator:
output.text = String(stateName[i][1] ?? "not set")
Or using the alternate swift String magic
output.text = "\(stateName[i][1] ?? "not set")"
The operator returns the first value if it not nil, otherwise it returns the second value.

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

BAD_INSTRUCTION within swift closure

func loadMe() -> Void {
println(me.initUrl());
let url:NSURL = NSURL(string:me.initUrl())
let request:NSURLRequest = NSURLRequest(URL:url)
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request, queue:queue, completionHandler:{response, data, error in
if data {
var jerr:NSError?
var json:NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error:&jerr) as NSDictionary
if !jerr {
println(json.description)
let time:String = json.valueForKey("time") as String
println(time)
// self.me.setDictionary(json)
}
}
})
}
The code above works fine up to the point where i want to assign a value from an NSDictionary to a variable.
let time:String = json.valueForKey("time") as String
is followed by EXC_BAD_INSTRUCTION(code=EXC_I386_INVOP,subcode=0x0) but
println(json.description)
prints out a valid NSDictionary. Does anybody know a solution to this problem?
The valueForKey() method returns an optional value; you are forcing that value to a String and apparently that is causing the crash. I can get the Swift REPL to crash with:
1> var json = ["a": "1", "b": "2"]
json: Dictionary<String, String> = {
[0] = {
key = "a"
value = "1"
}
[1] = {
key = "b"
value = "2"
}
}
2> let data:String = json["b"] as String
Bitcast requires both operands to be pointer or neither
%58 = bitcast i8* %57 to %SS.232
Bitcast requires both operands to be pointer or neither
%110 = bitcast i8* %109 to %SS.232
Stored value type does not match pointer operand type!
store %SS.232 %110, i8** %.core7._baseAddress.value, align 8
i8*LLVM ERROR: Broken function found, compilation aborted!
Assertion failed: (err == 0), function ~Mutex, file /SourceCache/lldb_KLONDIKE/lldb_KLONDIKE-320.3.100/source/Host/common/Mutex.cpp, line 246.
Abort trap: 6
The solution is to forgo the String coercion. In my example:
2> let data:String? = json["b"]
data: String? = "2"
3> let data:String? = json["c"]
data: String? = nil
I suspect you added the 'as String' 1) knowing that the value is actually a String and 2) to avoid a compiler error. The proper approach is to use ? to indicate an optional value.
I solved my problem with casting to the correct type of the original NSDictionary value after i realised that not all values of the NSDictionary were NSStrings. If your service returns a mixed type JSON object like this
{"id":2, "name":"AC Vent Temp", ...}
you'll have to fetch it's values like that.
var id:int = sensor.valueForKey("id") as Int;
var name:String? = sensor.valueForKey("name") as String;

Resources