-
-
Save kyle-ilantzis/00f4685462a150506481a15ac2af7259 to your computer and use it in GitHub Desktop.
func swizzleReplacingCharacters() { | |
let originalMethod = class_getInstanceMethod( | |
NSString.self, #selector(NSString.replacingCharacters(in:with:))) | |
let swizzledMethod = class_getInstanceMethod( | |
NSString.self, #selector(NSString.swizzledReplacingCharacters(in:with:))) | |
guard let original = originalMethod, let swizzled = swizzledMethod else { | |
return | |
} | |
method_exchangeImplementations(original, swizzled) | |
} | |
extension NSString { | |
@objc | |
func swizzledReplacingCharacters(in range: NSRange, with replacement: String) -> String { | |
/// By simply calling the original method the nil argument is handled. :shrug: :ok: | |
/// | |
/// (yes, we will call the original method and not ourselves even though it looks like it, | |
/// because the methods have been swapped.) | |
return self.swizzledReplacingCharacters(in: range, with: replacement) | |
} | |
} |
Hi Kyle, thanks for sharing your method.
But i use Objective-C.. So Could you please let me know how to call that method in Objecitve-C?
i'm trying add "public"in front of function name but failed..
too difficult.TT
did you have any solutions?
Here is Objective-c code. @yangloria @choi-bong-sik
This is from @acruis, Thanks
NSString+Swizzle.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSString (Swizzle)
@end
NS_ASSUME_NONNULL_END
NSString+Swizzle.m
#import "NSString+Swizzle.h"
#import <objc/runtime.h>
@implementation NSString (Swizzle)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(stringByReplacingCharactersInRange:withString:);
SEL swizzledSelector = @selector(swizzle_stringByReplacingCharactersInRange:withString:);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (success) {
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
- (NSString *)swizzle_stringByReplacingCharactersInRange:(NSRange)range withString:(NSString *)replacement
{
return [self swizzle_stringByReplacingCharactersInRange:range withString:replacement ?: @""];
}
@end
Here is Objective-c code. @yangloria @choi-bong-sik
This is from @acruis, ThanksNSString+Swizzle.h
#import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN @interface NSString (Swizzle) @end NS_ASSUME_NONNULL_END
NSString+Swizzle.m
#import "NSString+Swizzle.h" #import <objc/runtime.h> @implementation NSString (Swizzle) + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Class class = [self class]; SEL originalSelector = @selector(stringByReplacingCharactersInRange:withString:); SEL swizzledSelector = @selector(swizzle_stringByReplacingCharactersInRange:withString:); Method originalMethod = class_getInstanceMethod(class, originalSelector); Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); if (success) { class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else { method_exchangeImplementations(originalMethod, swizzledMethod); } }); } - (NSString *)swizzle_stringByReplacingCharactersInRange:(NSRange)range withString:(NSString *)replacement { return [self swizzle_stringByReplacingCharactersInRange:range withString:replacement ?: @""]; } @end
Should I import "NSString+Swizzle.h" into AppDelegate.m and run load() function or it works without import anything.
If should import, please show me how to import it into AppDelegate.m
Please answer me @623637646, I stuck at this for the whole day, Thanks.
Should I import "NSString+Swizzle.h" into AppDelegate.m and run load() function or it works without import anything.
If should import, please show me how to import it into AppDelegate.m
Please answer me @623637646, I stuck at this for the whole day, Thanks.
Hi @kyunkakata , No need to import it. Just add those files to your project. The + (void)load
will be called automatically.
Should I import "NSString+Swizzle.h" into AppDelegate.m and run load() function or it works without import anything.
If should import, please show me how to import it into AppDelegate.m
Please answer me @623637646, I stuck at this for the whole day, Thanks.Hi @kyunkakata , No need to import it. Just add those files to your project. The
+ (void)load
will be called automatically.
Thank you @623637646
@kyunkakata Thanks your code :)
Can I use your code in my commercial app?
Please let me know how I can use the code for commercial distribution.
That was @623637646 's code.
hi @seyoung-hyun . Feel free to use it. do remember to test before release to live.
@kyunkakata Sorry for confusing you.
@623637646 Thanks your reply :)
hi @kyle-ilantzis.
I wonder if I use your code at this gist in my commercial app, too.
Please let me know how I can use the code for commercial distribution.
Thanks :)
Does it mean, default ObjC implementation fails on empty tagged string, and Swift bridges empty tagged string to empty string? 😮
I once observed the same behavior in NSData. Nil
NSData
bridged to emptyData
🤣