Found nil while unwrapping an Optional value (Music Library) - arrays

var songList = NSMutableArray()
var player = AVPlayer()
var isSelected = false
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var songs = MPMediaQuery() // also tried var songs = MPMediaQuery.songsQuery()
var localSongs: NSArray = songs.items
songList = NSMutableArray(array: localSongs)
tableView.reloadData()
var song: MPMediaItem = songList[0] as MPMediaItem // <<- Error here
var currentItem = AVPlayerItem(URL: song.valueForProperty(MPMediaItemPropertyAssetURL) as NSURL)
player.replaceCurrentItemWithPlayerItem(currentItem)
player.play()
var songTitle: NSString = song.valueForProperty(MPMediaItemPropertyTitle) as NSString
songName.text = songTitle
var time = Float(CMTimeGetSeconds(player.currentItem.duration))
sliderOutlet.value = time
}
I'm building a music player, but the app crasher when i run in the simulator and gives this error: index 0 beyond bounds for empty array, and says this when i try run on iPhone : {
MediaLibrary} Database validation succeeded
fatal error: unexpectedly found nil while unwrapping an Optional value
EDIT: Seems like it's not accessing the local music library on my iPhone and adding songs to the array.

You're accessing an element without testing its size. So songList[0] is out of bounds, hence the crash.

If your media query returns no items, then localSongs and songlist will both be arrays of size 0. When you then try to reference a song with songList[0] you will be accessing index 0 in an empty array. Hence the crash.

Seems more like a problem with expecting the simulator to have music in it. Since it doesn't, songList.count == 0, which means songList[0] should generate an exception. Seems like the expected and desired behavior to me.

Put a check on count using if condition. You are accessing index which can be nil. If accessed it will through runtime error.
Preferred approach would it be wrapped explicitly with ?

Related

godot invalid get index '-1'(on base 'array') during A.P.I

I'm making an A.P.I. that displays dialogue, choices, sprites, audio etc. etc., i was able to do it after looking up this video on youtube but i keep getting this error invalid get '-1' (on base 'array') here's my code so you can see
extends Control
onready var bg_rect = get_node("Media_Sys/BG_Rect")
onready var char_sprite = get_node("Media_Sys/Sprite")
onready var text_box = get_node("Dialog_Sys/Dialog_Text")
onready var text_nam = get_node("Dialog_Sys/Label/Name")
onready var click = get_node("ClickManager")
var player = []
var lu = "Lu"
var ciel = "Ciel"
func _ready():
click.request_ready()
func write(char_name_str, text_str=null):
if text_str == null:
text_str = char_name_str
char_name_str = ""
player.push_front({"type": "dialogue","name": char_name_str, "text": text_str})
func write_component():
text_nam.clear()
text_box.clear()
text_nam.add_text(player[player.size() - 1]["name"])#the debugger says the problem is here
text_box.add_text(player[player.size() - 1]["text"])#as well as here if you remove the first line.
player.pop_back()
func _input(event):
if event is InputEventMouseButton:
write_component()
I have some people say that it's because i didn't define the size of the array, i have some people say that it's really weird that my code somehow set the player as an integer. I've check the array docs page for this and came up with nothing, I've changed some minor things in the code but it still churns out the same invalid error.
extends Node
onready var g = get_parent()
var lu = "Lu"
var ciel = "Ciel"
func _ready():
g.write(lu, "hello")
One thing to note is that it does display the dialogue and name, i just get the error immediantly afterwards.
You initialize the player variable to be an empty list. Then, in write_component you attempt to access this list with the calculated index [player.size() - 1]. The issue is that if player is empty, this ends up as [0-1] or [-1] as an index, which is not valid in GDScript. Your code assumes Write will be called first (and it may, some of the time) so that player is not empty by the time write_component is called.
The most immediate solution is to check if player.size() == 0 before attempting to access the last element.
func write_component():
text_nam.clear()
text_box.clear()
if player.size() > 0:
text_nam.add_text(player[player.size() - 1]["name"])
text_box.add_text(player[player.size() - 1]["text"])
player.pop_back()

Simple swift array append not working

I know this is going to be super elementary, but I have this piece of code:
var labels: [String]?
func initVC(image: Images){
self.image = image
let tempLabels = image.label?.allObjects as! [Labels]
for i in 0..<tempLabels.count{
labels?.append(tempLabels[i].label!)
}
}
labels is in the public scope, so the function should have access to it, but when the loop runs through, labels is still nil with no elements.
When I po during debugging, tempLabels is as I expect it to be with 2 string elements.
I'm pretty sure this is a very simple problem, but I guess I'm just out of it right now.
Labels has never been initialised. Change
var labels:[String]?
to
var labels:[String] = []
You are declaring the labels variable but never allowing it to store information. This means that it does not necessarily exist, since it is not initialized, and therefore cannot be used.
For it to be useable, you must initialize it
var labels:[String] = []
Yep, it was super simple.
Changed
var labels: [String]?
To
var labels = [String]()

circular reference using weak variables causing the unwrapping of nils

let me start off by saying I searched to find a topic that would help me but I could not anything that helped. Here is my situation...
I created a class sign where I created the variable thing1. I then created an array called arrayX that uses sign. Then I used a NSURL session to pull values from a domain. I then created thingX that will hold that value and finally I appended my arrayX with that value of thingX. This works GREAT except that it appears i have strong circular references and the memory cannot be deallocated. I tried fixing it with weak references but then the occasional empty thingX causes my app to crash because it is trying to unwrap a nil. Please help!!!
class sign {
var thing1 = ""
init(thing1: String) {
self.thing1 = thing1
}
}
var arrayX : [sign] = [sign]()
index1 = 0
while index1 < count {
//NSURL will grab info info will grab a value from my domain and thingX will be given this value (occasionally the value will be empty)
let thingX = ‘NSURL value’ as! String
let data1 = sign(thing1: thingX)
self.arrayX.append(data1)
index1++
}

Swift addObject

So, I'm learning how to get data from DB with JSON and then put the data on some array. Problem accours on last line, citiesArray.addObject(City()), when I need to put all data from object city (id, name, state,...) into array.
I was looking line by line with compiler, and basically everything is fine except that at the end, my array is still empty (its value is nil)?
for (var i=0;i<jsonArray.count;i++){
//Create city objec
var cID: AnyObject? = jsonArray.objectAtIndex(i).objectForKey("id") as NSString
var cName: AnyObject? = jsonArray.objectAtIndex(i).objectForKey("cityName") as NSString
var cState: AnyObject? = jsonArray.objectAtIndex(i).objectForKey("cityState") as NSString
var cPopulation: AnyObject? = jsonArray.objectAtIndex(i).objectForKey("cityPopulation") as NSString
var cCountry: AnyObject? = jsonArray.objectAtIndex(i).objectForKey("country") as NSString
//add city obj (i have City class) to city array
var city = City()
city.cityID = cID as NSString
city.cityName = cName as NSString
city.cityState = cState as NSString
city.cityPopulation = cPopulation as NSString
city.cityCountry = cCountry as NSString
citiesArray.addObject(City())
}
A couple of issues:
You suggested that you were trying to add the city with the following line of code:
citiesArray.addObject(City())
The City() construct will instantiate a new, blank City object. So that line of code would, best case scenario, add a blank City object to your array, which is not what you intended.
When you add the city to your citiesArray, you should simply:
citiesArray.addObject(city)
You say you've defined your citiesArray like so:
var citiesArray: NSMutableArray!
You also need to instantiate an object for this variable (i.e. create an object to which this variable will now point), e.g.:
citiesArray = NSMutableArray()
You are reporting, though, that at the end of this loop, that citiesArray is nil. Really?!? But if you tried to call the addObject method and citiesArray was nil, you could have received a fatal error: "unexpectedly found nil while unwrapping an Optional value".
So, if citiesArray was nil, then jsonArray must have been empty, too. Or for some reason you didn't even get to this loop. I would suggest (a) logging jsonArray; and (b) log or put breakpoint inside this loop and confirm you're even getting in here like you think you are.
Also, check the timing of this (i.e. make sure your statement logging citiesArray is actually taking place after this routine that populates it). I know that sounds crazy, but if you are retrieving the data from some network resource asynchronously, you could have some timing related issues.
Since you're writing Swift code, you might consider using Swift arrays. For example, define your array variable as
var citiesArray: [City]!
And instantiate it with:
citiesArray = [City]()
And add objects to it with:
citiesArray.append(city)
I am pretty sure you need to use the append function:
citiesArray.append(city)
or
if you want to append at the start of the array
citiesArray.insert(city, atIndex: 0)
instead of
citiesArray.addObject(City())
here is a little example: Syntax might not be 100% not on comp with xcode right now.
var strA:String = "apple"
var strB:String = "pineapple"
var strArr = ["kiwi", "mango", "lime"]
strArr.append(strA)
println(strArr.count) //4 ["kiwi", "mango", "lime", "apple"]
citiesArray.insert(strB, atIndex: 0)
println(strArr.count) //5 ["pineapple", "kiwi", "mango", "lime", "apple"]

swift setting string from array element error

So im grabbing a property from core data, using a dictionary. And it grabs it just fine. However, when I try to take that single returned attribute and assign it to the navigationitem.title it throws some nasty error. Am I missing something here..
Its not actually outputting an error message in the console but instead is giving me this:
Thread 1: EXC_BREAKPOINT(code+exc_I386_BPT.....
on this line.
0x10707a5f3: nopw %cs:(%rax,%rax)
Also its saying
0 swift_dynamicCastObjCClassUnconditional
code:
override func viewDidLoad() {
super.viewDidLoad()
let appDel:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
let context:NSManagedObjectContext = appDel.managedObjectContext
let frequest = NSFetchRequest(entityName: "Round")
frequest.propertiesToFetch = NSArray(object: "course")
frequest.returnsObjectsAsFaults = false
frequest.returnsDistinctResults = true
frequest.resultType = NSFetchRequestResultType.DictionaryResultType
var fetchedArray = context.executeFetchRequest(frequest, error: nil)
//this is the line that throw the error...why won't it let me set the title to the array of the single returned result?
self.navigationItem.title = fetchedArray[0]
println(fetchedArray)
}
Without a specific error message you are receiving, this is just a guess...
NSArray un untyped contents (that is to say that elements are of type AnyObject), so the compiler probably doesn't think you can set AyObject as a string. So likely need something like:
self.navigationItem.title = fetchedArray[0] as String
Or:
self.navigationItem.title = String(fetchedArray[0])
To start, I would check couple of things to see if the problem is in the fetched array or in the navigation item:
what exactly is returned in fetchedArray[0]? Is is a string? A nil? Something else? Does it actually have anything at index 0? After checking if fetchedArray is not nil and has any elements, you could use "\(fetchedArray[0])"
What is the state of navigationItem? Is it actually instantiated at the time you are trying to set it's title property? I would suggest checking it for nil. You can also try assigning it a string like this: self.navigationItem.title = "Hello" and see if it fails.

Resources