0

My project is combined with one viewcontroller written in objective C (objCViewController) and the other is written by swift (SwiftViewCOntroller). I have several variable NSString. I would like to update the string in objCViewController and access it in SwiftViewController by using delegate because I need to change between these two viewcontroller continuously and keep updating the string.

Here is the code:

objCViewController.h

#import <UIKit/UIKit.h>

@protocol MyDelegate <NSObject>
@end

@interface objCViewController : UIViewController{
  NSString * stringbeingpassed;
}

@property (nonatomic, weak) id<MyDelegate> delegate;
@property (nonatomic, retain) NSString * stringbeingpassed;
@end

objCViewController.m

@implementation objCViewController
@synthesize delegate;
@synthesize stringbeingpassed;

- (void)updatestring {
  //update string in this method
  NSString * newstring = @"testing";

  if (delegate != nil && [delegate respondsToSelector:@selector(stringUpdated:)]) {
    [delegate stringUpdated: newstring];
}

}

bridging header.h:

#import "objCViewController.h"

SwiftViewController.swift:

protocol MyDelegate {
func stringUpdated(newMessage: String)
}

import UIKit
@objc class SwiftViewController: UIViewController, MyDelegate{
override func viewDidLoad() {
    super.viewDidLoad()
}

func stringUpdated(newMessage:String) {
let newMessage = "sent string"
}

I have tried to use delegate but I have no idea how to use it. I'm completely new to swift and objective C

Q1. I would like to ask how can I assign my newstring to delegate in objCViewController and then pass it to SwiftViewController.

Q2. Another question is that how can I retrieve the data in delegate in SwiftViewController. What should I add?

Q3. Anything else that I have missed in defining delegate? Do I need to define it in both viewcontroller? Thank you.

Hugo.W
  • 11
  • 3

2 Answers2

0

It's hard to say whether a delegate is the right tool for the job due to the minimal information provided. In fact I might suggest researching better ways to architect your app.

That being said, it would be helpful to see the code for your protocol MyDelegate. If this protocol doesn't already it will need a 'func' that accepts a 'String' as an argument/parameter. For now let's call this function stringUpdated. With that code that's provided you're going to need to set an instance of SwiftViewController to your property delegate within objCViewController. That way when updatestring is called you can do something like this:

- (void)updatestring {
    //update string in this method
    NSString * newstring = @"testing";

    if (delegate != nil && [delegate respondsToSelector:@selector(stringUpdated:)]) {
        [delegate stringUpdated: newstring]
    }
}

In SwiftViewController you'll have to adopt the protocol like so:

@objc class SwiftViewController: UIViewController, MyDelegate {

and then adhere to the protocol by implementing the function stringUpdated.

Update

Your protocol is still missing the method. It should look like this:

@protocol MyDelegate
- (void) stringUpdated:(NSString *)updatedString;
@end
Taylor2412
  • 36
  • 6
  • I have created a func stringUpdated in SwiftViewController Here is the code : protocol MyDelegate { func stringUpdated(newMessage: message) } func stringUpdated(newMessage:String) { newMessage = "sent string" } but in objCViewController I got errors : No known instance method for selector 'respondsToSelector:' No known instance method for selector 'stringUpdated:' – Hugo.W Apr 09 '18 at 19:25
  • Could you edit/update your question with your protocol please? It sounds like the protocol was defined in swift and does not conform to NSObject which it will need to be in order to work with Obj-C – Taylor2412 Apr 09 '18 at 19:40
  • the question is updated. I added in Mydelegate protocol and now I still got an error in objCViewController : No known instance method for selector 'stringUpdated:' – Hugo.W Apr 09 '18 at 20:03
  • Oh, sorry, I didn't see your protocol at the top of the **objCViewController** header. You missed a very important part and this is the actual reason it's returning that error. You never defined the protocol method as I described above. I've added an example to my answer. – Taylor2412 Apr 09 '18 at 20:06
  • What is the meaning of this if statement? if (delegate != nil && [delegate respondsToSelector:@selector(stringUpdated:)]) . My code cannot run into this if statement and I failed to do printf inside this if statement – Hugo.W Apr 10 '18 at 04:27
  • It's checking to make sure the you've set the delegate and that the delegate has implemented the method **stringUpdated**. The reason you are not getting inside is because you haven't added the method as part of the protocol and I don't see you setting your delegate to an instance of SwiftViewController. I'd would highly recommend looking at some tutorials or making sure that this is the best way to handle what you're trying to do as it seems you are not grasping much of what I'm trying to convey. – Taylor2412 Apr 10 '18 at 14:59
0

let me answer Q3 first Q3:Anything else that I have missed in defining delegate? Do I need to define it in both viewcontroller? No you haven't to define MyDelegate in both viewControllers, just add it to the objCViewControlle

Now here under I had modified you code

objCViewController.h

@protocol MyDelegate <NSObject>
- (void) stringUpdated:(NSString *)updatedString;
- (NSString *) getString;
@end

@interface objCViewController : UIViewController{
  NSString * stringbeingpassed;
}

@property (nonatomic, weak) id<MyDelegate> delegate;
@property (nonatomic, retain) NSString * stringbeingpassed;
@end

bridging header.h:

#import "objCViewController.h"

SwiftViewController.swift:

import UIKit
@objc class SwiftViewController: UIViewController, MyDelegate{
var thisIsObjectiveVCString:String?
override func viewDidLoad() {
    super.viewDidLoad()
}

func stringUpdated(newMessage:String) {
thisIsObjectiveVCString = newMessage
}

func getString() ->String {
return thisIsObjectiveVCString
}
}

Q2: how can I retrieve the data in delegate in SwiftViewController. What should I add?

on objCViewControlle

if (delegate != nil && [delegate respondsToSelector:@selector(getString)]) {
        NSString * theString = [delegate getString];
    }

Q1: how can I assign my newstring to delegate in objCViewController and then pass it to SwiftViewController

actually on objCViewController if you call updatestring then you will update SwiftViewController

Same7Farouk
  • 837
  • 9
  • 19