I believe your "P" as the dataWithBytes param
NSData *keydata = [NSData dataWithBytes:P length:len];
should be "buf"
NSData *keydata = [NSData dataWithBytes:buf length:len];
since i2d_PrivateKey puts the pointer to the output buffer p at the end of the buffer and waiting for further input, and buf is still pointing to the beginning of your buffer.
The following code works for me where pkey is a pointer to an EVP_PKEY:
unsigned char *buf, *pp;
int len = i2d_PrivateKey(pkey, NULL);
buf = OPENSSL_malloc(len);
pp = buf;
i2d_PrivateKey(pkey, &pp);
NSData* pkeyData = [NSData dataWithBytes:(const void *)buf length:len];
DLog(@"Private key in hex (%d): %@", len, pkeyData);
You can use an online converter to convert your binary data into base 64 (http://tomeko.net/online_tools/hex_to_base64.php?lang=en) and compare it to the private key in your cert file after using the following command and checking the output of mypkey.pem:
openssl pkcs12 -in myCert.p12 -nocerts -nodes -out mypkey.pem
I referenced your question and this EVP function site for my answer.