check if an string matches any value in an array? - iphone

Preamble: I'm working with some code I didn't write and I have next to no knowledge of iOS.
The app has a webview which handles most of the app; internal links are loaded in the webview and links to other sites are opened in Safari which is expected. However, embedding a google maps also causes safari to open. I found the relevant controller code, I think, and it looks like this:
// a bit higher up
static NSString *const siteURL = #"http://my.example.com"
if (![request.URL.absoluteString hasPrefix:siteUrl])
{
if ([[UIApplication sharedApplication] canOpenURL:request.URL])
{
[[UIApplication sharedApplication] openURL:request.URL];
}
return NO;
}
Now because 'maps.google.com' doesn't start with 'my.example.com' it farms out to safari - and that makes sense to me. However, I tried modifying this:
static NSString *const googleMaps = #"http://maps.google.com"
if (! ([request.URL.absoluteString hasPrefix:siteUrl] || [request.URL.absoluteString hasPrefix:googleMaps]))
{
if ([[UIApplication sharedApplication] canOpenURL:request.URL])
{
[[UIApplication sharedApplication] openURL:request.URL];
}
return NO;
}
This also works. But I need to add some more URLs. Is my only choice to keep adding 'or' and string constants? Or is there a way to make an array and say "if it matches any of these"? Sorry if this question seems simplistic.
In PHP I'd just do something like in_array('string', $array) as my condition, I guess I'm looking for how to do this in iOS

One solution would be to maintain a NSSet of objects, being all the strings that you want to be handled in your internal webview.
NSSet *internalURLSet = [NSSet setWithObjects:#"http://my.example.com", #"http://maps.google.com", nil];
Use a mutable set if you will be adding to the set over time but you will likely know which URLs you want to handle internally as soon as your app starts and this will not change. If you are adding sets as the app runs then add them to the mutable set as they become known.
When you check a URL, use [internalURLSet containsObject:urlToTest] and it will match any of the strings you have added to the set.
Checking against the set is very efficient. Adding objects to the set is less so, but you will very likely add URLs to the set only once while you check many times.
(Doing indexOfObject: against a NSArray is very inefficient...)

You could try using a predicate. Here's a tutorial link with an example (older, but should still work):
http://arstechnica.com/apple/2009/04/cocoa-dev-the-joy-of-nspredicates-and-matching-strings/
I do a lot of .NET development too and always miss LINQ when I go back to iOS. Predicates help a little, more lines of code but handy since you can do all kinds of searches.

I see your problem. In IOS, don't have a function in_array('string',$array) to check a string is contained in array.
I have a suggestion: you create a array with all urls. And implement 'for' or 'while' loop to get value of array check it. If it's same, you call function OpenUrl.

You could do this by creating an NSArray of your URLS and then using the indexOfObjectPassingTest: method to test your URL against each one in the array. It would go something like this:
NSArray *testURLs = #[ #"http://maps.google.com", #"http://www.example.com" ];
NSString *urlString = request.URL.absoluteString;
BOOL urlMatchedTest = NO;
for ( NSString *testURL in testURLs ) {
if [urlString hasPrefix:testURL] ) {
urlMatchedTest = YES;
}
}
if ( urlMatchedTest ){
// the url contains one of the test URLS
} else {
// it didn't match any of the test URLs
}

Related

Objective-C: Comparing normal strings and strings found in NSMutableArrays

I am confused about strings (a beginner's problem, I'm afraid):
I have one NSMutableArray called Notebook. At index position 1, I have an object, which I think is a string. At least I put it into the array like this:
[NoteBook replaceObjectAtIndex:1 withObject:#"x-x-x-x"];
So far so good. If I put this into an UILabel, it will show x-x-x-x on my screen. The nightmare starts when I try to compare this string with other strings. Let's consider that I do not want to display the string x-x-x-x on my screen, but just to have a blank instead. So I thought I could achieve this by coding this:
NSString *tempDateString;
tempDateString = [NSString stringWithFormat:#"%#",[NoteBook objectAtIndex:1]];
if (tempDateString == #"x-x-x-x") {
UISampleLabel.text = #"";
}
For some reason, this does not work, i.e. even if the string at position 1 of my array is 'x-x-x-x', it will still not set my UISampleLabel to nothing.
I suppose that I am getting confused with the #"" markers. When do I really need them? Why can't I simply code tempDateString = [NoteBook objectAtIndex:1]; without the formatting thing?
Any help and suggestions would be very much appreciated!
You need to compare string with isEqualToString:
if ([tempDateString isEqualToString:#"x-x-x-x"]) {
UISampleLabel.text = #"";
}
In addition to the question that's been answered:
Why can't I simply code tempDateString = [NoteBook objectAtIndex:1]; without the formatting thing?
You can. Why do you think you can't?

What code should I use to get & (not &) in the tweet?

I use Twitter-OAuth-iPhone to POST tweets by [_engine sendUpdate:myText];, which works fine. However, the letter & in the 'myText' will be changed to & in the tweet shown on Twitter.com. The & is for coordinates link: #"http://maps.google.co.uk/maps?f=q&source=s_q&hl=en&geocode=&q=%f,+%f".
I tried to replace the & with %%26 in the 'myText', which turns out with %26 in the tweet instead of &; and when I replace with %26, the app crash.
What code should I use to get & (not &) in the tweet?
You may need to use a URL shortener, since Twitter may be doing something to avoid SQL injection and the like.
Otherwise, does this work for you?
- (NSString *)stringByReplacingPercentEscapesFromString:(NSString *)inString
{
NSString *outString = (NSString *)CFURLCreateStringByReplacingPercentEscapes(NULL, (CFStringRef)inString, CFSTR(""));
return [outString autorelease];
}

Parsing my flat-file on iPhone is a pain in the ***, please Help me out

I am programming an iPhone App which is supposed to parse a flat-file from the web, create managed objects from the flat-file and later on should display them in an UITableView.
There are no problems with the saving and the displaying, but I just can't get the hang of a good Parser.
Thats the file I want to parse: Flat-file
AS far as I know, I can't use the NSXMLParser for this task (because obviously there are no tags).
So I at first tried to programm a NSScanner which should get me the interesting properties --> didn't work out
Now I am using this method:
- (void) parseMemberDataWithURL: (NSString *)urlString
{
self.memberTempCounter = 1;
//Get data from web
self.downloadedText = [NSString stringWithContentsOfURL: [NSURL URLWithString: urlString] encoding:NSUTF8StringEncoding error:nil ];
memberArray = [downloadedText componentsSeparatedByString:#";"];
while (self.memberTempCounter<[memberArray count])
{
[[ExhibitorController sharedController] createExhibitorWithName:[memberArray objectAtIndex:self.memberTempCounter]
street:[memberArray objectAtIndex:self.memberTempCounter+2]
zip:[memberArray objectAtIndex:self.memberTempCounter+3]
city:[memberArray objectAtIndex:self.memberTempCounter+4]
email:[memberArray objectAtIndex:self.memberTempCounter+7]
phone:[memberArray objectAtIndex:self.memberTempCounter+5]
website:[memberArray objectAtIndex:self.memberTempCounter+8]
produktbereiche:[[memberArray objectAtIndex:self.memberTempCounter+9] componentsSeparatedByString:#","]];
self.memberTempCounter= self.memberTempCounter+13;
}
}
I am using the memberTempCounter to identify the property.
The problems are:
This only works out in like 3 of 4 times.1 of 4 times the App crashes and I have no Idea why...
The method has a performance like a 1962 VW Beetle. Parsing the whole chunk of data takes up to 3 Minutes on my iPhone 3G
Any Ideas or a simpler way to do this?
I would be really gratefull. Thanks in advance: -)
You might as well do all the parsing in the background, and then display as the information gets parsed.
As for memory issues, try doing temporary autorelease pools and release every 50 or so iterations through the loop.
int count = 0;
NSAutoreleasePool * loopPool = [[NSAutoreleasePool alloc] init];
while(someInsanelyLargeCondition){
// Do your stuff here
// .............
count++;
if (count > 50) {
count = 0;
[loopPool release];
loopPool = [[NSAutoreleasePool alloc] init];
}
}
Recursive-descent (LL1) parsers are pretty simple, light on memory, and for speed they go almost as fast as you can run a pointer through characters. Building your data structure would probably be the dominant time-taker.
I was finally able to fix my performance problem.
I have a method in another class, which ads Tags for the different Exhibitors. Therefore it first checks if the Tag already is stored in the database or else creates it.
With an growing Set of Tags in my database the search-process took longer and longer and this led to the long parsing time.
Anyone else having this problem: Take a look at the Performance Core Data Programming guide of apple in the "Implementing Find-or-Create Efficiently"-section:
http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CoreData/Articles/cdImporting.html

if-query: if (Nslog isEqualtoString #"...") - How can I make this?

I want my app to do something when the last NSLog has a certain string. I thought I could realize this with an if-query and isEqualtoString, but how can I make this?
Sorry for my bad English ;)
Maybe I don't understand what you're trying to do, but you can just create the string somewhere, log it, and then test it:
NSInteger _someInt = 2;
NSString *_someString = #"bananas";
NSString *_stringToBeLogged = [NSString stringWithFormat:#"%d %#", _someInt, _someString];
NSLog(#"%#", _stringToBeLogged);
if ([_stringToBeLogged isEqualToString:#"2 bananas"]) {
NSLog(#"I logged two bananas...");
}
You could consider creating your own custom log function which calls NSLog() after checking for your string constant. This would keep your code a bit cleaner if you want this functionality in multiple places and also allows you to easily extend the logging function further if desired.

hot do i make a comparison of integers and values of text box in Objective C

i'm new to iphone programming and i encountered/noticed some problems while i was coding. which was after i typed a statement like
if (label.text > label2.text) {
do something...}
however, after typing my application can be compiled and run however when i try to validate it by comparing the values, my specified actions can run and i can change my image view image, however the conditions is not true but the specified actions can be run. Do enlighten me thanks! i will post my codes at the bottom, do comment if you spot any better practices? thanks once again.
Oh and how can i specify to check in my label that the default value is not "Label" or empty because i would like the values to be populated with number before commencing.
-(IBAction) beginMatch {
if (resultP1.text, resultP2.text = #"Label") {
errorMsg.text = #"Please Press Roll (:";
}
else
if (resultP1.text > resultP2.text) {
MG = [MainGameController alloc];
MG.player1 = playerName.text;
}
else {
MG.player1 = playerNameP2.text;
}
[self.view addSubview:MG.view];
}
this is one example that it does not work i have another one which is below.
-(IBAction) btn:(id) sender {
ptc = [playerTurnController alloc];
if (ptc.player1name = MGplayerName.text) {
if (lblDiceResultP1.text > lblDiceResultP2.text) {
img.image = [UIImage imageNamed:#"yellow.png"];
}
else if (ptc.player2name = MGplayerName.text) {
img.image = [UIImage imageNamed:#"Blue.png"];
}
}
}
Thank you.
Your code contains quite a few errors. You're trying to compare NSString values with ">", you're using the comma operator and = operator incorrectly, and you're allocating new objects in (what look to be) the wrong places.
You really should work your way through the introductory documentation on Apple's developer website first:
Learning Objective-C: A Primer
and
Your First iPhone Application
In here you're comparing string (alphabetically) addresses:
lblDiceResultP1.text > lblDiceResultP2.text
You probably want to extract NSNumbers of out the strings and compare the numeric values.
This here is an assignment and not a comparison:
ptc.player2name = MGplayerName.text
You probably meant to use == which is also wrong.
NSStrings are compared with the isEqualToString e.g.
NSString * s1 = #"String One";
NSString * s2 = #"String Two";
if([s1 isEqualToString:s2])
// do something when strings are equal