Extending UILocalNotification [duplicate] - objective-c

I beginner in iOS. I try extend UILocalNotification. My class below.
#interface FSCustomNatification : UILocalNotification
typedef enum {
FSCustomNatificationPay,
FSCustomNatificationWrite,
FSCustomNatificationSend
} NotificationTypeT;
#property (nonatomic, assign) NotificationTypeT typeNotificationT;
#end
#import "FSCustomNatification.h"
#implementation FSCustomNatification
#end
When I set typeNotificationT property I get -[UIConcreteLocalNotification setTypeNotificationT:]: unrecognized selector sent to instance 0x8144780. Why?
FSCustomNatification* localNotification = [[FSCustomNatification alloc] init];
localNotification.typeNotificationT = FSCustomNatificationWrite;

By the looks of your error message UILocalNotification is part of a class cluster. The docs don't say (that I can see quickly) but it seems unlikely that you should subclass UILocalNotification.
Instead, you should make use of the userInfo provided by UILocalNotification to add any extra information you want to be available when the notification fires.

Related

Sending a message to an instance method from inside a block

I am relatively new to Cocoa programming. Basically, I want to send a message within a method in my Document class to an intense of a class (that inherits from NSView) that I have initialised as a property in the #interface of the Document class.
Here is the simplified version:
///////////////////////////KOZDocument.h///////////////////////////
#import <Cocoa/Cocoa.h>
#import "KOZOtherClass.h"
#interface KOZDocument : NSDocument
#property (assign) IBOutlet KOZOtherClass *otherClassInstance; //this would be connected to the relevant CustomView in the IB
#end
///////////////////////////KOZDocument.m///////////////////////////
#import "KOZDocument.h"
#implementation KOZDocument
- (id)init
{
self = [super init];
if (self) {
// I want to send a message to otherClassInstance from some method e.g. init
NSLog(#"INITIALISING");
[[self otherClassInstance] printMessage];// this is the message I want to work but which doesn't (even though i don't any errors)
//sending the message to a locally initiated instance works but I don't want to use a local instance because i want to connect it to a CustomView in IB
KOZOtherClass *otherClassLocalInstance = [[KOZOtherClass alloc] init];
[otherClassLocalInstance printMessage];
}
return self;
}
//.….
///////////////////////////KOZOtherClass.h///////////////////////////
#import <Foundation/Foundation.h>
#interface KOZOtherClass : NSView
- (void) printMessage;
#end
///////////////////////////KOZOtherClass.m///////////////////////////
#import "KOZOtherClass.h"
#implementation KOZOtherClass
- (void) printMessage{
NSLog(#"This method can be called!!");
}
#end
/////////////////////////////////////////////////////////////////////
The same methodology works for all the native Cocoa objects but not for mine.
Can anyone tell me what I'm doing wrong?
Here is the context of why i want to do this:
I am building an app that plays a video using the AVFoundation. I have an animation I want to trigger in an NSView when the playback reaches a particular part in the video (e.g. after 2 seconds). I am adapting Apple's AVSimplePlayer and using the time observer to get the position of the playhead. The time observer executes the code inside a block for every given time interval. In this block I want to send a message to my animation view to trigger the animation when the time is more that 5 seconds for example.
In -init of your objects the Interface Builder connections are not set yet, the loading mechanism can't set those before your object is initialized.
Instead you want to overwrite the -awakeFromNib method like so:
- (void)awakeFromNib {
[[self otherClassInstance] printMessage];
}
-awakeFromNib is guaranteed to be called after the connections have been made. Depending on the exact implementation you may also need to guard against that code being executed twice, for example by having a boolean instance variable didWake that you check/set in that method.

How to use #property correctly (Setters) within another class

another question i'm trying to use a setter within another class but I seem to get this odd error here is the code below:
AppDataSorting.h
#import <Foundation/Foundation.h>
#interface AppDataSorting : NSObject{
NSString *createNewFood;
NSNumber *createNewFoodCarbCount;
}
#property (readwrite) NSString *createNewFood;
#end
AppDelegate.m
#import "AppDelegate.h"
#implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
}
- (IBAction)saveData:(id)sender {
NSLog(#"%#", self.foodName.stringValue);
self.createNewFood = self.foodName.stringValue;
NSLog(#"%.1f", self.carbAmount.floatValue);
}
#end
I get the error message in AppDelegate.m which is: Property 'createNewFood' not found on object of type 'AppDelegate *'
Could someone please explain the issue here?
You declare this property:
#property (readwrite) NSString *createNewFood;
In AppDataSorting.h so you can access it like self.createNewFood in AppDataSorting.m file not AppDelegate.m. If you want to call it as you do in AppDelegate.m you have move this line:
#property (readwrite) NSString *createNewFood;
to AppDelegate.h file.
Or if you want to use property from AppDataSorting class in AppDelegate you have to create object and call it on that object:
- (IBAction)saveData:(id)sender {
NSLog(#"%#", self.foodName.stringValue);
AppDataSorting *dSorting = [[AppDataSorting alloc] init];
dSorting.createNewFood = self.foodName.stringValue;
NSLog(#"%.1f", self.carbAmount.floatValue);
}
In -saveData:, self refers to an instance of NSAppDelegate. The createNewFood property is defined on instances of the class AppDataSorting.
Also note that Cocoa/CF naming conventions give special meaning to methods that start with "init", "new" and (to a lesser degree) "create". You probably want to avoid such things in your property names. Details here.
In general, properties should represent conceptual "properties" of an object. So if you had a Person class, it might have a name property, but it wouldn't have a createNewOutfit property.
You need to access createNewFood on an instance of AppDataSorting - but you're trying to access the property on the AppDelegate-class which clearly doesn't implement it.
So you would need to create an instance of AppDataSorting and then access the property like so:
AppDataSorting *instance = [[AppDataSorting alloc] init];
instance.createNewFood = self.foodName.stringValue;
Final notes:
The docs provide a good base of information
If you don't need atomicity you should always declare properties with the nonatomic attribute
createNewFood is not a good name for a property since it suggests a method which creates new food - yet it's only meant to store data (in this case an NSString instance)

NSObject call to self gives XCode error

I have a class WebServices that inherits from NSObject. I am using xcode4.2 and ARC turned on.
When I created the class, there was no other method in the NSObject lie viewDidLoad or init.
The issues is that when I try to call self.something or [self someMethod] Xcode flags my code red and complains with:
implicit conversion of Objective-C pointer type 'Class' to C pointer type 'struct obj_class*' requires a bridge cast
Please help. Why isn't cocoa like java where you call "this" and get the object you are in?
// WebService.h file
#interface WebService : NSObject
#property (weak, nonatomic) NSString * myString;
+(void) setAndPrintMyString:(NSString*) someString;
#end
//WebService.m file
#import "WebService.h"
#implementation WebService
#synthesize myString=_myString;
+(void) printMyString:(NSString*) someString{
[self setMyString:someString]; //XCode does not allow
NSLog(#"myString is set to %#",self.myString); //XCode dose not allow
}
#end
Declaring a method with + means that it is a class method. Within a class method self refers to the class itself, which in your case would be [WebService class]. If you declared and instance method (using -) then inside the method self would refer to the instance, which is what you want.
To set an instance variable - you need an instance
WebService *webService = [[WebService alloc] init];
webService.myString = #"some string";
Now to make your method work you need to declare it with a - instead of + which makes it an instance method
- (void)printMyString:(NSString *)someString
{
[self setMyString:someString];
NSLog(#"myString is set to %#",self.myString);
}
Now
[webService printMyString:#"boom"];
results in the instance variable myString being set to boom and the console logging out `myString is set to boom".
viewDidLoad method doesn't fit with NSObject subclass. It's a method for UI which will be there in UIViewController subclasses.
Now, Coming to point about self.something OR [self someMethod], That works perfectly well with NSObject subclasses. You need to show us the code, in which you are facing problem.
Just for your reference (I think you should start developing for iOS after going through this):
NSObject Class Reference
UIViewController Class Reference

Subclassing UILocalNotification for property addition

I tried to cancel localNotifications with specific tag number. It's my favorite manner to use tag number for compare logic.
So, I subclassed UILocalNotification and add property NSInteger tag. Then use the subclass instance for scheduling localNotification.
CustomNotification *customNoti = [[CustomNotification alloc] init];
customNoti.fireDate = myDate;
customNoti.timeZone = [NSTimeZone defaultTimeZone];
customNoti.tag = self.tag; // crash
// error : -[UIConcreteLocalNotification setTag:]: unrecognized selector sent to instance 0x75a3630
Here is CustomNotification.h file
#import <UIKit/UIKit.h>
#interface CustomNotification : UILocalNotification
#property (nonatomic, assign) NSInteger tag;
#end
Why is it crash and 'unrecognized selector' message shown? Is UILocalNotification class special? I can't find any missed code.

Variable access in multiple classes

I have a Cocoa project with an object that holds information from a SQLite database.
By now the information is stored in memory by this object and is used in the user interface to read and write new information.
But now I came to a small problem... I decided to create a new controller class to handle the actions of an NSTableView and I want to access this same database object that was declared elsewhere.
Which is the best option to access this information? I wish to avoid loading the information more than once in memory and also avoid use pure C/C++ codes with global variables.
It is better to understand my point by looking at the code.
I accept other solutions as well, naturally.
My idea of code is currently like this:
FirstClass.h
#import <Foundation/Foundation.h>
#import "DatabaseModel.h"
#interface FirstClass : NSObject {
IBOutlet NSScrollView *informationListTable;
NSMutableArray *informationList;
}
#end
FirstClass.m
#import "FirstClass.h"
#implementation FirstClass
- (void)awakeFromNib{
DatabaseModel *list = [[DatabaseModel alloc] init];
informationList = [[NSMutableArray alloc] initWithArray:[list loadList]];
[list release];
[machinesListTable reloadData];
}
SecondClass.h
#import <Foundation/Foundation.h>
#interface SecondClass : NSObject {
IBOutlet NSTextField *labelName;
NSString *name;
}
- (IBAction)showName:(id)sender;
#end
SecondClass.m
#import "FirstClass.h"
#import "SecondClass.h"
#implementation SecondClass
- (IBAction)showName:(id)sender{
/*
Here name must get something like:
[[FirstClass.informationList objectAtIndex:3] name]
Here labelName must display name.
*/
}
#end
you can either create the object once then pass the object around, with each controller retaining it as needed. Or you can use a singleton instance. I would say the singleton instance is easier to read, but it depends on the application
One solution would be to make FirstClass a singleton. Then, anywhere else in your code, you could call [FirstClass sharedInstance] (replace sharedInstance with the name you'll give to your class method) and use this object. You'll have to be careful about concurrency issues though.