I have read ray's awsome tutorials on apns from there
http://www.raywenderlich.com/3443/apple-push-notification-services-tutorial-part-12
http://www.raywenderlich.com/3525/apple-push-notification-services-tutorial-part-2
and i have implemented them with development certificate and every thing is working fine, but now when i have implemented it with production certificate, the device token has stop generating. i have created new App Id for production and also new Production Push SSL Certificate and i have also created the .pem files but some how the device token is not generating, plz. guide me in this coz i am stuck here, even this notification is not being called
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSString* oldToken = [dataModel deviceToken];
NSString* newToken = [deviceToken description];
newToken = [newToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
newToken = [newToken stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"My token is: %#", newToken);
[dataModel setDeviceToken:newToken];
[[NSNotificationCenter defaultCenter] postNotificationName:#"TokenRecieved" object:nil];
if ([dataModel joinedChat] && ![newToken isEqualToString:oldToken])
{
[self postUpdateRequest];
}
}
plz. guide
One reason of this type of behavior can be that you have not registered your application for RemoteNotifications. To register it for apns you will need to write following code in your Application Delegate's didFinishLaunchingWithOptions method.
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeBadge ];
It will register your device for Badge and Alert kind of notification. To verify whether application is registered or not you can go in settings>notification>your application if its their with these two kind of notification types then your application will be ready to call the delegate method and receive notification(if the switch in settings is on).
Moreover, it would be helpful if you implement application:didFailToRegisterForRemoteNotificationsWithError: method and log errors if any.
Thanks
I had exactly a same problem a while ago. Even didFailToRegisterForRemoteNotificationsWithError was not called after calling registerForRemoteNotificationTypes.
One reason I have encountered and spent hours to find out was that I had an old provisioning profile which is associated with an APN certificate. All I needed to do was re-creating (not only redownloading) provisioning profiles for production and re-install them again.
If you have created an APN certificate AFTER creating provisioning profiles, this step might help you.
Related
I implement push notification in my application, I check it on my ipad device, in the php file, I put the device token specified:
$deviceToken = '2ca0c25ed7acea73e19c9d9193e57a12c1817ed48ddf8f44baea42e68a51563c';
until now, the notification works fine.
when I want to register devices into database, I got an the below error:
Error in registration. Error: Error Domain=NSCocoaErrorDomain Code=3000 "no valid 'aps-environment' entitlement string found for application" UserInfo=0x1edda520 {NSLocalizedDescription=no valid 'aps-environment' entitlement string found for application}
I don't understand the mentioned error, Note: that I use push notification for development and not for distribution yet.
I got the code of the registration from this link
Thank you for you help!
Have you registered your application for push notifications in the developer center? And if you have, did you re-generate your provisioning profile? You need to make sure your provisioning profile is setup for push messaging.
As pointed out it is most likely a code-signing problem. Be sure to sign with the correct profile! Check your target and project settings if those are correct and not some kind of wildcard ID.
Also may I point out that the How-To you posted is still using UDID.
UIDevice *dev = [UIDevice currentDevice];
NSString *deviceUuid = dev.uniqueIdentifier;
Push only uses the devToken and UDID use is deprecated.
A solution can be found here
This error is related to certificates..Make sure you set your certificate name is correct in php file and it is present in your respective folder. Let me know if you have still error.
As a request,I am posting code of php file which is used to send notification :
<?php
// Adjust to your timezone
date_default_timezone_set('Asia/Calcutta');
// Report all PHP errors
error_reporting(-1);
// Using Autoload all classes are loaded on-demand
require_once 'ApnsPHP/Autoload.php';
// Instantiate a new ApnsPHP_Push object
$push = new ApnsPHP_Push(
ApnsPHP_Abstract::ENVIRONMENT_SANDBOX,
'ck.pem'
);
// Set the Provider Certificate passphrase
$push->setProviderCertificatePassphrase('PUT_HERE_YOUR_PASSPHRASE_WHILE_GENERATING_NOTIFICATION');
// Set the Root Certificate Autority to verify the Apple remote peer
$push->setRootCertificationAuthority('ck.pem');
// Connect to the Apple Push Notification Service
$push->connect();
// Instantiate a new Message with a single recipient
$message = new ApnsPHP_Message('PUT_HERE_DEVICE_TOKEN');
// Set a custom identifier. To get back this identifier use the getCustomIdentifier() method
// over a ApnsPHP_Message object retrieved with the getErrors() message.
$message->setCustomIdentifier("Message-Badge-3");
// Set badge icon to "1"
$message->setBadge(1);
// Set a simple welcome text
$message->setText('Hello APNs-enabled device!');
// Play the default sound
$message->setSound();
// Set a custom property
$message->setCustomProperty('acme2', array('bang', 'whiz'));
// Set another custom property
$message->setCustomProperty('acme3', array('bing', 'bong'));
// Set the expiry value to 30 seconds
$message->setExpiry(30);
// Add the message to the message queue
$push->add($message);
// Send all messages in the message queue
$push->send();
// Disconnect from the Apple Push Notification Service
$push->disconnect();
// Examine the error message container
$aErrorQueue = $push->getErrors();
if (!empty($aErrorQueue)) {
var_dump($aErrorQueue);
}
?>
This code of notification is of APNS library.You can see here : APNS_PHP
I try to implement push notification in my iPhone application. I have create Provisioning Profile and App-id for push notification and add this certificates into Xcode. Connect iPhone device to mac system and build application through device for read Device token using the following code.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog(#"didRegisterForRemoteNotificationsWithDeviceToken:\n%#", deviceToken);
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(#"didFailToRegisterForRemoteNotificationsWithError:%#", [error localizedDescription]);
}
But it returns error.. like
didFailToRegisterForRemoteNotificationsWithError:no valid 'aps-environment' entitlement string found for application 2012-07-18
14:18:08.597 Z2NotifyMe[1874:707]
didFailToRegisterForRemoteNotificationsWithError:Error
Domain=NSCocoaErrorDomain Code=3000 "no valid 'aps-environment'
entitlement string found for application" UserInfo=0x11fee0
{NSLocalizedDescription=no valid 'aps-environment' entitlement string
found for application}
I have remove all old certificates in Xcode and my device, then re-create all certificate newly then execute above same code it returns same above error.
Please help solve this problem.
Thanks..
Register your device using the following code :
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
In the applicationDidFinishLaunching: method.
I hope that the device on which you are trying is not Jailbroken.
This problem occurs when your code signing identity does not have push notification enabled.
Check out this link:
http://mobiforge.com/developing/story/programming-apple-push-notification-services
http://blog.martinreichart.com/2010/01/getting-iphone-push-notifications-to-work/
I had a similar problem when I did all the steps correctly but i still got this error.
Try doing the following steps, it helped me:
1) Go to you Provisioning Profile -> Provisioning
2) Press the "edit" button in the right hand side near your app provisioning profile - > then modify
3) Make some change here, it doesn't really matter what the change is, this is just to trigger a new profile. Unselect one of the devices, or change the name, you can change it back later.
4) press the "submit" button
5) download the profile and drag it to Xcode. (delete your old profile in Xcode before)
I'm using MKStoreKit to implement an IAP into my application. Everything does as expected when purchasing the product, no error messages at all. The product is purchased using the following code..
[[MKStoreManager sharedManager] buyFeature:#"pro_upgrade"
onComplete:^(NSString* purchasedFeature)
{
NSLog(#"Purchased: %#", purchasedFeature);
// provide your product to the user here.
// if it's a subscription, allow user to use now.
// remembering this purchase is taken care of by MKStoreKit.
}
onCancelled:^
{
// User cancels the transaction, you can log this using any analytics software like Flurry.
}];
After the product has been purchased I recieve the notification (via the code below) which confirms the purchase..
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector (subscriptionPurchased:)
name: kSubscriptionsPurchasedNotification
object:nil];
After the purchase I execute the following code (as documented) to determine if the product has been purchased..
if([MKStoreManager isFeaturePurchased:#"pro_upgrade"]) {
NSLog(#"This feature is purchased.");
} else {
NSLog(#"This feature is not purchased");
}
It constantly returns NO for the product ID. This happens when running the app in the same instance as when the product was purchased as well as closing the app and opening it. Running the app using Development or Distribution certificates make no difference at all. Further more I can't find where exactly MKStoreKit stores the product purchased BOOL that it seems to be looking for (it's pretty deep in the code so i'm not saying it does or doesn't, i just can't find it). My app is storing other information using NSUserDefaults so that isn't the issue.
Any help you can offer will be extremely appreciated, thanks for your time.
MKStoreKit doesn't store in NSUserDefaults.
I use keychain instead. Place a breakpoint in the method
storeData:forKey: (writing this method name straight from my head
without looking at code, search for similarly named methods) and try
debugging it. This is the place I save your purchases.
Do remember that purchases are remembered even after deleting and
reinstalling the app.
I'm trying to implement in app purchases in a free application.
I have created a productd id "test1" within the in app purchases manager in itunes connect portal.
When I make the product request in the following way:
- (id)init {
NSSet *productIdentifiers = [NSSet setWithObjects:
#"test1",
nil];
if ((self = [self initWithProductIdentifiers:productIdentifiers])) {
}
return self;
}
- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers
{
if ((self = [super init]))
{
// Store product identifiers
_productIdentifiers = [productIdentifiers retain];
// Check for previously purchased products
NSMutableSet * purchasedProducts = [NSMutableSet set];
for (NSString * productIdentifier in _productIdentifiers)
{
BOOL productPurchased = [[NSUserDefaults standardUserDefaults] boolForKey:productIdentifier];
if (productPurchased)
{
[purchasedProducts addObject:productIdentifier];
NSLog(#"Previously purchased: %#", productIdentifier);
}
NSLog(#"Not purchased: %#", productIdentifier);
}
self.purchasedProducts = purchasedProducts;
}
return self;
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
NSLog(#"Received products results...");
self.products = response.products;
self.request = nil;
[[NSNotificationCenter defaultCenter] postNotificationName:kProductsLoadedNotification object:_products];
NSLog(#"%d",[self.products count]);
NSEnumerator *e = [self.products objectEnumerator];
id object;
while(object=[e nextObject])
{
NSLog(#"item");
NSLog(#"%s",(char*)object);
}
}
- (void)requestProducts {
self.request = [[[SKProductsRequest alloc] initWithProductIdentifiers:_productIdentifiers] autorelease];
_request.delegate = self;
[_request start];
}
The response is always 0. I don't understand what am I doing wrong. This code came from a tutorial. The documentation regarding in app purchases tend to be quite confusing and the whole process in itunes connect doesnt give me confidence.
I thought the application needed to be online for sale for in app purchases to be working. However, I decided not to included in app purchases, but let the in app purchase in itunes connect for review. During the review process, the application was rejected because it should be working with the in app purchases for testing.
But how do I test in app purchases if the product listing comes always at zero?
If someone with more experience could give me an advice on this, since i'm already getting crazy with it!
Thanks,
With my best regards,
Nuno
The most coherent solution I found to this problem was this checklist. It should be wide spreaded in order to avoid anyone passing by the same problem which is really time consuming and desperating:
Have you enabled In-App Purchases for your App ID?
Have you checked Cleared for Sale for your product?
Have you submitted (and optionally rejected) your application binary?
Does your project’s .plist Bundle ID match your App ID?
Have you generated and installed a new provisioning profile for the new App ID?
Have you configured your project to code sign using this new provisioning profile?
Are you building for iPhone OS 3.0 or above?
Are you using the full product ID when when making an SKProductRequest?
Have you waited several hours since adding your product to iTunes Connect?
Are your bank details active on iTunes Connect? (via Mark)
Have you tried deleting the app from your device and reinstalling? (via Hector, S3B, Alex O, Joe, and Alberto)
Is your device jailbroken? If so, you need to revert the jailbreak for IAP to work. (via oh my god, Roman, and xfze)
Are you logged out from real iTunes account?
Have you tried restarting device?
Are you on Device? (Will not work on Simulator)
Credits go to Troy Brant
Have a look here, that answered all of my questions (and the framework is simple to use, too :-):
http://blog.mugunthkumar.com/coding/iphone-tutorial-%E2%80%93-in-app-purchases/
But I have to say the whole in-app purchase thing is a PITA - my app just got released, and of course I downloaded it and checked the in-app purchase screen. Guess what, it came up completely empty!
After some reading up it seems that even if all is accepted and ready for sale, the in-app purchase products still need a while to become available online - after 3 hours it finally worked ...
EDIT:
You need to create the in-app purchase for your app and set it to clear for sale in itunes connect. You do not need to upload a screenshot yet or have it already reviewed in order to be able to test it in development mode.
How did you name the purchase in itunes connect? Normally you should use a com.companyname.productname.purchasename name, and the name you request from your app ha to be exactly the same.
I know it's a little bit flooded with Apple's Push Notification Service (APNs) issues all over StackOverflow so I actually did a lot of researches before coming up my question.
Basically, I have followed the apns-php's CertificateCreation, some tutorial like on mobiforge, and some from Matthijs Hollemans. Still, I can't get any notification posted onto my iPad 2.
Basically these are the steps I have done:
I followed the CertificateCreation tutorial, I came out with server_certificates_bundle_sandbox.pem, entrust_root_certification_authority.pem.
Followed the tutorial specified in mobiforge blog, I successfully created the App ID, provisioning profile and linked them together nicely.
Description: APNTest
Bundle Seed ID: Use Team ID
Bundle Identifier: com.learn.APN
Then I enable the Development Push SSL Certificate (only for now) using the same certificate request I have used just now to get the certs, and I download it and install it into my keychain.
I downloaded my provisioning profile in .mobileprovision file and loaded it into Xcode's Organizer under my iPad 2 device.
Next I create a simple application with only these codes:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
// Override point for customization after application launch.
return YES;
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog(#"%#", deviceToken);
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(#"Error: %#", error);
}
Then I configure the build parameters:
Targets > Info > Build Identifier: net.learn.APN
Targets > Build Settings > Code Signing Identity > (I chose the provisioning profile I have installed just now, and it automatically selects the identical profiles for my Debug and Release)
I build and run the application on my iPad 2. My application requesting for Push Notification and after I approved it, the Token ID appeared in my console:
2012-01-19 12:43:26.345 TestAPN[578:707] <3cb08612 9392996b 5332d2fc 5adce03d 994f8959 d7a2ac38 de7bed52 c8e0778e>
I used apns-php, changed the device ID (raw 64 hexa-values), then run the sample_push.php. Script ran successfully, but my device is not receiving any notification
Then I try to use the SimplePush.php. A "Message successfully delivered" appeared, but my iPad still doesn't receive any notification from APN
Question is, which steps have I done wrongly? I'm pretty newbie in this area, and it is actually a requirement for my project that the server need to send out messages to our own applications. We are aware of the third party softwares that send APN on behalf of you, but we would like to implement one ourselves.
I also came across the "APN Feedback Service" and I written this (base on the SimplePush) but sadly it's empty. What should I do now?
<?php
// Put your private key's passphrase here:
$passphrase = '';
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'server_certificates_bundle_sandbox.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://feedback.sandbox.push.apple.com:2196', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);
echo 'Connected to APNS' . PHP_EOL;
while (!feof($fp)) {
$data = fgets($fp, 1024);
var_dump(unpack("N1timestamp/n1length/H*devtoken", $data));
}
// Close the connection to the server
fclose($fp);
Note
I am aware of the differences between development/production certs.
iPad is not jailbroken, running iOS 5.0.1
Other App Store apps receives notifications normally
XCode 4.2.1, Lion 10.7.2
I hope I'm not duplicates any of the questions here.. ;)
EDIT
When I run php simplepush.php then php feedback.php, I received a feedback with my device ID. My App is still in the iPad, so does it mean my device ID is wrong?
[root#ip-xx-xx-xx-xx SimplePush]# php feedback.php
Connected to APNS
array(3) {
["timestamp"]=>
int(1326962028)
["length"]=>
int(32)
["devtoken"]=>
string(64) "3cb086129392996b5332d2fc5adce03d994f8959d7a2ac38de7bed52c8e0778e"
}
Thanks
EDIT
After much struggling and redoing all the steps written by Matthijs Hollemans, I finally get it working. So the problem lies within the incorrect PEM file generated... hmm
I had similar problem, for me the key thing I didn't know is that the device token is different for dev and prod (for the same device).
I was using the device token I got when testing in dev to test in prod. This was working fine in dev, but when I switched to prod I kept the same device token in my python script (assuming, wrongfully, that the device token would be the same for the same device) but the actual device token registered in prod was different.
In practice this wouldn't happen as the device token is sent to the server, but when I was testing I was using hard coded device token as I didn't want to involve the server.
Hopefully this will save someone some frustration.