title: IOS sprite kit didBeginContact not called
body: <p>Please help me, I've been trying to solve this problem for 24 hours and I'm going crazy:) I am trying to detect collision in Sprite Kit through the <code>didBeginContact</code> delegate method, but this method is not fired, I've tried all the answers on the Internet</p>
  
  <pre><code>#import "MyScene.h"
  #import "GameOverScene.h"
  
  
  static const uint32_t basketCategory      =  1 &lt;&lt; 0;
  static const uint32_t ballCategory        =  1 &lt;&lt; 1;
  
  
  // 1
  @interface MyScene () &lt;SKPhysicsContactDelegate&gt;
  //@interface MyScene ()
  @property BOOL contentCreated;
  @property (nonatomic) SKSpriteNode * basket;
  @property (nonatomic) SKSpriteNode * ball;
  @property (nonatomic) NSTimeInterval lastSpawnTimeInterval;
  @property (nonatomic) NSTimeInterval lastUpdateTimeInterval;
  @property (nonatomic) int ballDestroyed;
  @property (nonatomic) int score;
  @end
  
  static inline CGPoint rwAdd(CGPoint a, CGPoint b) {
      return CGPointMake(a.x + b.x, a.y + b.y);
  }
  
  static inline CGPoint rwSub(CGPoint a, CGPoint b) {
      return CGPointMake(a.x - b.x, a.y - b.y);
  }
  
  static inline CGPoint rwMult(CGPoint a, float b) {
      return CGPointMake(a.x * b, a.y * b);
  }
  
  static inline float rwLength(CGPoint a) {
      return sqrtf(a.x * a.x + a.y * a.y);
  }
  
  // Makes a vector have a length of 1
  static inline CGPoint rwNormalize(CGPoint a) {
      float length = rwLength(a);
      return CGPointMake(a.x / length, a.y / length);
  }
  
  
  
  @implementation MyScene
  float balltime;
  
  -(id)initWithSize:(CGSize)size {    
      if (self = [super initWithSize:size]) {
          /* Setup your scene here */
  
      }
      return self;
  }
  
  
  - (void)didMoveToView:(SKView *)view
  {
  
          if (!self.contentCreated) {
              self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
              self.physicsWorld.gravity = CGVectorMake(0,0);
              self.physicsWorld.contactDelegate = self;
              self.basket = [SKSpriteNode spriteNodeWithImageNamed:@"basket"];
              self.basket.size = CGSizeMake(100, 100);
              self.basket.position = CGPointMake(self.frame.size.width/2, self.basket.size.height/2);
              self.basket.physicsBody.dynamic = YES; // 2
              self.basket.physicsBody.categoryBitMask = basketCategory; // 3
              self.basket.physicsBody.contactTestBitMask = ballCategory; // 4
              self.basket.physicsBody.collisionBitMask = 0; // 5
              self.basket.physicsBody.usesPreciseCollisionDetection = YES;
              [self addChild:self.basket];
           //   self.physicsWorld.contactDelegate = self;
          }
  
  }
  
  
  
  
  
  - (void)addball {
      balltime=1;
      // Create sprite
      self.ball = [SKSpriteNode spriteNodeWithImageNamed:@"basketball"];
      self.ball.size = CGSizeMake(100, 100);
      self.ball.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.ball.size]; // 1
      self.ball.physicsBody.dynamic = YES; // 2
      self.ball.physicsBody.categoryBitMask = ballCategory; // 3
      self.ball.physicsBody.contactTestBitMask = basketCategory; // 4
      self.ball.physicsBody.collisionBitMask = 0; // 5
      self.ball.physicsBody.usesPreciseCollisionDetection = YES;
    //  self.physicsWorld.contactDelegate = self;
  
      // Determine where to spawn the ball along the x axis
      int minX = self.ball.size.width / 2;
      int maxX = self.frame.size.width - self.ball.size.width / 2;
      int rangeX = maxX - minX;
      int actualX = (arc4random() % rangeX) + minX;
  
      // Create the monster slightly off-screen along the right edge,
      // and along a random position along the X axis as calculated above
     // ball.position = CGPointMake(actualX,self.frame.size.height + ball.size.height/2);
      self.ball.position = CGPointMake(actualX,self.frame.size.height + 300);
      [self addChild:self.ball];
  
      // Determine speed of the ball
      int minDuration = 3.99;
      int maxDuration = 4.0;
      int rangeDuration = maxDuration - minDuration;
      int actualDuration = (arc4random() % rangeDuration) + minDuration;
  
      // Create the actions
      SKAction * actionMove = [SKAction moveTo:CGPointMake(actualX,-self.ball.size.height/2) duration:actualDuration];
      SKAction * actionMoveDone = [SKAction removeFromParent];
      SKAction * loseAction = [SKAction runBlock:^{
          SKTransition *reveal = [SKTransition flipHorizontalWithDuration:0.5];
          SKScene * gameOverScene = [[GameOverScene alloc] initWithSize:self.size won:NO];
          [self.view presentScene:gameOverScene transition: reveal];
      }];
      [self.ball runAction:[SKAction sequence:@[actionMove,  actionMoveDone]]];
  
  }
  
  - (void)updateWithTimeSinceLastUpdate:(CFTimeInterval)timeSinceLast {
  
      self.lastSpawnTimeInterval += timeSinceLast;
      if (self.lastSpawnTimeInterval &gt; balltime) {
          self.lastSpawnTimeInterval = 0;
          [self addball];
      }
  }
  
  - (void)update:(NSTimeInterval)currentTime {
      // Handle time delta.
      // If we drop below 60fps, we still want everything to move the same distance.
      CFTimeInterval timeSinceLast = currentTime - self.lastUpdateTimeInterval;
      self.lastUpdateTimeInterval = currentTime;
      if (timeSinceLast &gt; 1) { // more than a second since last update
          timeSinceLast = 1.0 / 60.0;
          self.lastUpdateTimeInterval = currentTime;
      }
  
      [self updateWithTimeSinceLastUpdate:timeSinceLast];
  
  }
  
  
  
  - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
  
      UITouch *touch = [touches anyObject];
      CGPoint positionInScene = [touch locationInNode:self];
      self.basket.position=positionInScene;
  }
  
  - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
  
      UITouch *touch = [touches anyObject];
      CGPoint positionInScene = [touch locationInNode:self];
      self.basket.position=positionInScene;
  }
  
  
  
  
  - (void)ball:(SKSpriteNode *)ball didCollideWithbasket:(SKSpriteNode *)basket {
      NSLog(@"Hit");
      [self.ball removeFromParent];
      self.ballDestroyed++;
      if (self.ballDestroyed &gt; 20) {
          SKTransition *reveal = [SKTransition flipHorizontalWithDuration:0.5];
          SKScene * gameOverScene = [[GameOverScene alloc] initWithSize:self.size won:YES];
          [self.view presentScene:gameOverScene transition: reveal];
      }
  }
  
  - (void)didBeginContact:(SKPhysicsContact *)contact
  {
  
          NSLog(@"contact");
      // 1
      SKPhysicsBody *firstBody, *secondBody;
  
      if (contact.bodyA.categoryBitMask &lt; contact.bodyB.categoryBitMask)
      {
          firstBody = contact.bodyA;
          secondBody = contact.bodyB;
      }
      else
      {
          firstBody = contact.bodyB;
          secondBody = contact.bodyA;
      }
  
      // 2
      if ((firstBody.categoryBitMask &amp; basketCategory) != 0 &amp;&amp;
          (secondBody.categoryBitMask &amp; ballCategory) != 0)
      {
          [self ball:(SKSpriteNode *) firstBody.node didCollideWithbasket:(SKSpriteNode *) secondBody.node];
      }
  }
  </code></pre>