Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialMikhail Damiani
Courses Plus Student 4,175 PointsSwift Dynamic Cast Failed
Getting a runtime error "Swift dynamic cast failed"
It seems to be happening after clicking the main navigation image on this line on the PlaylistMasterController:
let playlistImageView = sender!.view as UIImageView
Has anyone else encountered this?
Richard Price
2,050 Pointsyup same here cannot progress and its so FRUSTRATING
13 Answers
Pasan Premaratne
Treehouse TeacherYour tap gesture recognizers need to be added to the image views and not the main view. If you select a gesture recognizer in the document outline and check the connections in the Connections inspector (in the utilities panel), under referencing outlet collections it should show that the "gestureRecognizers" is connected to "placeholder". Placeholder is my image name in this example.
What I'm guessing is happening is that you added the gesture recognizer to the view instead of the image view and when you reference sender.view it doesn't return an image view making your cast fail.
As an aside, my name is "Pasan" and you need to tag me using the @+name function of the forum to bring a post to my attention. There are over a hundred posts per day and I simply can't get to each one unless tagged.
kaitlanlang
3,042 PointsI think for many of us your guess is correct, with great respect, for many of us to all make similar time consuming error (not withstanding errors are good for learning) it says something about demonstrating technique and the visual ambiguaty to the unitiated, technique shouldn't assume what is clearly obvious to the educated as may not be to others. I felt until I read this I duplicated your demonstration to the nth degree when clearly I did not, even after reviewing back as far as that video. If instructors catered for the lowest common denominator ( me for example) we'd all be nailing this with less frustration and less forum posts would be posted to annoy you with. Rant over. Was still a good learning experience. Good to know about the @+name too, was unaware. :)
Pasan Premaratne
Treehouse TeacherCertainly not annoyed and happy to help fix bugs. I think there's a slight misconception here about software development and getting your code to work like this. Debugging isn't something that disappears as you get better at programming. In fact, as you write more complex code, your bugs may be even harder to spot and the learning process here is figuring out how to resolve those issues yourself.
Programmers spend more time reasoning about how their code works and debugging existing code than writing any new code. Trying things out to the nth degree, as you say, is a big part of this. When it comes to course creation we can't always show the possible ways it could go wrong - simply because the course would be hours longer than it already is. For the one error that you encountered (that this post solves) there are lots of other errors that could occur with this one specific line of code.
We try and maintain that balance although it's often difficult to do it contextually. The issue in this case ("orphaned outlets") are covered in the How to Build a Simple iPhone App course so I specifically chose to cover new content here. But..point noted! I'll add it as a note on the video :)
Mummy Lao
Courses Plus Student 2,414 Pointsand how can I fix this bug, to change the Referencing Outlet Collections from "gestureRecognizers -> View" to "gestureRecognizers -> placeholder" pls tell me how to do
Pasan Premaratne
Treehouse TeacherWhere it says "gestureRecognizers -> View", press on the tiny X to get rid of that connection. Then control drag from the gestureRecognizer in the document outline over to an image view. Only let go when you see the placeholder image highlighted. You can even drag it from the gestureRecognizer in the document outline to the image view in the outline as well
Mummy Lao
Courses Plus Student 2,414 PointsThank you very much Kaitlan Lang, now it's work :)
Mikhail Damiani
Courses Plus Student 4,175 PointsI determined that the problem was actually coming from incorrectly connecting the playlistImageView outlets. For anyone else struggling with a similar problem, I solved this by checking the connections tab (next to size and attributes tabs) and noticing that a playlistImageView had not been configured correctly
Richard Price
2,050 Pointswhat do you mean by this? when I remove the code added from this video it works fine (indicating that the playlist outlet is fine) the issue is with down casting to a UIImageView. It doesn't like it and I can't understand how it works in this video but not on my X code. We need an answer from Prasad....please help
Eliot Murton
7,315 PointsHi Pasan Premaratne and everybody else. I see what you mean about having linked it to the view rather than the image view. I delete this link then ctrl drag from gesture recognizer to the placeholder. When I do this the drop down that appears is headlined "Outlets" with only one option of "delegate". Why is this? I can't get past this point.
Deepa Laxmi
3,035 PointsHi Eliot Murton ! Did you solve your problem? I am also facing the same issue. please help me out if you have solved it.
Thanks
Eliot Murton
7,315 PointsNever mind. I figured out how to do it by ctrl clicking and dragging from the option box that appears then. All works so far. AWESOME!!!!!!!! (I'm a little bit excited as I was 3 seconds away from crying in a corner somewhere). Peace.
Steve Hunter
57,712 PointsGlad you got it fixed, Eliot!
You know where we are if you need a hand at any point. Just shout in the forum!
Steve.
Wissile Sogoyou
4,742 PointsHad the same issue but got it to work in the end! Apple keep upgrading Xcode and changing swift syntax, so its not Pasan's fault. All you need to do is add a bang: "!" right after UIImageView like this Solution: let playlistImageView = sender!.view as! UIImageView!
and voila !
Marcelo Farjalla
3,241 PointsOkay. So I keep seeing Xcode telling me I have to add a bang(!) after 'as' and Pasan's example doesn't show any such thing. I am assuming as mentioned in this comment that it's because Apple changed things after the video was created. Thanks.
Steve Hunter
57,712 PointsYes, Marcelo, the Swift language changed making the bang usage different.
Steve.
Steve Hunter
57,712 PointsCan you post the rest of the code in that Controller, please?
Jens Hagfeldt
16,548 PointsDid you check what object sender is before casting it's view as an UIImageView?
In that step I think that we first made sure that sender is one of our image views by checking it's segue identifier... So in other words do they all have the segue identifier that you ask for?
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showPlaylistDetailSegue" {
let playlistImageView = sender!.view as UIImageView
if let index = find(playlistArray, playlistImageView) {
let playlistDetailController = segue.destinationViewController as PlaylistDetailViewController
playlistDetailController.playlist = Playlist(index: index)
}
}
}
Richard Price
2,050 Pointshappening for me and my controller is connected correctly. Does anyone have a fix please?
Richard Price
2,050 Pointssoon as this code is added the app crashes and complains about casting
works fine before this. Any ideas anyone on this?
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showPlaylistDetailSegue" {
let playlistImageView = sender!.view as UIImageView
if let index = find(playlistArray, playlistImageView) {
let playListDetailController = segue.destinationViewController as PlaylistDetailViewController
playListDetailController.playlist = Playlist(index: index)
}
}
}
Richard Price
2,050 PointsPRASAD...please help your code has been copied correctly but this is the issue its been copied therefore making it difficult to debug. As soon as the above code is added the app falls down which means everything was fine up until this video with downcastinf to UIIMAGEVIEW and adding the optional binding
unable to progress onto the next video and very frustrating
David Sparks
Courses Plus Student 8,657 PointslibswiftCore.dylib`swift_dynamicCastObjCClassUnconditional:
0x103510620: pushq %rbp
0x103510621: movq %rsp, %rbp
0x103510624: pushq %rbx
0x103510625: pushq %rax
0x103510626: movq %rsi, %rcx
0x103510629: movq %rdi, %rbx
0x10351062c: xorl %eax, %eax
0x10351062e: testq %rbx, %rbx
0x103510631: je 0x10351064c ; swift_dynamicCastObjCClassUnconditional + 44
0x103510633: movq 0x82756(%rip), %rsi ; "isKindOfClass:"
0x10351063a: movq %rbx, %rdi
0x10351063d: movq %rcx, %rdx
0x103510640: callq 0x1035131ca ; symbol stub for: objc_msgSend
0x103510645: testb %al, %al
0x103510647: movq %rbx, %rax
0x10351064a: je 0x103510653 ; swift_dynamicCastObjCClassUnconditional + 51
0x10351064c: addq $0x8, %rsp
0x103510650: popq %rbx
0x103510651: popq %rbp
0x103510652: retq
0x103510653: leaq 0xcdc8(%rip), %rax ; "Swift dynamic cast failed"
0x10351065a: movq %rax, 0x8ae57(%rip) ; gCRAnnotations + 8
0x103510661: int3
0x103510662: nopw %cs:(%rax,%rax)
Dias Rezky
Courses Plus Student 1,982 PointsI've try to change the "gesture recognition" connection but I still can't tap the image in the IOS simulator and my Xcode version is 6.1.3.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showPlaylistDetailSegue" {
let playlistImageView = sender!.view as! UIImageView
if let index = find(playlistArray, playlistImageView){
let playlistDetailController = segue.destinationViewController as! PlaylistDetailsViewController
playlistDetailController.playlist = Playlist(index: index)
}
}
}
@IBAction func showPlaylistDetails(sender: AnyObject) {
performSegueWithIdentifier("showPlaylistDetailSegue", sender: sender)
}
this is the picture of the connection inspector from tap gesture recogniser inspector
Michael Thomas
10,910 PointsIf Pasan's fix still didn't work for you, make sure that the playlists place holder image has 'User Interaction Enabled' you'll find this checkbox by selecting the placeholder then attributes inspector. For some reason I had to go back an re-enable it.
Piyawit Wipoosiri
Courses Plus Student 7,122 PointsPiyawit Wipoosiri
Courses Plus Student 7,122 PointsI got a problem at that line too