I have some existing code in ObjC that I would like to use in a MonoTouch app. I am creating a static lib from the existing code and then using binding to access and use it from the MonoTouch app. Everything is working great except when I attempt to bind to a type derived from NSManagedObject. For some reason it cannot find the property. I get an "unrecognized selector sent to instance" error. I'm guessing it has something to do with #dynamic, but I'm not sure and couldn't find any documentation regarding why this doesn't work.
.h
#interface MyNSManagedObject : NSManagedObject
#property (nonatomic, retain) NSString *clientName;
#end
.m
#implementation MyNSManagedObject
#dynamic clientName;
#end
Related
I am hoping someone can help with this issue that I am having using monotouch with xib files.
I am trying to create a subview derived from uiview. In IB I create a class, set its type to that of my custom class, and then link all of the IBOutlets to the custom class (this is where I think the error may be, as I suspect this should be the files owner).
A IB .h file example is
#interface ActivityUtilityView : UIView {
UILabel *_ActivityLabel;
UILabel *_CaptionLabel;
}
#properrty (nonatomic, retain) IBOutlet UILabel * ActivityLabel;
#properrty (nonatomic, retain) IBOutlet UILabel * CaptionLabel;
#End
In the application code this view needs to be loaded at run time using.
var intptr = NSBundle.MainBundle.LoadNib("ActivityUtilityView",parent_controller,null).ValueAt(0);
m_ActivityView = new ActivityView(intptr);
The first issue is that none of the IBOutlets are instantiated.
The second issue is that the view is being created twice, from what I can tell.
Please can anyone help?
EDIT
I have discovered that half the problem is that the outlets are not instantiated until the view is displayed.
So how can I force a subview to be displayed?
I found a solution that works.
m_ActivityView = Activator.CreateInstance<ActivityUtilityView>();
var view = NSBundle.MainBundle.LoadNib("ActivityUtilityView",m_ActivityView,null);
m_ProgressView = Runtime.GetNSObject(views.ValueAt(0) as ActivityUtilityView;
Creating the view using the IntPtr constructor does not instantiate the IBOutlets until the view has been displayed. This method appears to.
To clarify the issue arrose due to a race condition on background worker threads.
New to iOS dev. Kindly correct me if i am wrong?
I have a UIWindow, and rootviewcontroller is :
#interface ViewController : UIViewController
{
IBOutlet UIButton *but;
}
#property (nonatomic, strong) UIButton *but;
-(IBAction) butButtonPressed;
#end
ie: If i make this Viewcontroller as a root view controller, the UIView that is available in the ViewController is displayed. Understood.
I have created a new class inherited from UIViewController, and along with its .xib file.
So xib file name is : view1.xib,
My Objective is to display this view when the button is pressed.
Now i have created a button and button press invokes butButtonPressed. Inside of butButtonPressed, i did the following.
myViewController *vcontroler = [[ViewController alloc] initWithNibName:#"view1" bundle:nil];
[self.view.window addSubview:vcontroler.view];
Application crashes. What am i doing wrong ? Kindly point out.
This...
[self.view.window addSubview:vcontroler.view];
...is a really bad strategy (and I seriously wish I knew where people are finding it as a way of showing views). If you create a view controller, you should use it rather than just treating it as a temporary container that you can rip views out of.
If you want vcontroler to look like a child of your first controller (and you have a UINavigationController), use pushViewController:animated:. Otherwise you can show it as modal with presentModalViewController:animated:.
If you only want to add a view to the existing display, put the view in ViewController's hierarchy and show/hide it.
If you absolutely must have it as a sub-controller of ViewController then you need to keep a reference to it and manage its lifecycle inside the owning controller.
Reading through Apple's docs here, the example code declares the primitive accessor and mutator as separate methods in a category. Is it possible to use #property to declare the primitives? Is there a disadvantage to do it this way; it seems like it saves boiler plate code, but are there performance implications in the way the methods are generated when declared this way? What are the optional attributes - (strong, nonatomic)?
Apple's Example Code
#interface Department : NSManagedObject
#property(nonatomic, retain) NSString *name;
#end
#interface Department (PrimitiveAccessors)
- (NSString *)primitiveName;
- (void)setPrimitiveName:(NSString *)newName;
#end
Suggested Change
#interface Department : NSManagedObject
#property(nonatomic, retain) NSString *name;
#end
#interface Department (PrimitiveAccessors)
#property (strong, nonatomic) NSString *primitiveName;
#end
You should generate classes for your Core Data entities automatically. You do this by pressing the Editor menu and selecting "Create NSManagedObject subclass". This will automatically create a class for each of your entities, and those will have the properties you want.
If you want to customize these classes I strongly recommend that you do it in a category. I recommend this because, you may want to go back to your datamodel and add or remove an attribute, and thus you will have to generate new subclasses. In that event, any changes you may've made to the subclasses will be overwritten and that can be painful :)
I need to sort I need to subclass NSDate to add a tag, I don't need to change its behaviour, do I still need to implement my own:
(NSTimeInterval)timeIntervalSinceReferenceDate
(id)initWithTimeIntervalSinceReferenceDate:(NSTimeInterval)seconds;
as stated in apple's documentation? If so, how do I do it?
currently I just created a class extends NSDate with a tag attribute, but how do I initialise it?
Thanks!
NSDate is a class cluster, not a simple class. It is not wise to subclass a class cluster unless you know exactly what you are doing; see How do I subclass NSDate?
I would recommend that you create your own class containing an NSDate and a tag, and extend as needed:
#interface MyClass : NSObject {
NSDate *_date;
NSUInteger _tag;
}
#end
Add the appropriate properties, etc for easy dot-notation access.
I am just getting started with the CoreData API and am following a few tutorials. I get the basics of storing and retrieving objects, but am having trouble connecting all the pieces in terms of MVC.
I have a CustomView into which I draw some stuff with CoreAnimation, including some text layers that will get their strings from an NSManagedObject. I started with a basic CoreData application template so the managedObjectContext etc are declared in the appDelegate, and I'm just not sure how I should be getting data from the CoreData stack into the view. By the way, this is all in code, not interface builder.
So my question is, if I want to build my app in a pure MVC way, how should I go about getting data from the stack into the view? How should I give my view access to the initialized NSManagedObjectContext, for example?
I have been reading Cocoa Design Patterns but am a bit of a dunce when it comes to MVC. I know its a pretty general question, but if someone can just say, "set the delegate, grab a pointer..." whatever it is, that would be great!
Thanks in advance!
So I did some more poking around and it seems the easiest way to do this is to get a pointer to the AppDelegate and then a pointer to the managedObjectContext. From there, execute a fetch request and put it into your view!
In a good tutorial Björn Sållarp does it this way:
From the app delegate he creates the rootViewController and sends it the context with:
RootViewController *rootViewController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain];
rootViewController.managedObjectContext = context;
rootViewController.entityName = #"Counties";
In the rootViewController's h file you declare:
NSManagedObjectContext *managedObjectContext;
Create its property:
#property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
and in m you
#synthesize managedObjectContext;
Then its there for your use.