StoreKit delegate functions are not getting called - iphone

I wanted help from you guys. I have implemented the storekit code in my iPhone/iPad app and I am testing the application on iPad 1 with iOS 3.2.
I tried to test the application after performing all the steps like adding the products in for an application in iTunes connect and using provisioning profile to run that app on my iPad but when i run the application Storekit delegate functions are never called neither it gives any error and it never crashes. I can't figure out what is the problem.
Please help me to resolve this.
Below is the code which i have used
- (void) requestProductData
{
SKProductsRequest *request= [[SKProductsRequest alloc]
initWithProductIdentifiers: [NSSet setWithObject:#"myproductid"]];
request.delegate = self;
[request start];
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:
(SKProductsResponse *)response
{
NSArray *myProduct = response.products;
// populate UI
[request autorelease];
}
- (void) request:(SKRequest *)request didFailWithError:(NSError *)error {
NSString *errorMessage = [error localizedDescription];
NSLog(#"%#",errorMessage);
}
- (void)requestDidFinish:(SKRequest *)request{
NSLog(#"%#",#"inside request finish");
}
I call the requestProductData but none of the delegate function is called.
Thanks so much in advance!

I figure this is a bit late and you would of solved it by now, but I am trying to resolve another issue, came across your question and was wondering if you had the delegates in your interface file.
#import <UIKit/UIKit.h>
#import <StoreKit/StoreKit.h>
#interface ViewController : UIViewController<SKProductsRequestDelegate, SKRequestDelegate, SKPaymentTransactionObserver>
#end
I suspect you did have the above code and as said solve it, but just in case someone else has the same issue and has forgotten to include the delegates in the h file.

Related

NSURLConnection doesn't receive data when creating many downloading objects in iOS5

I have been searching for this problem on the SOF for several days and I still have not found the solution (say the same problem) yet.
I'm making and app that downloads 5 images simultaneously in an URL list (each image is on a different server).
I have an ImageDownloader class subclasses NSOperation and implements the NSURLConnectionDataDelegate.
So that I can add an instance of ImageDownloader to an operationQueue in the ViewController and it will run in a separate thread under the operationQueue. The line that add the downloader to the operationQueue is here:
downloader = [[ImageDownloader alloc] init];
[downloader downloadImageWithURL:[controller.URList objectForKey:[NSString stringWithFormat:#"%d",downloadIndex]] queue:queue andTag:downloadIndex + 100]; //my custom initialize
downloader.delegate = self;
[queue addOperation:downloader]; //use the addOperation method
Everything works fine in iOS6 but messed up in iOS5 (5.0 on my test device and 5.1 on my SDK), it just doesn't receive any response nor data by performing the methods didReceiveResponse and didReceiveData at all (these 2 methods are not jumped in).
After the timeout was exceeded, the runloop jumps into didFailWithError method and the program stalls.
As I understand, this means the runloop still runs right?
I tried to print out the error and all I got is: The request timed out.
When I reduce the number of downloading instances to 2 then it runs, but not with >=3 downloading instances.
One more information is that my network connection does limit the number of connection. But it work fine in iOS6, why it just doesn't work on iOS5?
I can still load the web in the simulator while the app is downloading.
So what kind of problem is this and how can I get over this problem?
Thanks in advance.
*Update:* as there are many classes and the problem's not been clearly detected yet, I will share here the whole project. You can download it directly from here:
DownloadingImage
As I just found out, if you're using credentials there is a chance that the server will reject them randomly every once in a while. So if you have a check to make sure previousFailureCount == 0 then you will most likely have a bug.
I've just figured out where my problem is, but not really understand why.
In my ImageDownloader class, I set up a runloop with done and currentRunLoop variables.
In the main method, I have a while loop for forcing the currentRunLoop run.
As I remove those "runLoop" stuffs, the app runs smoothly on both iOS6 and iOS5.
So change the entire ImageDownloader.m with these lines then it works (I commented out some useless (say harmful) lines):
//
// ImageLoader.m
// DownloadImagesTableView
//
// Created by Viet Ta Quoc on 6/25/13.
// Copyright (c) 2013 Viet Ta Quoc. All rights reserved.
//
#import "ImageDownloader.h"
#implementation ImageDownloader
#synthesize downloadData,delegate,queue,done,customTag;
NSRunLoop *currentRunLoop;
-(void)downloadImageWithURL:(NSString *)imageUrl queue:(NSOperationQueue*)opQueue andTag:(int)tag{
self.customTag= tag;
self.queue = opQueue;
// self.done = NO;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:imageUrl] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[connection start];
// currentRunLoop = [NSRunLoop currentRunLoop];
NSLog(#"Start downloading image %d...",customTag);
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
NSLog(#"Received response...");
downloadData=[[NSMutableData alloc] initWithLength:0];
expectedDataLength=[response expectedContentLength];
NSLog(#"Image %d size: %lld kb",customTag,[response expectedContentLength]/1024);
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
float receivedLenght = [data length];
receivedDataLength=(receivedDataLength+receivedLenght);
float progress=(float)receivedDataLength/(float)expectedDataLength;
[delegate updateProgess:progress andIndex:[NSIndexPath indexPathForRow:customTag-100 inSection:0]];
[self.downloadData appendData:data];
// NSLog(#"Percentage of data received of tag %d: %f %%",self.customTag,progress*100);
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
[delegate finishedDownloadingImage:downloadData andTag:customTag];
// done = YES;
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Warning" message:#"Network Connection Failed?" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:nil, nil];
// NSLog(#"%#",[error debugDescription]);
NSLog(#"Connection failed! Error - %# %#",[error localizedDescription],[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
[alert show];
}
-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{
NSLog(#"Got here *(*&(**&(*&(*&(*&(*&(*&(*&(*&(*&(*&(*&(*&(*&(*&(*&(*&(*&");
}
-(void)main{
// do{
//// NSLog(#"Running....1");
// [currentRunLoop runUntilDate:[NSDate distantFuture]];
// // [currentRunLoop run];
// } while (!done);
// [currentRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
}
#end
Thank you guys for your supports.
==================================================================================
P/s: for anyone who interested in this problem, I update here my entire solution: DownloadImage_Final

EXC_BAD_ACCESS error with RestKit in didReceiveResponse method

I can't get rid of a EXC_BAD_ACCESS error in RestKit. I suspect its because I have an ARC project and may be releasing the request or response variable too many times, but I've spent hours on this and am not sure.
My problem sounds similar to this post, but I'm not sure where in my code to make a similar change.
My implementation file has a straightforward method to post the new object to the server. All the mapping logic is down within the implementation file for the NSObject below:
-(void) createMeeting
{
NSString* baseUrl = #"https://myapp.appspot.com/api/meeting/?format=json&username=testuser#test.com&api_key=f8s9df8as8df9s8d97";
RKObjectManager* rkoManager = [RKObjectManager objectManagerWithBaseURLString:baseUrl]; [NewMeetingRK initMap:rkoManager];
NewMeetingRK *newmtg = [NewMeetingRK alloc];
newmtg.leader = self.leaderEmail.text;
newmtg.startdate = [sqliteformatter stringFromDate:bdate];
newmtg.enddate = [sqliteformatter stringFromDate:edate];
[[RKObjectManager sharedManager] postObject:newmtg delegate:self];
And it successfully begins requestDidStartLoad:(RKRequest *)request
However it then crashes in RKResponse.m on the second to last line below (if ([[_request delegate] respondsToSelector:... with a EXC_BAD_ACCESS error.
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response {
RKResponseIgnoreDelegateIfCancelled();
RKLogDebug(#"NSHTTPURLResponse Status Code: %ld", (long) [response statusCode]);
RKLogDebug(#"Headers: %#", [response allHeaderFields]);
_httpURLResponse = [response retain];
[_request invalidateTimeoutTimer];
if ([[_request delegate] respondsToSelector:#selector(request:didReceiveResponse:)]) {
[[_request delegate] request:_request didReceiveResponse:self];
}
}
Any ideas to help me? Thanks much.
EXC_BAD_ACCESS happens when a message is sent to an object that has been released.
You should pay attention to _request delegate object. NSZombieEnabled break point might help you too. How to enable zombie objects

How to make NSURLConnection file download work?

I have a ViewController declared as:
#interface DownloadViewController : UIViewController
<UITableViewDataSource, UITableViewDelegate>
and I want to use NSURLConnection to download files. NSURLConnection simply "doesn't start", the delegate methods don't work (for example connection:didReceiveResponse is never called) . I noticed in some sample code that the class was subclassing NSObject instead of UIViewController.
How do I combine it? I want to use ViewController methods but then I can't use NSURLConnection.
It's not so easy to find a fully explained example how to download file with NSURLConnection. Everyone only concentrates on the easy methods like didReceiveResponse.
Using a UIViewController instead of an NSObject should not be your problem here !
I'm using a NSURLConnection in an UIViewController with no issue !
Here is a part of my code (not sure it will compile as it is) :
//
// MyViewController.h
//
#import <Foundation/Foundation.h>
#interface MyViewController : UIViewController {
#protected
NSMutableURLRequest* req;
NSMutableData* _responseData;
NSURLConnection* nzbConnection;
}
- (void)loadFileAtURL:(NSURL *)url;
#end
-
//
// MyViewController.m
//
#import "MyViewController.h"
#implementation MyViewController
- (void)loadView {
// create your view here
}
- (void) dealloc {
[_responseData release];
[super dealloc];
}
#pragma mark -
- (void)loadFileAtURL:(NSURL *)url {
// allocate data buffer
_responseData = [[NSMutableData alloc] init];
// create URLRequest
req = [[NSMutableURLRequest alloc] init];
[req setURL:_urlToHandle];
nzbConnection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES];
[req release];
req = nil;
}
#pragma mark -
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// Append data in the reception buffer
if (connection == nzbConnection)
[_responseData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
if (connection == nzbConnection) {
[nzbConnection release];
nzbConnection = nil;
// Print received data
NSLog(#"%#",_responseData);
[_responseData release];
}
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
// Something went wrong ...
if (connection == nzbConnection) {
[nzbConnection release];
[_responseData release];
}
}
#end
If you plan to download large files, consider storing the received packets in a file instead of storing it in memory !
If you're having problems, you could consider using the well regarded ASIHTTPRequest library to manage your download. It takes care of everything for you.
For example, just 2 lines will do it.
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadDestinationPath:fullPathOfWhereToStoreFile];
Use "NSURLConnection asynchronously" search for the term and you'll find source. Or just NSURLConnection.
For example:
NSURLConnection NSURLRequest proxy for asynchronous web service calls
Using NSURLConnection from apple with example code
Objective-C Programming Tutorial – Creating A Twitter Client Part 1

productsRequest response method is not calling

I am implementing an in app purchase and I am sending the request to apple store through
- (void) requestProductData
{
SKProductsRequest *request= [[SKProductsRequest alloc] initWithProductIdentifiers:
[NSSet setWithObjects: featureAId,featureBId,nil]]; // add any other product here
request.delegate = self;
[request start];
}
the response method
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
[purchasableObjects addObjectsFromArray:response.products];
}
is not getting called at all. Only once did it call out of ten attempts I tried.
Try to implement also - (void)request:(SKRequest *)request didFailWithError:(NSError *)error method - may be there're some errors in processing of your requests.
I faced the same problem, but in my case the cause was that I was using Automatic Reference Counting and I forgot to retain the request.
My code was like:
- (void) requestProductData
{
SKProductsRequest *request= [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:ProductIdentifier]];
request.delegate = self;
[request start];
}
But delegate's productsRequest:didReceiveResponse: never got called.
A fix would be:
#property (strong, nonatomic) SKProductsRequest *request;
- (void) requestProductData
{
self.request= [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:ProductIdentifier]];
self.request.delegate = self;
[self.request start];
// you can nil request property in request:didFailWithError: and requestDidFinish:
}
I had the same problem. I had created a helper class to handle the IAP and check for the products. What I finally found was the instance of the class I created was being released before the response came back, thus the delegate methods never got called because they did not exist anymore.
I solved my problem by retaining the instance of the helper class in the class I called it from using #proprty(strong, nonatomic)...
If you are not using a helper class and coding it into an existing class then the answer above will work by retaining your SKProductRequest.
I've had a similar problem (error: Cannot connect to iTunes Store). After upgrading iTunes Beta to the latest version it started working again.

Trying to launch App Store - getting ""in something not a structure or union" error

I am trying to launch the App Store without launching Safari with all the redirects and I am getting an error about "Request for member 'iTunesURL' in something not a structure or union."
I am new to a lot of this so thank you for being patient with me. I think it has something to do with me calling "self.iTunesURL" since it doesn't think iTunesURL is a part of the current class, but I could be very wrong.
Thank you in advance for your help while I am (slowly) learning all of this.
SampleAppDelegate.h
-(void)launchStore:(NSURL *)iTunesURL;
-(void)connectionDidFinishLoading:(NSURLConnection *)connection;
SampleAppDelegate.m
// Process a LinkShare/TradeDoubler/DGM URL to something iPhone can handle
- (void)launchStore:(NSURL *)iTunesURL {
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:iTunesURL] delegate:self startImmediately:YES];
[conn release];
}
// Save the most recent URL in case multiple redirects occur
// "iTunesURL" is an NSURL property in your class declaration
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response {
self.iTunesURL = [response URL];
return request;
}
// No more redirects; use the last URL saved
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[[UIApplication sharedApplication] openURL:self.iTunesURL];
}
MyViewController.h
#import "SampleAppDelegate.h"
and i have NSURL *iTunesURL; within the #interface curley braces.
#property (nonatomic, retain) NSURL *iTunesURL;
- (IBAction) proButtonPressed: (id)sender; // press to launch App Store
MyViewController.m
#import "MyViewController.h"
#implementation MyViewController
#synthesize iTunesURL;
- (IBAction) proButtonPressed: (id) sender {
NSURL *iTunesLink = [NSURL URLWithString:#"actual http URL goes here"];
SampleAppDelegate *appDelegate = (SampleAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate launchStore:iTunesLink];
}
iTunesURL is a property of the ViewController class and you can only use the self reference within the methods of that class. Importing the ViewController.h class doesn't give the SampleAppDelegate class the ability to call the properties of ViewController class unless it is a subclass of ViewController.
You need to create a new another property within SampleAppDelegate and assign the value of ViewController.iTunesURL to that property.