4

I have an Objective-C class which looks like this:

@interface CustomObjectHavingData : NSObject
@property (nonatomic, strong) NSData *objWithData;
 - (instancetype)initWithObjHavingData;
@end

and implementation like this

@implementation CustomObjectHavingData
- (instancetype)initWithObjHavingData{
if (self = [super init]) {
    NSString *str = @"This is simple string.";
    self.objWithData = [str dataUsingEncoding:NSUTF8StringEncoding];
}
return self;
}
@end

Now I want to call this initWithObjHavingData in Swift

var objData = CustomObjectHavingData()

This returns nil to me. Please help how I can call the above init method here.

Dhvani Puar
  • 854
  • 9
  • 13
  • Check this : http://stackoverflow.com/questions/24002369/how-to-call-objective-c-code-from-swift – Mrunal May 26 '15 at 13:20

3 Answers3

9

You are not supposed to write initializer like that in Objective C. Either you should have it just init or then if you are passing argument in constructor then only you can name it otherwise.

Here is how you can do it,

@interface CustomObjectHavingData : NSObject

@property (nonatomic, strong) NSData *objWithData;

- (instancetype)initWithObjHavingData:(NSData *)data;

@end


@implementation CustomObjectHavingData

- (instancetype)initWithObjHavingData:(NSData *)data
{
    if (self = [super init]) {
        _objWithData = data;
    }

    return self;
}

@end

In Swift, you can simply call it like this,

  let myCustomObject = CustomObjectHavingData(objHavingData: someData)

The name is quite inappropriate though.

Sandeep
  • 20,908
  • 7
  • 66
  • 106
  • 1
    It looks like this gets bridged strangely. As far as I can tell `CustomObjectHavingData(objHavingData: ())` is a valid way of using the initializer OP provided, but of course the initializer you provided is much more appropriate. – Mick MacCallum May 26 '15 at 13:29
  • Yes that might be because of the strange default named parameter the is generated for Swift class. Do you know if it is possible to remove the named parameter from swift class , something like init(_ data). – Sandeep May 26 '15 at 13:37
  • Right, and as far as I can tell it can't be done from an initializer created this way, but I may be overlooking something. – Mick MacCallum May 26 '15 at 13:45
  • But what if I don't want to pass any parameter in constructor like this. All I want is that I should get the test string encoded as soon as I call this constructor. – Dhvani Puar May 26 '15 at 13:47
  • Now, I dont get your question. Do you want to make Objective C class compatible with Swift or what do you want to do ? – Sandeep May 26 '15 at 13:49
  • I want to call this constructor as it is in Swift. How do I do it?- (instancetype)initWithObjHavingData{ if (self = [super init]) { NSString *str = @"This is simple string."; self.objWithData = [str dataUsingEncoding:NSUTF8StringEncoding]; } return self; } – Dhvani Puar May 26 '15 at 13:51
  • 1
    @DhvaniPuar You should do this with class methods, not instance methods. – nhgrif May 26 '15 at 13:51
  • @Sandeep: In this setup CustomObjectHavingData expect NSData! and not NSData ?? CustomObjectHavingData(objHavingData: NSData!) - I have to pass NSData – BaSha Apr 12 '17 at 09:24
  • You can fix that with null qualifiers in Objective C. Look at this https://developer.apple.com/swift/blog/?id=25. I will edit answer later to handle optionality and non optional cases. – Sandeep Apr 12 '17 at 09:27
1

If you want to call the init method without any parameter with the requirements I posted in the question, we have to write the init method like this:

@interface CustomObjectHavingData : NSObject

@property (nonatomic, strong) NSData *objWithData;

- (id)init;
@end

And implement it like this

@implementation CustomObjectHavingData
- (instancetype)initWithObjHavingData{
if (self = [super init]) {
  NSString *str = @"This is simple string.";
  self.objWithData = [str dataUsingEncoding:NSUTF8StringEncoding];
}
return self;
}
@end

@implementation CustomObjectHavingData

- (instancetype)initWithObjHavingData:(NSData *)data
{
  if (self = [super init]) {
     _objWithData = data;
  }

  return self;
}

@end

Then, you can call this from swift like this:

var objData = CustomObjectHavingData()

It will by default initialize all the objects.

codercat
  • 22,873
  • 9
  • 61
  • 85
Dhvani Puar
  • 854
  • 9
  • 13
0

You can use this :

+ (Common *)sharedInstance
{

    static Common *sharedInstance_ = nil;
    static dispatch_once_t pred;

    dispatch_once(&pred, ^{
        sharedInstance_ = [[Common alloc] init];
    });   
    return sharedInstance_;
}

After that for calling

var com_obj : Common!

com_obj = Common.sharedInstance() com_obj.anyfunc(..)

Reshmi Majumder
  • 961
  • 4
  • 15