Java's byte type is signed and can have values between -128 and +127.
When writing an int (4 bytes) from Java using java.io.DataOutputStream.writeInt(int) the javadoc states
Writes an int to the underlying output stream as four bytes, high byte first...
Obj-C's char type is signed so to decode 4 bytes to an int in Obj-C make sure you AND each byte with 0xFF *before* casting to int which has the effect of translating signed values into the unsigned byte range 0..255:
-(void)handleDownloadWithData:(NSMutableData*)data
{
   NSLog(@"Downloaded data, size: %d", [data length]);
     
   char* bytes = (char*)[data bytes];

   int b0 = (int)(0x0ff & bytes[0]);
   int b1 = (int)(0x0ff & bytes[1]);
   int b2 = (int)(0x0ff & bytes[2]);
   int b3 = (int)(0x0ff & bytes[3]);

   int count = (b0 << 24) + (b1 << 16) + (b2 << 8) + b3;
   
   NSLog(@"Read int4: %d", count);

   // Other stuff
}