What's the How to Use an Objective-C Category Within Swift

What's the proper way to use an Objective-C category within Swift?

Actually, your category is transtlated to Swift as follows:

extension UIColor {

init(hex hexInt: Int) -> UIColor

init(hexString: String) -> UIColor

}

And because of that, you should be using:

let color = UIColor(hex: 0xffffff) // instead of hexInt:

let color = UIColor(hexString: "ffffff")

Autocompletion may still be buggy in the beta software, though.

How do I call Objective-C code from Swift?

Using Objective-C Classes in Swift

If you have an existing class that you'd like to use, perform Step 2 and then skip to Step 5. (For some cases, I had to add an explicit #import <Foundation/Foundation.h to an older Objective-C File.)

Step 1: Add Objective-C Implementation -- .m

Add a .m file to your class, and name it CustomObject.m.

Step 2: Add Bridging Header

When adding your .m file, you'll likely be hit with a prompt that looks like this:

A macOS sheet-style dialog from Xcode asking if you would "like to configure an Objective-C bridging header"

Click Yes!

If you did not see the prompt, or accidentally deleted your bridging header, add a new .h file to your project and name it <#YourProjectName#>-Bridging-Header.h.

In some situations, particularly when working with Objective-C frameworks, you don't add an Objective-C class explicitly and Xcode can't find the linker. In this case, create your .h file named as mentioned above, then make sure you link its path in your target's project settings like so:

An animation demonstrating the above paragraph

Note:

It's best practice to link your project using the $(SRCROOT) macro so that if you move your project, or work on it with others using a remote repository, it will still work. $(SRCROOT) can be thought of as the directory that contains your .xcodeproj file. It might look like this:

$(SRCROOT)/Folder/Folder/<#YourProjectName#>-Bridging-Header.h

Step 3: Add Objective-C Header -- .h

Add another .h file and name it CustomObject.h.

Step 4: Build your Objective-C Class

In CustomObject.h

#import <Foundation/Foundation.h>

@interface CustomObject : NSObject

@property (strong, nonatomic) id someProperty;

- (void) someMethod;

@end

In CustomObject.m

#import "CustomObject.h"

@implementation CustomObject

- (void) someMethod {
NSLog(@"SomeMethod Ran");
}

@end

Step 5: Add Class to Bridging-Header

In YourProject-Bridging-Header.h:

#import "CustomObject.h"

Step 6: Use your Object

In SomeSwiftFile.swift:

var instanceOfCustomObject = CustomObject()
instanceOfCustomObject.someProperty = "Hello World"
print(instanceOfCustomObject.someProperty)
instanceOfCustomObject.someMethod()

There is no need to import explicitly; that's what the bridging header is for.

Using Swift Classes in Objective-C

Step 1: Create New Swift Class

Add a .swift file to your project, and name it MySwiftObject.swift.

In MySwiftObject.swift:

import Foundation

@objc(MySwiftObject)
class MySwiftObject : NSObject {

@objc
var someProperty: AnyObject = "Some Initializer Val" as NSString

init() {}

@objc
func someFunction(someArg: Any) -> NSString {
return "You sent me \(someArg)"
}
}

Step 2: Import Swift Files to ObjC Class

In SomeRandomClass.m:

#import "<#YourProjectName#>-Swift.h"

The file:<#YourProjectName#>-Swift.h should already be created automatically in your project, even if you can not see it.

Step 3: Use your class

MySwiftObject * myOb = [MySwiftObject new];
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);
myOb.someProperty = @"Hello World";
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);

NSString * retString = [myOb someFunctionWithSomeArg:@"Arg"];

NSLog(@"RetString: %@", retString);

Notes:

  1. If Code Completion isn't behaving as you expect, try running a quick build with R to help Xcode find some of the Objective-C code from a Swift context and vice versa.

  2. If you add a .swift file to an older project and get the error dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib, try completely restarting Xcode.

  3. While it was originally possible to use pure Swift classes (Not descendents of NSObject) which are visible to Objective-C by using the @objc prefix, this is no longer possible. Now, to be visible in Objective-C, the Swift object must either be a class conforming to NSObjectProtocol (easiest way to do this is to inherit from NSObject), or to be an enum marked @objc with a raw value of some integer type like Int. You may view the edit history for an example of Swift 1.x code using @objc without these restrictions.

How to use Objective-C category in Swift file

So firstly you have your Objective C proj and in it you have your category(in Obj C) and now you added a Swift file and want to use category method in Swift.

So now answer goes-

  1. Firstly add your .swift file and mostly it asks for creating a bridging header. If it does not get created, follow the steps from this.

  2. Add #import "NSDictionary+Test.h" before #endif.

  3. Now you should be able to use the (void)testDone:(TestBlock)block as dictionary.testDone(block : TestBlock!).

How to call an Objective-C category method in Swift

The compiler automatically looks for common ObjC naming patterns and substitutes Swift patterns in their place. An ObjC class method that returns an instance of the class (and is named a certain way, it looks like) gets turned into a Swift convenience initializer.

If you have the ObjC method (defined by a custom category):

 + (UIColor *)colorWithHexString:(NSString *)hex alpha:(float)alpha;

The compiler generates the Swift declaration:

convenience init(hexString: String?, alpha: CFloat)

And you call it like this:

let color = UIColor(hexString: "#ffffff", alpha: 1.0)

And in Swift 2.0 or later, you can use the NS_SWIFT_NAME macro to make ObjC factory methods that don't match the naming pattern import to Swift as initializers. e.g.:

@interface UIColor(Hex)
+ (UIColor *)hexColorWithString:(NSString *)string
NS_SWIFT_NAME(init(hexString:));
@end

// imports as
extension UIColor {
init(hexString: String)
}

How to call below objective c category from swift class

You call it as simply as:

imgView.startScaningRepeatCount(2)

Or

imgView.startScaningRepeatCount(1000, duration: 2)

Or

imgView.startScaningRepeatCount(1000, duration: 2, heightFactor: 0.3)

Etc.

Remember to import your category's header from the project's bridging header.

Objective C - Is it possible to call a category's method from another category of same type?

A category adds methods to the original class. This is Objective-C so there's no concept of access control: once they exist, they are accessible to everybody. Therefore anybody with a pointer to an instance of the class and knowledge of the category can call them. That includes methods implemented in other categories of the same class.

So, yes, it is possible.



Related Topics



Leave a reply



Submit