Before I was using NSNotificationEvents, but as I know I should be using delegate because of 1:1 relations (it will be used only in one place in code).
Basically Im new to objective-C and swift (Im JavaScript guy) and the code that I created after a few hours of reading and checking - it just doesnt work, because self.delegate in not defined.
Im trying to delegate "an event" from objective-C code to swift code. NSNotificationEvents works like charm, but I want to make it with protocols / delegate.
I guess, I just missing how to exactly initialize the delegate protocol.
ProtocolDelegate.h
#import <Foundation/Foundation.h>
#protocol ProtocolDelegate <NSObject>
- (void) delegateMethod: (id)data;
#end
Event.h
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import "ProtocolDelegate.h"
#interface Event : NSObject <RCTBridgeModule, ProtocolDelegate>
#property(nonatomic, weak)id <ProtocolDelegate> delegate;
#end
Event.m
(someMethod is executed from JavaScript React-native code, but it shouldn't be any difference from what I know)
#import "Event.h"
#implementation Event
RCT_EXPORT_MODULE(Events);
RCT_EXPORT_METHOD(someMethod: (NSString*)parameter) {
NSDictionary* data = #{#"parameter": parameter};
NSLog(#"This I can see");
if ([self.delegate respondsToSelector:#selector(delegateMethod:)]) {
NSLog(#"This I can not see");
[self.delegate delegateMethod:data];
}
}
ViewController.swift
class ViewController: UIViewController, ProtocolDelegate {
// Xcode has automatically created this method
func delegateMethod(_ data: Any!) {
os_log("ON AUCTION");
}
}
I want delegateMethod inside ViewController to be executed.
Or maybe I get the whole idea wrong? Objective-C is a bit confising to me.
Related
I'm trying to create an Obj-C, CoreBluetooth virtual peripheral app and get this warning.
//
// ViewController.h
// sim_backend_empty3
//
//
#import <UIKit/UIKit.h>
#import <CoreBluetooth/CoreBluetooth.h>
#interface ViewController : UIViewController <CBPeripheralManagerDelegate>
#property (nonatomic, strong) CBPeripheralManager *peripheralManager;
#end
//
// ViewController.m
// sim_backend_empty3
//
//
#import "ViewController.h"
#implementation ViewController >>>>>>>>>> WARNING >>>>>>>>>> Class 'ViewController' does not conform to protocol 'CBPeripheralManagerDelegate'
- (void)viewDidLoad {
[super viewDidLoad];
}
-(void)start_BLE_advertisements
{
[[CBPeripheralManager alloc] initWithDelegate:self queue:nil options:nil];
}
#end
You need to implement the required CBPeripheralManagerDelegate protocol method:
peripheralManagerDidUpdateState:
as mentioned in the documentation here: https://developer.apple.com/documentation/corebluetooth/cbperipheralmanagerdelegate?language=objc
The protocol’s required one method, peripheralManagerDidUpdateState:, which Core Bluetooth calls whenever the peripheral manager’s state updates to indicate whether the peripheral manager is available.
You can check out an Objective-C example of how to setup CoreBluetooth using this repo:
https://github.com/LGBluetooth/LGBluetooth
Back when I still coded in ObjC, it was the library I used - and it was pretty great.
At the very least, it will give you some ideas on how you should be implementing the interfaces.
Here is a Swift implementation of what it sounds like you're trying to do (based on your other question asked a few days ago). Maybe you can backport it to ObjC (disclaimer: I'm the author).
https://github.com/RobotPajamas/SwiftyTeeth/blob/master/Sources/SwiftyTooth/SwiftyTooth.swift
While accessing protocol methods via delegate I'm getting following error:
"No known instance method for selector 'lostConnection'"
Swift Protocol:
#objc protocol GameDelegate {
func lostConnection()
}
Objective C game file
//game.h
#protocol GameDelegate;
#interface SSStreamManager : NSObject
#property (assign) id<GameDelegate> delegate
#end
Getting error while calling protocol methods
[self.delegate lostConnection]; // No known instance method for selector 'lostConnection'
You haven't shown any real code, but here's an example that will get you started. These are the three files in an iOS app project:
ViewController.swift
import UIKit
#objc protocol GameDelegate {
func lostConnection()
}
class ViewController: UIViewController {
}
Thing.h
#import <Foundation/Foundation.h>
#protocol GameDelegate;
#interface Thing : NSObject
#property (assign) id<GameDelegate> delegate;
#end
Thing.m
#import "Thing.h"
#import "MyApp-Swift.h"
#implementation Thing
- (void) test {
[self.delegate lostConnection];
}
#end
That compiles. You should be able to follow this model in your own code.
I'm having trouble calling an external method from a NSTextField Subclass. I have a NSTextField subclass that I'm monitoring text with and when textDidChange I'm calling an external method that is of a NSObject class. For some reason my method doesn't get called. I'm hoping someone could explain why. My code is below. Thanks.
EDIT: Fixed code to what drewag suggested.
MyTextField.h
#import <Cocoa/Cocoa.h>
#class ObjectController;
#interface MyTextField : NSTextField <NSTextFieldDelegate> {
ObjectController *objectController;
}
#property (strong, nonatomic) ObjectController *objectController;
#end
MyTextField.m
#import "MyTextField.h"
#import "ObjectController.h"
#implementation MyTextField
#synthesize objectController;
- (void)textDidChange:(NSNotification *)notification{
[objectController methodFromOtherClass];
}
#end
ObjectController.h
#import <Foundation/Foundation.h>
#interface ObjectController : NSObject {
}
- (void)methodFromOtherClass;
#end
ObjectController.m
#import "ObjectController.h"
#implementation ObjectController
- (void) methodFromOtherClass {
NSLog(#"Testing");
}
There are two likely scenarios causing this issue:
objectController is nil when textDidChange: is called
textDidChange: is not actually being called because you didn't connect it up correctly.
I don't think anyone can help you beyond that since you did not post your connection code nor where you are setting objectController.
Probably forgot to assign the delegate to self or whatever object that implements the textDidChange? Happens to me a lot.
I fixed the issue by creating an instance of ObjectController instead of the above process.
ObjectController *objectController = [ObjectController new];
[objectController methodFromOtherClass];
When I call respondsToSelector in an ARC environment, I get the following error message Automatic Reference Counting Issue No known instance method for selector respondsToSelector:
This is the header
#import <AppKit/AppKit.h>
#class MTScrollView;
#protocol MTScrollViewDelegate
-(void)scrollViewDidScroll:(MTScrollView *)scrollView;
#end
#interface MTScrollView : NSScrollView
{
}
#property(nonatomic, weak) id<MTScrollViewDelegate>delegate;
#end
This is the implementation file
#import "MTScrollView.h"
#implementation MTScrollView
#synthesize delegate;
- (void)reflectScrolledClipView:(NSClipView *)aClipView
{
[super reflectScrolledClipView:aClipView];
if([delegate respondsToSelector:#selector(scrollViewDidScroll:)])
{
[delegate scrollViewDidScroll:self];
}
}
#end
Any suggestions on why I am getting this error?
Make the protocol conform to NSObject
#protocol MTScrollViewDelegate <NSObject>
Otherwise the compiler doesn't think that the object will respond to NSObject messages like respondsToSelector, and will generate a warning. It will succeed at runtime without issues either way.
For Swift this becomes:
#objc protocol MTScrollViewDelegate: NSObjectProtocol
The NSObject protocol groups methods that are fundamental to all Objective-C objects.
For more information on what NSObjectProtocol is: https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/index.html
I've googled around and found some answers but I didn't get any of them to work. I have one NSObject with the class "A" and a second class "B" without an NSObject. In class "A" are my IBOutlets defined and I can't seem to figure out how to access those outlets from class "B"...
I've found answered questions like http://forums.macrumors.com/archive/index.php/t-662717.html But they're confusing.
Any help would be greatly appreciated!
Simplified Version of the Code:
aClass.h:
#import <Cocoa/Cocoa.h>
#interface aClass : NSObject {
IBOutlet NSTextField *textField;
}
#end
aClass.m:
#import "aClass.h"
#implementation aClass
// Code doesn't matter
#end
bClass.h:
#import <Cocoa/Cocoa.h>
#interface bClass : NSObject {
}
#end
bClass.m:
#import "aClass.h"
#import "bClass.h"
#implementation bClass
[textField setStringValue: #"foo"];
#end
When you write:
I have one NSObject with the class
"A" and a second class "B" without an
NSObject.
It tells me that you don't have your head around the basic concepts.
Read through Apple's objective-C introduction, and the tutorial projects.
The solution is using NSNotificationCenter. Here's a thread telling you how to do it: Send and receive messages through NSNotificationCenter in Objective-C?
Then in the method reacting to the notification, you call a method accessing the Outlet
- (void) receiveTestNotification:(NSNotification *) notification
{
if ([[notification name] isEqualToString:#"TestNotification"])
//NSLog (#"Successfully received the test notification!");
[self performSelectorOnMainThread:#selector(doIt:) withObject:nil waitUntilDone:false];
}
- (void) doIt
{
//testLabel.text = #"muhaha";
}
This worked for me, I hope it does so for you as well.