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:
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:
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:
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.
If you add a
.swift
file to an older project and get the errordyld: Library not loaded: @rpath/libswift_stdlib_core.dylib
, try completely restarting Xcode.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 toNSObjectProtocol
(easiest way to do this is to inherit fromNSObject
), or to be anenum
marked@objc
with a raw value of some integer type likeInt
. 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-
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.
Add
#import "NSDictionary+Test.h"
before#endif
.Now you should be able to use the
(void)testDone:(TestBlock)block
asdictionary.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
Type Conversion When Using Protocol in Swift
Make Code With Firebase Asynchronous
Try, Try! & Try? What's the Difference, and When to Use Each
How to Silence a Warning in Swift
Swap Rootviewcontroller With Animation
Swift Xcode Index Freezing or Slow
How to Document the Parameters of a Function'S Closure Parameter in Swift 3
How to Access Program Arguments in Swift
Get Button Pressed Id on Swift Via Sender
Programmatically Screenshot | Swift 3, Macos
Is Swiftui Backwards-Compatible With iOS 12.X and Older
Swiftui: Pop to Root View When Selected Tab Is Tapped Again
Whats the Swift Animate Withduration Syntax
How to Check Two Instances Are the Same Class/Type in Swift