Extracting URLs from NSString into NSMutableString - ios

I have a file with the following content:
cool name http://myurl1.tld/subdir/dir/var/ awesome\nanother cool name http://sub.domain.tld/dir/ nice\nsome nice name http://myname.tld/var/folder/ some\n
I read the file with this Objetive-C code:
NSData* data = [NSData dataWithContentsOfFile:[NSString stringWithFormat:#"../files/name.ext"]];
NSString* raw = [[NSString alloc]
initWithBytes:[data bytes]
length:[data length]
encoding:NSUTF8StringEncoding];
To extract all URLs from the above sample I use:
NSDataDetector* detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil];
NSArray* matches = [detector matchesInString:raw options:0 range:NSMakeRange(0, [raw length])];
My goal is to append all extracted URLs into one single string and separate them with a semicolon (without any other stuff from the file) with this loop:
NSMutableString *allURLStrings = [NSMutableString string];
for (NSString *s in matches) {
[allURLStrings appendString:s];
[allURLStrings appendString:#";"];
}
Whenever I try to run the code I get the following output:
terminating with uncaught exception of type NSException (lldb)
I tried to use the loop like this, but then the substringForCurrMatch only contains a slash (/):
NSMutableString * allRepoString = [NSMutableString string];
for (NSTextCheckingResult *s in matches) {
NSString* substringForCurrMatch = [s.URL path];
[allRepoString appendString:substringForCurrMatch];
[allRepoString appendString:#";"];
}
When I inspect s in the loop it shows me the correct object:
Is there a way to get this code working?
EDIT complete error message:
2016-08-11 23:00:19.272 AppName[34831:2892247] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[fetchurlsource allURLStrings]: unrecognized selector sent to instance 0x14c55ea00'
*** First throw call stack:
(0x181fa2db0 0x181607f80 0x181fa9c4c 0x181fa6bec 0x181ea4c5c 0x1000e8b6c 0x1000e8ee0 0x187100c40 0x187100844 0x18710759c 0x187104a88 0x18717afa4 0x1873a63ac 0x1873aa5f0 0x1873a7764 0x1839437ac 0x183943618 0x1839439c8 0x181f5909c 0x181f58b30 0x181f56830 0x181e80c50 0x18716f94c 0x18716a088 0x1000edb10 0x181a1e8b8)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)

None of the code you posted so far can result in the exception you posted.
But the following code is incorrect:
NSMutableString * allRepoString = [NSMutableString string];
for (NSTextCheckingResult *s in matches) {
NSString* substringForCurrMatch = [s.URL path];
[allRepoString appendString:substringForCurrMatch];
[allRepoString appendString:#";"];
}
You do not want to call the path method on s.URL. To get the full URL as a string, use absoluteString. This will give you the URL as a string. path just gives you the path portion of the URL.
NSMutableString * allRepoString = [NSMutableString string];
for (NSTextCheckingResult *s in matches) {
NSString* substringForCurrMatch = [s.URL absoluteString];
[allRepoString appendString:substringForCurrMatch];
[allRepoString appendString:#";"];
}

Related

Assigning text to UILabel gives error after parsing JSON

I've the following code for receiving response from PHP web service in JSON Format:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *responseStringWithEncoded = [[NSString alloc] initWithData: mutableData encoding:NSUTF8StringEncoding];
NSLog(#"Response from Server : %#", responseStringWithEncoded);
[self getData:responseStringWithEncoded];
}
-(void) getData:(NSString *) responseStringWithEncoded{
NSData *data = [responseStringWithEncoded dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(#"object for key ime = %#", [json objectForKey:#"imei"]);
NSString * jimei = [json objectForKey:#"imei"];
NSLog(#"jimei = %#", jimei);
// NSDictionary * jimei = [json objectForKey:#"imei"];
imeiLable.text = jimei;
}
I am successfully retrieving data in simulator but when assigning one value among received string(NSDictionary) to imeiLable.text it gives following error.
Here is the output:
Request data = { URL: http://localhost/getjsonimei.php?imei=478593219801234 }
Response from Server : {"id":7,"imei":478593219801234,"mname":"Samsung Glaxy","pamount":"2000 rupees","pname":"Faizi","address":"House number 88, block 31","cnumber":11122233,"nic":"87456893"}
object for key ime = 478593219801234
jimei = 478593219801234
Here is detailed description of simulator resulting string(dictionary) and error.
2017-05-24 20:01:13.229 imiechecker[4005:61372] -[__NSCFNumber length]: unrecognized selector sent to instance 0xb01b3472adbb0923
2017-05-24 20:01:13.263 imiechecker[4005:61372] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber length]: unrecognized selector sent to instance 0xb01b3472adbb0923'
I also tried following approach:
NSDictionary * jimei = [json objectForKey:#"imei"];
but having the same error.
Please suggest where I am doing it wrong?
Your IMEI number is of data type NSNumber, not NSString.
Try this:
NSString * jimei = [NSString stringWithFormat:#"%#", [json objectForKey:#"imei"]];
imeiLable.text = jimei;

AFNetworking crashing in multilingual app

Ride[source_name]=2152,%20Mohali%20Stadium%20Rd,%20Phase%2010,%20Sector%2064,%20Sahibzada%20Ajit%20Singh%20Nagar,%20Punjab%20160062,%20भारत
This parameter is causing crash while running in Hindi while working fine with Spanish and English. Please suggest me on it. Crash description is as following:-
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not
satisfying: URLString'
Check with this
Objective - C
NSString *string = #"भारत";
NSString *encoded = [string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];
Swift 3.0
let string = "भारत"
let urlString = string.addingPercentEncoding( withAllowedCharacters: . urlUserAllowed)
Output :: %E0%A4%AD%E0%A4%BE%E0%A4%B0%E0%A4%A4
Add below line of code to avoid invalid parameters in url.
NSString *str = ...; // Your URL
NSCharacterSet *set = [NSCharacterSet URLHostAllowedCharacterSet];
NSString *result = [str stringByAddingPercentEncodingWithAllowedCharacters:set];
Deprecated Code Before ios 9.0 :
NSString *str = ...; // Your URL
NSString *urlAsString = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

UISearchBar unrecognized selector sent to instance

I've a .json file stored locally from which I'm loading in an array called countries as countries = (NSArray *)[NSJSONSerialization JSONObjectWithData [fileContents dataUsingEncoding:NSUTF8StringEncoding] options:0 error:NULL]; after loading the filepath ofcourse. I'm Loading the .json into countries array as:
NSString * filePath =[[NSBundle mainBundle] pathForResource:#"countries" ofType:#"json"];
NSError * error;
NSString* fileContents =[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&error];
if(error||!filePath)
{
NSLog(#"Error reading file: %#",error.localizedDescription);
}
countries = (NSArray *)[NSJSONSerialization
JSONObjectWithData:[fileContents dataUsingEncoding:NSUTF8StringEncoding]
options:0 error:NULL];
After that I've taken an NSMutableArraycalled displayItems and initialized it as displayItems = [[NSMutableArray alloc] initWithArray:countries];. Than in UITableView delegate methods I've used displayItems in count which after NSLog gives 248 means it's correctly getting the values cellForRowAtIndexPath and didSelectRowAtIndexPath See this image below for the hierarchy of the ViewController
THE PROBLEM:
Based on the break points, this method is creating issue.
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
if ([searchText length] == 0) {
[displayItems removeAllObjects];
[displayItems addObjectsFromArray:countries];
} else {
[displayItems removeAllObjects];
for (NSString *string in countries) {
NSRange r = [string rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (r.location != NSNotFound) {
[displayItems addObject:string];
}
}
}
[tableView reloadData];
}
When it reaches the line Range r the app crashes and the error is unrecognized selector sent to instance. Everything is working great until I type a letter in the UISearchBar the app crashes at that time.
The Exact Error is:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary rangeOfString:options:]: unrecognized selector sent to instance 0x12ddd5e90'
*** First throw call stack:
(0x180a55900 0x1800c3f80 0x180a5c61c 0x180a595b8 0x18095d68c 0x1000d0e3c 0x185953d28 0x18577fe50 0x18577fdcc 0x185767a88 0x185953ad4 0x18578a8f8 0x18591fee8 0x18591f104 0x185aafae4 0x186095b20 0x18591ee70 0x185b5cc90 0x185b5c854 0x185772e84 0x181417e20 0x180a0cefc 0x180a0c990 0x180a0a690 0x180939680 0x181e48088 0x1857b0d90 0x1000e0e94 0x1804da8b8)
libc++abi.dylib: terminating with uncaught exception of type NSException

How to fix this mutating error?

I'm getting this error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to mutate immutable object with replaceCharactersInRange:withString:'
But I can't figure out what immutable object I'm mutating.
NSRange subRange = [self.label.text rangeOfString: #"="];
int numA = 5;
int numB = 3;
NSMutableString *mixed = [NSString stringWithFormat: #"%i %i", numA, numB];
NSMutableString *string = [NSString stringWithString: self.label.text];
subRange = [string rangeOfString: #"="];
if (subRange.location != NSNotFound)
[string replaceCharactersInRange:subRange withString:mixed];
Your NSMutableString creation calls aren't balanced properly. You're promising the compiler that you're creating a NSMutableString but you ask an NSString to create an instance.
For example:
NSMutableString *mixed = [NSString stringWithFormat: #"%i %i", numA, numB];
needs to be:
NSMutableString *mixed = [NSMutableString stringWithFormat: #"%i %i", numA, numB];
Your NSMutableStrings are actually instances of NSString. This is runtime detail, though there should at least be a warning for those lines. Change to:
NSMutableString *string = [self.label.text mutableCopy];
You need to create a NSMutableString like this:
[NSMutableString stringWithString: self.label.text];

RegexKitLite - iOS: unrecognized selector

I have a project that must use regular expressions, so I decided to use RegexKitLite, I downloaded it, have added RegexKitLite.m into "Compile Sources", and RegexKitLite.h into "Copy Files" sections. Added libicucore.A.dylib to project Libraries. Imported RegexKitLite.h into my class, and write code (just for test):
NSString *str = #"testing string";
if ([str isMatchedByRegex:#"[^a-zA-Z0-9]"])
{
NSLog(#"Some message here");
}
After that I have error message:
-[__NSCFString isMatchedByRegex:]: unrecognized selector sent to instance 0x1ed45ac0
2013-02-28 19:46:20.732 TextProject[8467:907] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString isMatchedByRegex:]: unrecognized selector sent to instance 0x1ed45ac0'
What I have missed? Please help me..
After some digging there wasn't in fact any Cocoa API to use regex before iOS4 so programmers were using external libraries like RegexKitLite which indeed could be used for iOS.
If you are on iOS4 or later there shouldn't be any reason not to use NSRegularExpression. Class reference description can be found here.
For example with NSRegularExpression your code snippet will look like:
NSString *str = #"testing string";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"[^a-zA-Z0-9]" options:NSRegularExpressionCaseInsensitive error:nil];
NSTextCheckingResult *match = [regex firstMatchInString:str options:0 range:NSMakeRange(0, [str length])];
NSRange range = [match rangeAtIndex:0];
if (range.location != NSNotFound)
{
NSString* matchingString = [str substringWithRange:range];
NSLog(#"%#", matchingString);
}

Resources