PubNub and Multiple View Controllers - ios

I'm making an app that will use PubNub for a group chat part of the app. I turned on Playback on my app and I completed the tutorial for setting up the code. I'm confused though, because all the code was in the AppDelegate, and I have my chat view controller as part of my storyboard. My question is, what setup code do I have to do in my view controller so I can get all the past 100 messages using the historyForChannel:start:end:limit:withCompletion: method. Would I have to make a new instance of the PubNub client? That doesn't make sense since the user will be switching view controllers and It should be stored in a long life property.
What setup code do I have to do in my view controllers to get the past messages? (To be loaded into a very elaborate tableview setup)

So I figured out a working solution. First, you have to make the PubNub client property public by defining it in the AppDelegate.h file, not the .m implementation.
// AppDelegate.h
#import <UIKit/UIKit.h>
#import <PubNub/PubNub.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate, PNObjectEventListener>
#property (strong, nonatomic) UIWindow *window;
// Stores reference on PubNub client to make sure what it won't be released.
#property (nonatomic) PubNub *pnClient;
#end
And don't forget to delete from the AppDelegate.m
#import "AppDelegate.h"
#interface AppDelegate ()
/*
// Stores reference on PubNub client to make sure what it won't be released.
#property (nonatomic) PubNub *pnClient;
*/ // Delete from here
#end
#implementation AppDelegate
If you want to do notifications and such, keep the AppDelegate as a listener to the [self.pnClient] property. If not, just delete <PNObjectEventListener> from the AppDelegate.h and [self.pnClient addListener:self]; from your AppDelegate.m. If you prefer to keep it, just don't delete that stuff.
Now, #import your AppDelegate in your ChatViewController.h or the .m of you prefer. Then, make your .h conform to the <PNObjectEventListener> delegate. The, before you forget, add another client in your .h or .m to store the property of your PubNub client in your AppDelegate. :
// Stores reference on PubNub client to make sure what it won't be released.
#property (nonatomic) PubNub *pnClient;
Next, in your viewDidLoad method, add:
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
self.pnClient = appDelegate.pnClient;
[self.pnClient addListener:self];
This code first grabs the AppDelegate of your app, (so there are no shared instance or singleton things involved). Then, It sets the pnClient of your app delegate to your "temporary" client in your view controller. (See why we moved the AppDelegate's client to the .h?) And lastly, it adds self as a listener, so you can do stuff in your view controller.
Thats all there is to it!
I would suggest using your chat controller to populate a UITableView or something else, and the AppDelegate for handling notifications.

Related

Delegates in Navigation Controller

I have a location class in my project which calls methods in different several view controllers. I have defined the class in each view controller as self which works fine but when I push to and from other view controllers it starts behaving irrationally and calls the method in the wrong controller causing all sorts of problems
My location class is setup correctly and I believe I have called them correctly but I am obviously missing something like deallocating the delegate once I am done with it?
This is what is in each of my view controllers
.h
#import "AHLocationClass.h"
AHLocationClass *location;
#interface AHSelectionController : UIViewController <AHLocationDelegate> {
.m
location = [[AHLocationClass alloc] init];
location.delegate = self;
Note, I know using notification will fix this but in my project using this method will quickly make things messy
It turns out that declaring globally was my issue, declaring it as a property fixed this inconsistency.
#property (nonatomic, strong) AHLocationClass *location;

Shared iAd on Tabbed Application

New to iOS development and I have a tabbed app with 4 tabs. I have an iAd showing on one tab and I don't want to regurgetate the code on every view controller and I know this is not the correct way to implement anyway. I have looked at the Apple code here and I'm struggling to be honest.
https://developer.apple.com/library/ios/samplecode/iAdSuite/Introduction/Intro.html
I have included the BannerViewController.m and BannerViewController.h in my application but I'm not fully sure how to get it to run the ad on each view controller.
Yours confused
JKX
Just grab a reference of UIWindow in any of your ViewController Class
Go to .m of your ViewController
#import "AppDelegate.h"
#interface ViewController ()
{
//make object of AppDelegate
AppDelegate *appDelegate;
}
Now in your viewDidLoad or ViewDidAppear grab the reference of window.
appDelegate=(AppDelegate*)[UIApplication sharedApplication].delegate;
[appDelegate.window addSubview:yourBannerView];

Feeling A Bad Design Layout Using Segues

So I'm on my first iPhone app. I'm actually rather far into it. I have already learned from many mistakes, but I feel I've made an ultimate mistake. I'm using segues to navigate to different views. I get into about 5 segue views deep, which I'm realizing is causing a LOT of allocated memory. In other words, View A calls View B, B segues into C, C into D, etc..From what I understand, by the time I get to D I now have instances of A B C and D open, which does not sound good. I am using delegates for example like below:
Just an example of what I'm doing throughout my app:
First View:
#interface FirstViewController : UIViewController<SecondViewControllerDelegate>
#end
Second View:
#class SecondViewController;
#protocol SecondReviewOrderViewControllerDelegate <NSObject>
- (void)secondViewControllerDidCancel:(SecondViewController *)controller;
#end
#interface SecondViewController : UIViewController<ThirdViewControllerDelegate>
#property (strong, nonatomic) id <SecondViewControllerDelegate> delegate;
#end
Third View:
#class ThirdViewController;
#protocol ThirdReviewOrderViewControllerDelegate <NSObject>
- (void)thirdViewControllerDidCancel:(ThirdViewController *)controller;
#end
#interface ThirdViewController : UIViewController<>
#property (strong, nonatomic) id <ThirdViewControllerDelegate> delegate;
#end
And so on and on onto view 4 and 5.
My question is, if this is wrong, which it seems to be, what is the right way to about navigating views and passing data from one viewcontroller to another? Thanks for any tips.
From what I understand, by the time I get to D I now have instances of A B C and D open, which does not sound good
A view controller, of itself, is a fairly lightweight object, and there is no problem whatever with going many levels deep (e.g. pushing five view controllers onto a navigation controller stack). However, memory and images you may be holding on to are not lightweight, so be sure to implement didReceiveMemoryWarning and take it seriously if it arrives.
A strategy for letting go of large retained memory-hogging stuff in response to didReceiveMemoryWarning is to save it off to disk (if it can't be recreated on demand) and then use lazy initialization to read it back in the next time you are asked for it.

PhoneGap CDVViewController

Im building a small IOS app using PhoneGap, and after setting up a base project and I noticed that under AppDelegate.h the following PhoneGap Object is initialised:
#property (nonatomic, strong) IBOutlet CDVViewController* viewController;
However I also noticed the MainViewController inherits the CDViewController, and MainViewController is displayed after running though AppDelegate so I dont quite understand why it does just do the following:
#property (nonatomic, strong) IBOutlet MainViewController* viewController;
I amended the code like above, and it works perfectly. Is there any reason why it uses the CDViewController instead of MainViewController :S?
Thanks
MainViewController is a subclass of CDVViewController, therefore more generic and less confusing.

iOS - keeping a reference to the main UIViewController in a static singleton class

I have a static singleton class that I use to access the main UIViewController (which is created by the appdelegate), and through it all sub-UIViewControllers.
Here's how I declare it
#interface mySingleton : NSObject
{
ViewController* m_viewController;
}
#property (nonatomic,assign) ViewController* m_viewController
And in the .m file, I get this error:
#synthesize m_viewController; // ERROR: Existing ivar "m_viewController" for unsafe_unretained property "m_viewController" must be __unsafe_unretained.
I solve this by putting __unsafe_unretained in the declaration as the error says, however..
is there any problems for me keeping a __unsafe_unretained property on the m_viewController? It represents the main menu of the app, and should never be deallocated. So it being a dangling pointer should never a problem due to it being released by the AppDelegate later on, right?
If you don't want m_viewController to be released, why not use strong instead of assign?
Also, since it's generally the app delegate that allocates the main view controller, and since the app delegate is accessible via the UIApplication singleton, why not keep the reference to the main view controller there instead of creating a separate class just to do that?

Resources