2
votes

I get no errors or anything, but when I run the app it crashes. The log I get is "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MPConcreteMediaItem imageWithSize:]: unrecognized selector sent to instance 0x14eefa3b0'".

I think the line that causes this problem is this one:

cell?.imageView?.image = sortedResults[indexPath.row].imageWithSize(imageSize)

because when I delete it/uncomment it, everything works fine.

imageSizeis a CGSize var.

The whole Code:

let startTime: NSTimeInterval = NSDate().timeIntervalSince1970
    let songsQuery: MPMediaQuery = MPMediaQuery.songsQuery()
    let songsArray: [MPMediaItem] = songsQuery.items!
    let songsNSArray : NSArray = NSArray(array: songsArray)

    let descriptor: NSSortDescriptor = NSSortDescriptor(key: MPMediaItemPropertyLastPlayedDate, ascending: false)
    let sortedResults: NSArray = songsNSArray.sortedArrayUsingDescriptors([descriptor])


    let finishTime: NSTimeInterval = NSDate().timeIntervalSince1970
    NSLog("Execution took %f seconds to return %i results.", finishTime - startTime, sortedResults.count)




    cell?.textLabel?.text = sortedResults[indexPath.row].title
    cell?.detailTextLabel?.text = sortedResults[indexPath.row].artist
    cell?.imageView?.image = sortedResults[indexPath.row].imageWithSize(imageSize)
2
Could you show the whole error message? - Larme
Post the full error, you're missing the integral part that answers your question. But chances are the object returned from sortedResults[indexPath.row] does not have a method imageWithSize(imageSize: CGSize) implemented. - Tim
Check my updated question - J.Vongehr
You have declared that your array contains MPMediaItem objects. Why do you think one of those has an imageWithSize function? - Phillip Mills
And that's why you shouldn't use NSArray in Swift. - Sulthan

2 Answers

2
votes

You have added an object to your sortedResults NSArray that isn't the type you are expecting. So when you call imageWithSize(imageSize: CGSize) on that object the app crashes as the object doesn't respond to that selector (implement that method).

MPMediaItem does not implement this method. Seems that you want to access the constant values on MPMediaItem?

General Media Item Property

Something like this may help:

if let mediaItem: MPMediaItem = sortedResults[indexPath.row] as? MPMediaItem {
    cell?.textLabel?.text = mediaItem.valueForProperty(MPMediaItemPropertyAlbumTitle) as? String
    cell?.detailTextLabel?.text = mediaItem.valueForProperty(MPMediaItemPropertyAlbumArtist) as? String

    if let artwork: MPMediaItemArtwork = mediaItem.valueForProperty(MPMediaItemPropertyArtwork) as? MPMediaItemArtwork {
        cell?.imageView?.image = artwork.imageWithSize(imageSize)
    }
}

Long term, I'd recommend implementing one of the sorting methods on a Swift array rather than hard converting to an NSArray to sort using a descriptor - this bug would have been caught at compile time instead. Haven't checked, but something like this to keep things in Swift:

songsArray.sort { (itemOne, itemTwo) -> Bool in
    return itemOne.lastPlayedDate?.laterDate(itemTwo.lastPlayedDate!) == itemOne.lastPlayedDate
}
3
votes

I'm guessing object located in sortedResults[indexPath.row] is not what you think it is, and hence it has not got the method imageWithSize(). Object may be nil?

EDIT

To be safe, you could do something like this before using the object in the array:

if let validObject = sortedResults[indexPath.row] as MPConcreteMediaItem? {
   // Can now use validObject safely, since we have checked that it is in fact an instance of MPConcreteMediaItem
}