Apple best practice requires that you always have in memory a class that is prepared to receive transactions. IMHO that is not best practice. I use a button that the user taps to instantiate a class that contains the observer and all the storekit stuff.
That said...
You asked how to add an observer to the App Delegate:
#import <StoreKit/StoreKit.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
and add all of the StoreKit stuff in the App Delegate. (Bad idea)
Then you realized that the transaction observer isn't supposed to be in the app delegate. So what you do (again 'Apple best' but not 'best') is create a class that has all of that StoreKit stuff in it and load and initialize that class all in didFinishLaunchingWithOptions. In the init method of that class add the transaction observer to the class.
And, as alluded to above as 'better' than best: anywhere in your code have a button labeled 'get IAP info' and when that button is tapped, instantiate the StoreKit class with transaction observer. Lastly, if you are using autorenewables, do that button-tapping thing in the background when you detect an expired subscription.