How can i add a new method to NSString class.
I need to create a method that get's called on a string and returns an NSDictionary.
I know that i can simply create a function that gets a string and return an nsdictionary, but i want to know how to add it to an existing class.
NSString *myStr = #"some json string";
NSDictionary *dictionary = [myStr getJSONData];
You can use Objective-C categories. For example to add on to NSString define the following in a new .h/.m file:
#interface NSString (CategoryName)
-(NSString *) aNewMethod;
#end
Related
so im trying to add new method for testing using Category from NSString, but some how i must declared like this with following step:
Create Category from NSString with name StringExtension so it will be NSString+StringExtension, after that i declared my own methos that return type is String
so after i define in NSString+StringExtension #interface and #implementation, i tried in my viewController to called it, but first i import the class NSString+StringExtension
after that i do like this
NSString *testString = #"as d a s d";
NSLog(#"===== %#", [testString removeWhiteSpaceStringWithString:testString]);
and it says
No visible #interface for 'NSString' declares the selector 'removeWhiteSpaceStringWithString:'
the question is, why it cannot use like that? i already search and see tutorial doing like that and its possible, but why i'm not able to do that?
so i found this way, but i don't know is this the correct code to use?
NSLog(#"===== %#", [[testString class] removeWhiteSpaceStringWithString:testString]);
anyone have the same case like i am?
Based upon what you have shared with us, it would appear that you defined a class method (with +). It should be an instance method (with -) and then you don’t need the parameter, either. You can simply reference self.
For example:
// NSString+Whitespace.h
#import Foundation;
NS_ASSUME_NONNULL_BEGIN
#interface NSString (Whitespace)
- (NSString *)stringByRemovingWhitespace;
#end
NS_ASSUME_NONNULL_END
And
// NSString+Whitespace.m
#import "NSString+Whitespace.h"
#implementation NSString (Whitespace)
- (NSString *)stringByRemovingWhitespace {
return [self stringByReplacingOccurrencesOfString:#"\\s+"
withString:#""
options:NSRegularExpressionSearch
range:NSMakeRange(0, self.length)];
}
#end
Then you can do:
NSString *testString = #"as d a s d";
NSLog(#"===== %#", [testString stringByRemovingWhitespace]); // ===== asdasd
Obviously, do whatever you want in your implementation, but it illustrates the idea, that you want an instance method and you do not need to pass the string again as a parameter.
Ok, begginer question here.
I create a class to hold a list of my dvds, h file:
#import <Foundation/Foundation.h>
#interface Films : NSObject
#property NSMutableArray *horrorFilms;
- (NSMutableArray*) createListOfHorrorFilms;
#end
m file:
#import "Films.h"
#implementation Films
- (NSMutableArray*) createListOfHorrorFilms{
self.horrorFilms = [[NSMutableArray alloc] initWithObjects:#"The Shinning", #"Carrie",#"The Blair Witch Poject", nil];
return self.horrorFilms;
}
#end
Would this work? If not, what is the proper way of doing it? Thanks
Hi You could prefer plist. if you are using more static values in your class. Which will be easy to modify and handle in future.
For doing the above case in plist.
Create a plist (Right click Project folder->New File -> resources -> select Property List), Assign a plist name for example horrorFilms.
horrorFilms plist will be saved in your project folder.
Select horrorFilms and change root plist type to NSArray from NSDictionary.
Add Itmes (as String) to your root plist Array
-Go to Your .m Controller class. Add the following method to fetch plist.
- (NSArray *)horrorFilmsList
{
NSString *plistPath = [[NSBundle mainBundle] pathForResource:#"horrorFilms" ofType:#"plist"];
NSArray * arrhorrorFilms = [[NSArray alloc] initWithContentsOfFile:plistPath];
return arrhorrorFilms;
}
6 fetch your plist array anywhere by [self horrorFilmsList. If you want to see in log try this in viewDidLoad NSLog(#"\nHorror Films-->%#",[self horrorFilmsList]);
I have seen in some source code (by other developers) something like this:
#import "SomeClass+SomeOtherClass.h"
What is the + for? What does this mean?
Let's say you want to add functionality to an existing class (exp: NSString). You can do that by creating a subclass or you can use a category. And it is common to name the file where the category is defined using the pattern : MyClass+MyCategory.h.
For example, we can add a method reverseString to the class NSString in a category:
// File NSString+reversable.h
- (NSString *)reverseString;
// File NSString+reversable.m
- (NSString *)reverseString
{
// Implementation
}
Have a look at this documentation for more information about categories.
Then you can use that category in another class:
#import "NSString+reversable.h"
// ...
NSString *aString = #"Hello!";
NSString *reversedString = [aString reverseString];
The "+" in header/source filenames is - by convention - used to describe Category implementations.
Example :
Let's say you want to add some functionality to an existing class (e.g.the NSString class). (NSString+Utilities.h)
// NSString+Utilities.h
#interface NSString (Utilities)
-(NSString *) doSthWithThisString;
#end
// NSString+Utilities.m
#implementation NSString (Utilities)
-(NSString *) doSthWithThisString
{
NSMutableString *transformedStr = [self copy];
// Do sth
return transformedStr;
}
#end
Using it :
// in another file
#import "NSString+Utilities.h"
- (void)awakeFromNib
{
NSString* myString = #"This is a string";
// you may use our new NSString method as much as any already-existing one
NSString* newString = [myString doSthWithThisString];
}
Reference :
Mac OS Developer Library - Categories & Extensions
Objective-C Categories - Wiki
I have a dictionary that I read from a plist. I want to create a subclass of NSDictionary to implement something like the following, so that I can avoid using #"key name" everywhere in my source code:
#interface MyDict{
}
-(NSString*) textString;
#end
#implementation MyDict
-(NSString*) textString {
return [self objectForKey:#"textString"];
}
#end
In my other method:
MyDict *d = ... // something i read from plist
NSString *str = [d textString];
When I call the method, the app crashes because of "unrecognized selector textString". What is wrong here?
Just assigning an NSDictionary to a MyDict pointer doesn't make it a MyDict instance.
One way you can do this would be to create a category to add your method to NSDictionary. See http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocCategories.html#//apple_ref/doc/uid/TP30001163-CH20-SW1 for info.
Your class has no superclass. Also, the conventional wisdom is that it's very difficult to subclass NSDictionary because it is an class cluster. You don't actually get an NSDictionary back when you:
NSDictionary * myDict = [NSDictionary dictionary];
You get a private subclass (NSCFDictionary in this case).
You might want to try defining your own dictionary keys, the way Apple does:
NSString * const MyWonderfulUnicornKey = #"MyWonderfulUnicornKey";
I'm not sure how to manage this, as objective-c is wierd enough for me
I'm have this derived class
#interface DoctorsSet : NSObject { NSString *tableid;
NSString *doctor_name;
NSString *doctor_surname;
NSString *city;
NSString *State;
NSString *phone; }
It has a custom constructor on which I'm initializing the properties as params...
THe problem is I have several functions that return this type, so how so I assign to a temporary local variable this type, or if my data comes from a NSMutableArray and I want to get that object at index ID
here are the 2 cases which I couldn't handle, because on assign it give an access error
NSMutableDictionary *doctors_set;
for(i=[doctors_sets count]-1;i>=0;i--) {
//this doesn't work
DoctorsSet * set=[doctors_set objectAtIndex:i];
}
i don't want to use for(DoctorsSet *set in doctors_sets)
because i want to pass the array in the reverse order....
If the end goal is to go in reverse use
for (DoctorsSet *set in [doctors_sets reverseObjectEnumerator])