Q:

Contact and category bitmask - does only one, or both, need to be set?

So I'm learning how to check bitmask collisions in Swift and I'm confused about whether or not to set both bodies to have each other's contact bitmask. 
My confusion comes from the following in the docs:

When two physics bodies overlap, a contact may occur. SceneKit
  compares the body’s contact mask to the other body’s category mask by
  performing a bitwise AND operation. If the result is a nonzero value,
  SceneKit creates an SCNPhysicsContact object describing the contact
  and sends messages to the contactDelegate object of the scene’s
  physics world.

From what I understand, collisions do not need to be reciprocal - in other words, one can collide with another and the other stays without motion. Please correct me if I'm wrong. But when it comes to contact testing, if A has its category mask set to 1 and contact bitmask set to 2, and B has its category mask set to 2 and its contact bitmask set to 4, then will A and B colliding register as a contact? What if B sets its contact bitmask to 1 now? Will two collisions register?

A:

Let me try to explain all these bit masks with an example from an actual game code. This game has the following objects: ball, pitch, ground, bat, boundary, batting stumps, bowling stumps which will have physics interactions.
Sorry the code is in ObjC, but translation to Swift is straightforward.
Step 1: Set up the category bit masks, which specify the type of each object

typedef NS_OPTIONS(NSUInteger, CollisionCategory) {
  CollisionCategoryBall = 1 << 1,
  CollisionCategoryPitch = 1 << 2,
  CollisionCategoryGround = 1 << 3,
  CollisionCategoryBat = 1 << 4,
  CollisionCategoryBoundary = 1 << 5,
  CollisionCategoryBattingStumps = 1 << 6,
  CollisionCategoryBowlingStumps = 1 << 7,
};

Step 2: Now we decide which objects have collisions with each other. 

For example for the ball object, there are collisions with pitch, ground bat and boundary. This is setup as follows, a bitwise OR operation, assuming ballBody is a SCNPhysicsBody:
ballBody.collisionBitMask =
      (CollisionCategoryPitch | CollisionCategoryGround | CollisionCategoryBat |
       CollisionCategoryBoundary);

Step 3: (Optionally), if you want to be notified when two physics bodies are in contact with each other.

Here, you set up the contactTestBitMask. For the ball for example, I want to be notified when it is in contact with pitch, ground, bat, boundary. Again, to do that:
ballBody.contactTestBitMask =
      (CollisionCategoryPitch | CollisionCategoryGround | CollisionCategoryBat |
       CollisionCategoryBoundary);

When you set up the contactTestBitMask, you will handle the contact notifications in the physics delegate, which will be something like this:
- (void)physicsWorld:(SCNPhysicsWorld*)world
     didBeginContact:(SCNPhysicsContact*)contact {
  CollisionCategory contactMask = contact.nodeA.physicsBody.categoryBitMask |
                                  contact.nodeB.physicsBody.categoryBitMask;
  if ((contactMask == (CollisionCategoryBall | CollisionCategoryPitch)) &&
      !self.ballLandedOnPitch) {
    NSLog(@" Ball hit the pitch");
  }
  ...
}

So overall you just categorize  your objects, then setup the collision mask which is just a bitwise OR operation of the category masks of the objects with which there will be collisions and optionally to handle the contacts of bodies with each other, set up the contact test bit mask.

But when it comes to contact testing, if A has its category mask set to 1 and contact bitmask set to 2,

I am not sure if you intend to explicitly set the contact bit mask to 2 above; the contact mask should be really be a bitwise OR operation of the category masks of the objects with which there will be contacts and you want to be notified of.
I think the docs are a bit confusing and hope the above explanation clears up your doubts. 

