NSInvocation problems - xcode

So I am running into some issues when I am trying to load information from a file.
myMutableArray=[[NSKeyedUnarchiver unarchiveObjectWithFile:dataFile]retain];
This is the line that gives me the NSinvocation problems
* NSInvocation: warning: object 0xf9f500 of class 'myClass' does not implement methodSignatureForSelector: -- trouble ahead
* NSInvocation: warning: object 0xf9f500 of class 'myClass' does not implement doesNotRecognizeSelector: -- abort
I have looked through other questions and other sites to try and find an answer.myClass does inherit from NSObject, and my customer view controller inherits from UIViewController. My customer view controller implements the code above. The save file I am loading from does exist. Not sure what I need to do for this, any help would be appreciated thanks!

So I had an issue within myClass that I was not encoding something but I was trying to decode it after. I just had to add a line of code and delete my old save file.

Related

Use a class in two different project : decoder exception

I have an exception using this code ;
let readingData = NSKeyedUnarchiver.unarchiveObjectWithData(data) as? [ExternalProjectClass]
The message in the console :
cannot decode object of class (MyIOSApp.ExternalProjectClass) for key (NS.objects); the class may be defined in source code or a library that is not linked'
I use 'ExternalProjectClass' class in 2 project in the same workplace. In MyApp application (mac version). Otherwise I can use my class normally, I only have problems with coding.
I know how poor is my english. I hope somebody can help me.
Regards.
Swift class names have namespaces, and the default namespace is module name. So if you move the archive from an app to another, the class name differs.
You could put #objc(ExternalProjectClass) attribute on your class, so it is called ExternalProjectClass as far as NSCoder considers.
#objc(ExternalProjectClass) class ExternalProjectClass: NSObject, NSCoding { ... }

Implementing a NSService method

I created a Service for my app, the menu appears correctly, but I still have a problem with the method called when the menu item is activated.
In AppDelegate.swift I have:
func applicationDidFinishLaunching(aNotification: NSNotification) {
NSApplication.sharedApplication().servicesProvider = ServiceProvider()
NSUpdateDynamicServices();
}
And the class ServiceProvider is:
import Cocoa
class ServiceProvider {
func serviceTest(pasteboard: NSPasteboard, userData: String, error: NSErrorPointer) {
// code here
}
}
When the service is activated I want to send some information to the components of my app, for example, to change the text of a label. How can I do this? I tried to get the mainWindow inside the function serviceTest to access its components, but it returned nil.
I am trying to do something similar to the Safari service that you select some text, and right-click > services > search with google. This open Safari and search for the selected text. Or something similar to add a new task to Wunderlist, that gets the selected text and create a new task in the app.
I really appreciate some help to solve this issue.
This is just the general problem of getting access to objects in various parts of a program. There are two general mechanisms: start with a well-known object or have the object(s) you need passed in to you by the part of the code which knows about both object.
For example, you can get to the application delegate using NSApplication.sharedApplication().delegate. You would then cast it to your custom app delegate class and access its properties.
However, it's probably better to avoid relying on pseudo-global variables if there's a simple alternative, and there is. Give your ServiceProvider class the necessary properties to track the objects it needs (like the app delegate). In the app delegate code which creates the ServiceProvider instance, simply set those properties. That may be in statements to set properties after it has been created or you could pass it in to the initializer method as an argument. Obviously, you'd need to declare that initializer method to take the argument and store it in your instance variable.

what does "failed to load window nib file" mean?

I'm working on my first Cocoa application, and I'm hoping very much that
[NSWindowController loadWindow]: failed to load window nib file 'Genius Document'
means that there's something very specific I've done wrong, because if I have to go back and redo all the bindings I'll want to kill myself.
FWIW, I'm working with a document-based application that has (so far) only one XIB file and no NIB files.
I can post code/screenshots of my bindings but in case that's not necessary I didn't want to make people wade through them.
Thanks for the help.
The error you have described ultimately occurs because a call to load the nib file is failing. Make sure you've supplied the correct name for your Interface Builder file.
You can supply the correct value in a number of ways (depending on your use of AppKit), so I'll lay out the two most common possibilities and you can track down which one applies to you. Given what you've said in your question, I suspect you'll be dealing with the first scenario.
NSDocument windowNibName
If you are relying on the document architecture's defaults, you are probably not making the call in question directly. Instead, the framework makes the call on your behalf, using whatever nib name you specify on the given document class.
For example, if you were to make a new document-based project with a document class of "XYZDocument," the Xcode template would provide you with a basic XYZDocument class and a XYZDocument.xib file. The XYZDocument implementation file would have the following in it:
// XYZDocument.m
- (NSString *)windowNibName {
return #"XYZDocument"; // this name tells AppKit which nib file to use
}
If you were to alter this value, you would create the [NSWindowController loadWindow] error.
NSWindowController initialization methods
If you are making this call yourself (perhaps on your own subclass of NSWindowController), then you will have written a line like the following.
// XYZWindowController.m (a subclass of NSWindowController)
- (id)init {
self = [super initWithWindowNibName:#"XYZDocument"];
if (self) {
// initializations
}
return self;
}
If the string argument you've supplied does not match the name of the nib file, the same error will occur.
I ran a Clean (Cmd-Shift-K) in Xcode and that solved the issue for me.

Xcode Updating a table from another method

I have a code_tab.m file which deals with the UI and code.m file which does the crunching of data and also updates a MutableArray. When the code.m updates the array I want to update the table in view linked to the connection_tab.m. I have a function in code_tab.m that has a:
[self.table tableupdate]
Which works as expected when called internally. When the same function is called from the code.m file (when the array has been updated) nothing happens even though I can see the same code is being accessed.
I have setup access by having this line in the code.h file:
connection_tab* connectiontab_script;
and then calling it in code.m with
connectiontab_script = [[connection_tab alloc] init];
[connectiontab_script tableupdate];
I've obviously missed something vital. Is there a way that one method can alter the visual display of another, in this case update the table already on screen?
Technically you should avoid having your data class make calls to methods in your view as it will likely cause you headaches in future, MVC is the recommended development practice.
However, you could achieve what you're trying to do by amending your initNetworkCommunication method in code to pass a reference to the active view through:
- (void) initNetworkCommunicationForView:(UIViewController*)passedVC
Which you'd call from inside connection_tab like:
[appDelegate.connection_script initNetworkCommunicationForView:self];
Then in code you'd do (if statement avoids warnings):
if ([passedVC respondsToSelector:#selector(tableupdate)]) {
[passedVC performSelector:#selector(tableupdate)];
}
Depending on the structure of your code class you may need to create a class-wide variable to store passedVC in if the tableupdate call isn't within initNetworkCommunication.
P.S You could also customize the method to be specific to your connection_tab class like:
- (void) initNetworkCommunicationForView:(connection_tab*)passedCT
Then you could ditch the selector stuff and go with:
[passedCT tableupdate];
But I went with UIViewController for compatibility reasons.

How to programmatically setObjectClass for NSArrayController

I'm having a problem with what should be a very simple thing. I want to create an NSArrayController and specify the class it manages. Problem is, I can't figure out the correct way to specify the Class in the setObjectClass method. I want to do the following:
[projectArrayController setObjectClass:SKHProject];
SKHProject is a class that I've imported in the implementation file. I keep getting the "Expected expression before 'SKHProject'" error, but I can't figure out the correct expression. Where am I going wrong?
Do
[projectArrayController setObjectClass:[SKHProject class]];
!
Just found it
[projectArrayController setObjectClass:[SKHProject class]];
Thanks anyway
You can only use a class name as the receiver of a message; you can't use it in any other context. So, to pass the Class somewhere, send it a message asking it for itself: [SKHProjectClass class].

Resources