I've ran my spritekit game on the following devices: iPhone 5s, iPhone 4s, iPad air and iPad mini. The app runs and all the devices except the 4s. On the 4s the app crashes when the app transitions to scenes that include SKPhysicsContactDelegate, for example:
class PlayScene: SKScene, SKPhysicsContactDelegate, ADBannerViewDelegate {
enum ColliderType: UInt32 {
case narrowCategory = 1
case bigCategory = 2
case smallCategory = 4
case roundCategory = 8
}
var narrow = SKSpriteNode(imageNamed: "Narrow")
var big = SKSpriteNode(imageNamed: "Big")
override func didMoveToView(view: SKView) {
........ }
The error message that comes up when the app crashes is: thread 1 exc_breakpoint (code=exc_arm_breakpoint, subcode = 0xe7ffdefe).
Initially the error stopped the app at this line where I add in the background music (which doesn't make any sense to me because this line is also within one of the other scenes with no SKPhysicsContactDelegate and yet it runs smoothly):
var backgroundMusicURL: NSURL = NSBundle.mainBundle().URLForResource("LevelOne", withExtension: "wav")!
When I commented out the background music the app then crashed at this line
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("addPlay"), name: "AddPlay", object: nil)
After I comment it out again the error jumps to this line
narrow.physicsBody?.mass = 0.0001
then this
narrow.physicsBody?.allowsRotation = true
and the error keeps moving as I comment out any lines that it previously crashed at. The app stops crashing once I remove the background music and all the functions that I call into my didMoveToView(view: SKView) that adds or modifies new or existing spritenodes, an example of one of these functions is below:
func addDiamond() {
var diamond = SKSpriteNode(texture: diamondTexture)
diamond.name = "diamond"
diamond.physicsBody = SKPhysicsBody(circleOfRadius: diamond.size.width/2)
diamond.zPosition = 1
diamond.physicsBody?.mass = 0.01
diamond.physicsBody?.allowsRotation = true
diamond.physicsBody?.dynamic = true
diamond.physicsBody?.affectedByGravity = false
diamond.setScale(0.75)
diamond.physicsBody?.categoryBitMask = diamondCategory
diamond.physicsBody?.contactTestBitMask = laserCategory
diamond.physicsBody?.collisionBitMask = laserCategory
// setting the position
let minX = diamond.size.width/2
let maxX = self.frame.size.width - diamond.size.width/2
let rangeX = maxX - minX
let positionX: CGFloat = round(CGFloat(arc4random()) % CGFloat(rangeX) + CGFloat(minX))
let minY = self.frame.size.height/5
let maxY = self.frame.size.height * 0.4
let rangeY = maxY - minY
let positionY: CGFloat = round(CGFloat(arc4random()) % CGFloat(rangeY) + CGFloat(minY))
diamond.position = CGPointMake(positionX, positionY)
// setting the rotation
let minR = 0
let maxR = 6
let rangeR = maxR - minR
let positionR: CGFloat = round(CGFloat(arc4random()) % CGFloat(rangeR) + CGFloat(minR))
diamond.zRotation = positionR
// set animation
let hold = SKAction.waitForDuration(4)
let remove = SKAction.removeFromParent()
diamond.runAction(SKAction.sequence([hold,remove]))
// animation of bubble
let minDur = 6
let maxDur = 8
let rangeDur = maxDur - minDur
let durationOne = Int(arc4random()) % Int(rangeDur) + Int(minDur)
let durOne = NSTimeInterval((Double(durationOne)/25))
var animateArray:NSMutableArray = NSMutableArray()
for i in 1...1500 {
animateArray.addObject(SKAction.rotateByAngle(0.2, duration: 0.01))
//animateArray.addObject(SKAction.rotateByAngle(-0.2, duration: 0.5))
}
diamond.runAction(SKAction.sequence(animateArray))
animateArray.addObject(SKAction.removeFromParent())
addChild(diamond)
}
this is added using the line below in the viewdidload
diamondTimer = NSTimer.scheduledTimerWithTimeInterval(10, target: self, selector: Selector("addDiamond"), userInfo: nil, repeats: true)
Scenes that do not use SKPhysicsContactDelegate run fine on the 4s. I also tested the 4s on the simulator and it seemingly crashes when you get to scenes using SKPhysicsContactDelegate but unlike the device an error doesn't come up, the device just blacks out and crashes without any debug sessions on xcode...does anyone have the faintest idea about what is going on here?
The problem was that I was using this line to place my nodes in a random position.
let durationOne = Int(arc4random()) % Int(rangeDur) + Int(minDur)
I suppose the problem with this line was that it in 32-bit devices (like the 4s) the device couldn't handle the size of the random number and it caused a crash. When I replaced that line with :
let durationOne = UInt32(arc4random()) % UInt32(rangeDur) + UInt32(minDur)
the problem stopped and the device ran smoothly. Although I have no idea why the error message did not target this line and kept moving about to irrelevant lines...anyway i hope that helps anyone with a similar problem!