Is it possible to get a NSArray from AppDelegate? - objective-c

Is it possible to get a NSArray from my AppDelegate? I need to send a array to other classes. And that array is generated in my AppDelegate. Thanks!

First of all you should have to alloc and init
In AppDelegate.h file
#property(nonatomic,retain)NSArray *books;
In AppDelegate.m file your array, then You can add objects in it.
_books = [[NSArray alloc]initWithObjects:#"test",#"test", nil];
You should have to create AppDelegate instance in your BooksDetailViewController like this,
in .h file
AppDelegate *appDelegate;
and in .m file
appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
Now you can access your array like this,
NSLog(#"Test Log :%#",appDelegate.books);
Output :
2016-07-14 13:04:08.211 Gridz[2490:39240] Test Log :(
test,
test
)

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
Now you can use any property or method like:
[appDelegate myProperty] or [appDelegate myMethod]
Hope this helps

It is possible to get the NSArray from AppDelegate to other classes.
AppDelegate.h
#import <UIKit/UIKit.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate> {
}
#property (nonatomic, strong) UIWindow *window;
#property (nonatomic, strong) ViewController *viewController; //For Xib
#property (nonatomic, strong) NSArray *arrayObjects;
#end
AppDelegate.m
#import "AppDelegate.h"
#import "ViewController.h"
#implementation AppDelegate
#synthesize arrayObjects;
As I use Xib, I set the root view controller in below method.If you use stroy board, it is enough to add NSArray objects only.Don't need to set the root view controller.
//For XIB
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
arrayObjects = [[NSArray alloc]initWithObjects:#"Steve",#"jobs",#"Tim",#"Cook",nil];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
self.window.rootViewController = navController;
[navController setNavigationBarHidden:YES];
[self.window makeKeyAndVisible];
return YES;
}
//For Storyboard
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
arrayObjects = [[NSArray alloc]initWithObjects:#"Steve",#"jobs",#"Tim",#"Cook",nil];
return YES;
}
Then in ViewController.m
You can also import the AppDelegate in ViewController.m
#import "ViewController.h"
#import "AppDelegate.h"
#interface ViewController ()
#end
#implementation ViewController
Now in viewDidLoad method
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
AppDelegate *delegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
NSLog(#"The app delegate NSArray Objects are - %#",delegate.arrayObjects);
}
The NSLog results are
The app delegate NSArray Objects are - (
Steve,
jobs,
Tim,
Cook
)

Related

Need help trying to implement react-native-firebase to my detached expo project

As title says I tried add some code in my detached expo project to receive push notification using react-native-firebase.
I kinda new to obj-c and iOS environment, so this could be silly question. But I couldn't find the solution in stackoverflow.
so my question is this: can I add UIResponder protocol with my existing protocol: EXStandaloneAppDelegate?
my AppDelegate.m
#import "AppDelegate.h"
#import <Firebase.h>
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#implementation AppDelegate
// Put your app delegate methods here. Remember to also call methods from EXStandaloneAppDelegate superclass
// in order to keep Expo working. See example below.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure];
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
// here the problem merges: Sending 'AppDelegate *const __strong' to parameter of incompatible type 'id<RCTBridgeDelegate>'
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:#"push"
initialProperties:nil];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:#"index" fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:#"main" withExtension:#"jsbundle"];
#endif
}
#end
my AppDelegate.h
#import <UIKit/UIKit.h>
#import <ExpoKit/EXStandaloneAppDelegate.h>
#import <React/RCTBridgeDelegate.h>
#import <UIKit/UIKit.h>
#interface AppDelegate : EXStandaloneAppDelegate <UIApplicationDelegate> UIResponder <UIApplicationDelegate, RCTBridgeDelegate>
#property (nonatomic, strong) UIWindow *window;
// this gives me an error
'Prefix attribute must be followed by an interface or protocol'
#end
#interface Appdelegate should takes UIresponder protocol, not only EXStandaloneAppDelegate.

Setting the view programmatically

I am trying to set my project without using storyboards in xcode and with objective c.
My appDelegate:
.h
#import <UIKit/UIKit.h>
#import "ViewController.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#end
.m
#import "AppDelegate.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
ViewController *vc = [[ViewController alloc] init];
self.window.rootViewController = vc;
return YES;
}
etc...
My viewController file:
.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
view.backgroundColor = [UIColor redColor];
[self.view addSubview:view];
}
I think my code is right and we should have a red screen when I run it, but I only get a black screen. Can someone tell me if I have forgotten something or is it something to do with the project settings. Thanks.
Add
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
to your application:didFinishLaunchingWithOptions:
You are missing two steps.
Initialize the window:
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
Make the window key & visible:
[self.window makeKeyAndVisible];
So all together, your code should look like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Initialize the window
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
// Add the view controller to the window
ViewController *vc = [[ViewController alloc] init];
self.window.rootViewController = vc;
// Make window key & visible
[self.window makeKeyAndVisible];
return YES;
}

how to give action to UIButtoun Outlet from another UIViewController

I have two UIViewController class with names : (RootViewController & SecondViewController).
I have one UIButton Outlet in my SecondViewController.now I want give action method to my UIButton in RootViewController.but I don't know about it.
please guide me and tell me how to get my UIButton in another View and give action method on it in another View....
I'm not sure why you are doing this, it doesn't look good.
Anyway, here's the way.
SecondViewController.h
#interface SecondViewcontroller:UIViewController
#property (nonatomic, weak) IBOutlet UIButton *theButton;
#end
RootViewController.m
SecondViewContoller * sv = [[SecondViewController alloc] init];
[sv.theButton addTarget:self action:#selector(buttonHandler:) forControlEvents:UIControlEventTouchUpInside];
You have to removeTarget when you've done with the button.
Why don't you use delegate or block callback?
ADDED
delegate
SecondViewController.h
#protocol SecondViewControllerDelegate <NSObject>
- (void)theButtonPressed;
#end
#interface SecondViewController : UIViewController
#property (nonatomic, strong) id<SecondViewControllerDelegate>delegate;
#end
SecondViewController.m
#interface SecondViewController ()
{
UIButton *theButton;
}
#end
#implementation SecondViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[theButton addTarget:self.delegate action:#selector(theButtonPressed) forControlEvents:UIControlEventTouchUpInside];
}
#end
RootViewcontroller.h
#interface RootViewController : UIViewController <SecondViewControllerDelegate>
#end
RootViewController.m
SecondViewController *sv = [[SecondViewController alloc] init];
[sv setDelegate:self];
and
- (void)theButtonPressed
{
}
block
SecondViewController.h
typedef void(^TheButtonTouched)(void);
#interface SecondViewController : UIViewController
- (void)addButtonEvent:(TheButtonTouched)event;
#end
SecondViewController.m
#interface SecondViewController ()
{
UIButton *theButton;
TheButtonTouched buttonBlock;
}
#end
#implementation SecondViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// button alloc init here and..
[theButton addTarget:self action:#selector(buttonEvent:) forControlEvents:UIControlEventTouchUpInside];
}
- (void)buttonEvent:(UIButton *)sender
{
if(buttonBlock)
{
buttonBlock();
}
}
- (void)addButtonEvent:(TheButtonTouched)event
{
buttonBlock = event;
}
#end
RootViewController.m
SecondViewController *sv = [[SecondViewController alloc] init];
[sv addButtonEvent:^{
// ADD SOMTHING HERE
}];
You need to create the button's iboutlet property.
Than using object of secondclass.button name you can assign selector.
[classobjectname..btnname addTarget:objectname.class action:#selector(objectname.methodname:);
Just Create RootViewController 's Object and passed into target parameter.
e.g.
[btnShow addTarget:self.rootCtrlObj action:#selector(viewPhoto_click:)
forControlEvents:UIControlEventTouchUpInside];
where rootCtrlObj is #property inside SecondViewController.h file
and when you push this controller in RootViewController you have to pass reference of RootViewController .
For Example,
secVCObj.rootCtrlObj = self;
[self.navigationController pushViewController:secVCObj animated:YES];
as i said custom delegate methods will work perfect for these cases,
in SecondViewController.h file define a custom delegate method like below
#import <UIKit/UIKit.h>
#import "ViewController.h"
#protocol SecondControllerDelegate<NSObject>
- (void)someActionToPerformInRootController;
#end
#interface SecondViewController : UIViewController
#property (nonatomic, assign) id<SecondControllerDelegate>delegate; //declare a custom delegate
#end
in SecondViewController.m file lets take an action of some button
- (IBAction)myButtonActionMethod:(id)sender
{
if([self.delegate respondsToSelector:#selector(someActionToPerformInRootController)])
{
[self.delegate someActionToPerformInRootController]; //this will call the delegate method in first view conroller( root view controller) //do what ever u want t do in the action method of rootviewcontroller
}
}
in RootViewController.h file
#import "SecondViewController.h"
#interface RootViewController : UIViewController < SecondControllerDelegate> //confirmas to delegate
in RootViewController.m while presenting the SecondViewController set the delegate to self
- (IBAction)showAction:(id)sender
{
SecondViewController *secondController = [[SecondViewController alloc]initWithNibName:#"SecondViewController" bundle:nil];
secondController.delegate = self; //call back to this controller
[self presentViewController:secondController animated:YES completion:nil];
}
//this method called from the secondViewcontroller
- (void) someActionToPerformInRootController
{
NSLog(#"perform action in root view controller");
}

Impossible to presentViewController

I've created a new application view based.
Here some the main code:
// AppDelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate>
{
UINavigationController *navigationController;
MIAPreferences *preferences;
}
#property (strong, nonatomic) UINavigationController *navigationController;
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) MIAPreferences *preferences;
// AppDelegate.m
#implementation AppDelegate
#synthesize window = _window;
#synthesize navigationController;
#synthesize preferences;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];
// Override point for customization after application launch.
UIViewController *rootController = [[HomeViewController alloc] initWithNibName:nil bundle:nil];
navigationController = [[UINavigationController alloc]
initWithRootViewController:rootController];
navigationController.navigationBar.hidden = YES;
self.window = [[UIWindow alloc]
initWithFrame:[[UIScreen mainScreen] bounds]];
_window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
return YES;
}
// HomeViewController.m
-(IBAction)openLogin
{
LoginViewController *view = [[LoginViewController alloc] initWithNibName:nil bundle:nil];
// 1
[self.navigationController presentViewController:view animated:YES completion:nil];
// 2
[self.navigationController pushViewController:view animated:YES];
// 3
[self presentViewController:view animated:YES completion:nil];
}
All 3 options returns a EXC_BAD_ACCESS (code=2, address=....)
Can you please help me understand how to solve this?
UPDATE
The problem was due to a UIButton apparence set up during AddDelegate loading....but the first button was in the UIView I was going to load... that's why it crashed -.-"
It could either mean: (1) The pointer used to point to memory that was ok, but its chunk was deallocated or (2) The pointer is corrupt. You can try to use zombie mode, if you aren't already, to get more information. In XCode press the Command, option, and I keys and a screen should pop up. Selected the Run option in the left hand side, then Diagnostics, and under memory management enable zombie objects should be checked.
Check the value of view after initWithNibName:. init'ing with a nil nib name looks wrong to me, and you may be trying to push a nil view controller onto your navigation stack.

iphone changing the initial scene

In my iphone application I have two scenes, both of them are view controllers.
Normally initial scene is set to the first one. When user plays it passes to the second one.
At this point when the user closes the app and restarts it, if the user has already played, it should start with the second scene, so the initial scene should change for that user.
How can I do this?
And i dont use a navigation controller.
If you are using xibs, you set this up in the app delegates
applicationDidFinishLaunchingWithOptions.
Create a global BOOL and check it's value on applications launch, E.g:
.h
#class ViewController;
#class SecondViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) ViewController *viewController;
#property (strong, nonatomic) SecondViewController *SecondViewController;
.m
#import "ViewController.h"
#import "SecondViewController.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
if (isSecondViewControllerBool == YES) {
self.SecondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
}else{
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
}
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
For storyboards:
In the first view controllers viewDidLoad.
- (void)viewDidLoad
{
if (isSecondViewControllerBool == YES) {
UIViewController *secondVC = [self.storyboard instantiateViewControllerWithIdentifier:#"mySecondViewController"];
[self presentViewController:secondVC animated:NO completion:nil];
}else{
//present normally
}
}
If you are using storyboards and have decided to use my xib solution, delete the storyboard from the project, and remove it here as well: