I have both certificates created and the APP in the portal has APNS enabled for both development and production.
In development it works fine, but in production when someone downloads the app and signs in my server is updated with NAPN which stands for No Push Notifications.
This is the section of code it goes to if the user has them disabled, but I have checked with multiple users and they are completely enabled but for some reason its like it is stuck with the development APNS certificate or something, also users are not prompted to enable push notifications when they first download and launch the app.
I don't know if I need to approach apple with this questions but if anyone can, please assist with recommendations on how to get this to work that would be greatly appreciated.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
//Clear notifications upon launching
[[UIApplication sharedApplication] cancelAllLocalNotifications];
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
//Register with APN
if ([[UIApplication sharedApplication] enabledRemoteNotificationTypes] != 0)
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
}else
{
URLSingleton *registrar = [URLSingleton sharedInstance];
[registrar setDevToken:#"NAPN"];
//Register APN with iShame Service
URLSingleton *urls = [URLSingleton sharedInstance];
NSString *authString = [NSString stringWithFormat:#"{\"user\":\"%#\",\"token\":\"%#\"}", [[NSUserDefaults standardUserDefaults] valueForKey:#"session_token"], [registrar getDevToken]];
NSData *authData = [authString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSMutableURLRequest *url = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urls.updateAuth]];
[url setHTTPMethod:#"POST"];
[url setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[url setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[url setValue:#"json" forHTTPHeaderField:#"Data-Type"];
[url setValue:[NSString stringWithFormat:#"%d", [authData length]] forHTTPHeaderField:#"Content-Length"];
[url setHTTPBody:authData];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:url delegate:self];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[connection start];
}
return YES;
}
You should always register for remote notification types, since that call is what causes the user to be prompted to enable push notifications on the first time they launch the app . Remove that condition. I don't know how this code worked in the sandbox env. My guess is that you added this condition at a later stage, after you already ran your app without the condition, and that's how the registration worked in that env.
When you create the .ipa, instead of building with the distribution, (unless you're putting it on the store) build with the developer license, so that the app will sign it with your signature. I have had issues with apps and that was my problem. Hope this helps!
Related
So I have an app that send a synchronous request to my remote server and all goes right running it from xcode. The question is that when I archive the app and send it to TestFlight, the tester receive no response, making the same request. I'm using the xcode's Devices window to see the log within the device with the Adhoc build and it gives me a empty object coming from the server. I have also made the request from a browser's web client to certify there is no error on the server. Here goes the code:
-(NSDictionary *)postData:(NSString *)data toUrl:(NSString *)url
{
if( nil == url || nil == data ){ return nil; }
NSString *fullUrl = [NSString stringWithFormat:#"%#%#", [self baseUrl], url];
NSURL * serviceUrl = [NSURL URLWithString:fullUrl];
NSMutableData *dados = [NSMutableData data];
[dados appendData: [data dataUsingEncoding: NSUTF8StringEncoding]];
NSMutableURLRequest * serviceRequest = [NSMutableURLRequest requestWithURL:serviceUrl];
[serviceRequest setValue:#"application/json; charset=UTF-8" forHTTPHeaderField:#"Content-type"];
[serviceRequest setHTTPMethod:#"POST"];
[serviceRequest setHTTPBody:dados];
NSHTTPURLResponse * serviceResponse;
NSError * serviceError;
NSData *dataResponse = [NSURLConnection sendSynchronousRequest:serviceRequest
returningResponse:&serviceResponse
error:&serviceError];
NSString *status = [self statusFamily:serviceResponse.statusCode];
NSDictionary *dataFromResponse = [[QMParser sharedParser] dataToDictionary:dataResponse];
return [NSDictionary dictionaryWithObjectsAndKeys:serviceResponse, #"response",
status, #"status",
dataFromResponse, #"data", nil];
}
I had a similar problem, due to the provisioning profile. I solved the problem by setting automatically the provisioning profile in Xcode (Go to Project Settings -> Build Settings -> Code Signing).
I think TestFlight require new AdHoc provisioning profile. Before this fix the app crashes in every device not included in the AdHoc provisioning profile when the application makes a a generic http request.
If that doesn't work try to delete all the prov profile and let xcode to recreate them.
I have been trying to upload a new version of my app containing non-renewing In-app Purchases with no success. It has been revoked for almost two months and i cannot find the problem.
When i'm testing with a sandbox account the purchase goes to my server, i authenticate the receipt and then update my user's status. But when my app goes to review, the reviewer says that my app doesn't deliver user's paid content, but i get not single attempt on my server.
I have made some changes on my Objective-C code hoping that maybe the error could be the timeout, which now i changed to 45.0 seconds. How long it is supposed to be?
I also made some changes to my server code that check if the purchase have been made by a sandbox or production account.
So... this is the method called after SKPaymentTransactionStatePurchased.
#pragma mark pagamento
-(void)completarTransacao:(SKPaymentTransaction *)transacao
{
[SVProgressHUD dismiss];
receipt = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];
if (!receipt)
{
receipt = transacao.transactionReceipt;
}
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[SVProgressHUD showWithStatus:NSLocalizedString(#"Efetuando assinatura...", nil)];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#assinaturaplano/", [[NSDictionary dictionaryWithContentsOfFile:configuracoes_plist] objectForKey:#"Dominio"]]] cachePolicy:nil timeoutInterval:45.0];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField: #"Content-Type"];
[request setAllHTTPHeaderFields:[NSHTTPCookie requestHeaderFieldsWithCookies:[[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:[NSURL URLWithString:#"http://temp"]]]];
NSString *postString = [NSString stringWithFormat:#"receipt=%#&transactionIdentifier=%#&origem=%#", [receipt.base64Encoding urlencode], transacao.transactionIdentifier, [[NSDictionary dictionaryWithContentsOfFile:[home_documents stringByAppendingPathComponent:#"compra"]] objectForKey:#"origem"]];
[request setHTTPBody:[NSData dataWithBytes:[postString UTF8String] length:postString.length]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *erro)
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[SVProgressHUD dismiss];
if ([(NSHTTPURLResponse*)response statusCode] == 200 || [(NSHTTPURLResponse*)response statusCode] == 201)
{
// SUBSCRIPTION CONFIRMED
[SVProgressHUD showSuccessWithStatus:NSLocalizedString(#"Assinatura efetuada com sucesso!", nil)];
[[NSNotificationCenter defaultCenter] postNotificationName:#"atualizarGold" object:nil];
}
else
{
// SUBSCRIPTION NOT CONFIRMED
[SVProgressHUD showErrorWithStatus:NSLocalizedString(#"Assinatura não efetuada. Tente novamente.", nil)];
}
[[SKPaymentQueue defaultQueue] finishTransaction:transacao];
}];
}
My purchase method always goes to else when in review.
Review response
Reasons
2.2: Apps that exhibit bugs will be rejected
----- 2.2 ----- We found that your app exhibited one or more bugs, when reviewed on iPad running iOS 8 and iPhone 5s running iOS 8, on
both Wi-Fi and cellular networks, which is not in compliance with the
App Store Review Guidelines. In App Purchase does not complete. After
users tap on the In App Purchase, enter the Apple ID and password and
confirm the purchase, an error message is produced. The steps to
reproduce are:
1. launch app
2. sign in with the provided credentials
3. select 'Gold Membership'
4. tap '7 days'
5. enter the user's Apple ID and password
6. confirm purchase
7. error message appears
What am i doing wrong? Why does it work only though sandbox?
To find the receipt info i did the following:
// Transaction: SKPaymentTransaction
// storeURL: Sandbox - https://sandbox.itunes.apple.com/verifyReceipt | Production - https://buy.itunes.apple.com/verifyReceipt
-(void)validateTransaction:(SKPaymentTransaction *)transaction storeURL:(NSString *)url
{
receipt = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];
if (!receipt)
{
receipt = transacao.transactionReceipt;
}
NSError *error;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[NSJSONSerialization dataWithJSONObject:#{#"receipt-data": [receipt base64EncodedStringWithOptions:0], #"password" : #"yourpassword"} options:0 error:&error]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
{
if (!connectionError)
{
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
if ([[jsonResponse objectForKey:#"status"] intValue] == 0)
{
NSDictionary *purchaseInfo;
NSArray *inApp = [[jsonResponse objectForKey:#"receipt"] objectForKey:#"in_app"];
if (inApp)
{
for (NSDictionary *receptDictionary in inApp)
{
if ([[receptDictionary objectForKey:#"transaction_id"] isEqualToString:transacao.transactionIdentifier])
{
purchaseInfo = receptDictionary;
break;
}
}
}
// The recent has been found
// Send it to your server
}
else
{
switch ([[jsonResponse objectForKey:#"status"] intValue])
{
case 21003:
// Receipt not authenticated
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case 21005:
// Server not available
break;
case 21007:
// Sandbox receipt send it to sandbox server
[self validateTransaction:transaction storeURL:#"https://sandbox.itunes.apple.com/verifyReceipt"];
break;
case 21008:
// Production receipt send it to production
[self validateTransaction:transaction storeURL:#"https://buy.itunes.apple.com/verifyReceipt"];
break;
}
}
}
else
{
// It was not possible to connect AppStore
}
}];
}
In my application i have added notification by storing the device id in server and using php i sending notification the problem is now device token is not storing in the server previously it was working f9 but not its not working.
Previously I was using different account now I'm accessing different account after setting the new account certification in my app is not working please tell where I'm wrong.
Notification code.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeNone)];
return YES;
}
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
const char* data = [deviceToken bytes];
NSMutableString * token = [NSMutableString string];
for (int i = 0; i < [deviceToken length]; i++) {
[token appendFormat:#"%02.2hhX", data[i]];
}
NSString *urlString = [NSString stringWithFormat:#"url?token=%#",token];
NSURL *url = [[NSURL alloc] initWithString:urlString];
NSLog(#"token %#",urlString);
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSLog(#"request %# ",urlRequest);
NSData *urlData;
NSURLResponse *response;
urlData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:nil];
NSLog(#"data %#",urlData);
[self clearNotifications];
}
The above same code was working fine previously now its not working I'm not able to find solution why its not storing after i changing to new account please tell me how to resolve.
Thanks.
Just for other people reading this question. We have narrowed down the issue by implementing
-(void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
After that it turns out that the app was signed with wrong provisioning profile. Simple things like that are getting missed :)
I am implementing Push notification in my app.
I have created the certificate and Profiles as per apple guidelines.
I am also able to get token in
didRegisterForRemoteNotificationsWithDeviceToken: method
I am using a PHP server to generate PUSH notification.
Now I am not clear, Do I need to send the apptoken back to my push server.
And how send token to server.
Thanks,
Yes, you should implement a web service exposed by the server to allow the client app to send its push token to the server.
Without the token your server has no idea where to send the notification.
You need to transform your token received in your method - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken like this
NSString *tokenPush = [[[deviceToken description] stringByTrimmingCharactersInSet:
[NSCharacterSet characterSetWithCharactersInString:#"<>"]]
stringByReplacingOccurrencesOfString:#" " withString:#""];
And after to send it to your server for to keep it. After, when you need to send any push notification to any device, you will need to use this tokenPush.
Hey after getting token yo have to send it to server via web services.below i have given an example of websevices using ASHIHttp framework.Save this token in database if you have to send notification to more then one devices.
-(void)savePlayerDataOnServer:(NSString *)facebookName
{
appdelegate = [[UIApplication sharedApplication]delegate];
NSLog(#"Tokennn %#", [appdelegate string]);
NSURL *url = [NSURL URLWithString:kAPIHost#"yourscripturl"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
NSString *fbnameinside = [[NSString alloc] initWithFormat:#"%#",facebookName];
NSLog(#"globalmailID in savePlayerDataOnServer %#",globalmailID);
[request setPostValue:fbnameinside forKey:#"PlayerName"];
[request setPostValue:globalmailID forKey:#"PlayerEmail"];
[request setPostValue:[appdelegate string] forKey:#"DeviceToken"];
[request setDelegate:self];
[request startAsynchronous];
[request setCompletionBlock:^{
NSString *responseString = [request responseString];
NSLog(#"Response in savePlayerDataOnServer: %#", responseString);
}];
[request setFailedBlock:^{
NSError *error = [request error];
NSLog(#"Error in savePlayerDataOnServer: %#", error.localizedDescription);
}];
}
I have an iOS app that has a series of images in a scrollview (camera pictures). I want to be able to post these on to a url individually or collectively as a group.
Can someone point me to an example or some sample code that would get me started?
Much appreciated
in that case if you if you set up your server (how do this i don`t now, because i used quickblox - ready-made solution) try send GET-request to the server. You can try this like this:
(source - How to send a Get request in iOS? )
NSString *getString = [NSString stringWithFormat:#"parameter=%#",yourvalue];
NSData *getData = [getString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *getLength = [NSString stringWithFormat:#"%d", [getData length]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:#"https:yoururl"]];
[request setHTTPMethod:#"GET"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:getData];
self.urlConnection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
NSAssert(self.urlConnection != nil, #"Failure to create URL connection.");
// show in the status bar that network activity is starting
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
For more advanced preferences I would advise you try learn http://allseeing-i.com/ASIHTTPRequest/
For this you can create file server or use other maded. Look this: http://quickblox.com/ - they has blobs and ios api for their server, so download|upload files simple implemented in code.
First, you need register your account and then register your app.( https://admin.quickblox.com/signin ) (it's not difficult, few minuts)
Then, using instructions from site added Quickblox auth to your app and then use QBBlobs for dowload photo. Good luck!