Issue with NSString and concatenation - objective-c

Why this code gives me the following errors?
"use of undeclared identifier baseURL"
and
"Unexpected Interface name NSString, expected expression"
here is the entire block of code
switch (type) {
case 1:
NSString *baseURL = [NSString stringWithString:#"http://www.myserver.net/somephp/"];
NSString *finalURL = [baseURL stringByAppendingString:#"?i="];
break;
case 2:
NSString *finalURL = [baseURL stringByAppendingString:#"?n="];
break;
default:
break;
}

Sounds like those lines are within a switch statement. If this is the case, move the declaration of the strings outside the switch statement.
NSString *baseURL;
NSString *finalURL;
switch (<expression>) {
case <constant>:
baseURL = [NSString stringWithString:#"http://www.myserver.net/somephp"];
finalURL = [baseURL stringByAppendingString:#"?i="];
break;
default:
break;
}
More information and other techniques to work around this on this question.

Related

How do I handle file names with spaces?

I am using this code below to copy a file selected in the file browser and copying it to the temp directory with a different name. But when I select a file with spaces in it, the program throws an error saying it cannot find the specified fine path. I have tried using escape methods but they do not work either. Are there any other ways to handle file names with spaces?
Code starts here:
[openPanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) {
[openPanel close];
if (result == NSFileHandlingPanelOKButton) {
myString = [self randomStringWithLength:7];
NSString *filePath = [[[openPanel URLs] objectAtIndex:0] absoluteString];
NSLog(#"%#", filePath);
NSString *strTemp = [self extractString:filePath toLookFor:#"//" skipForwardX:2 toStopBefore:#".png"];
NSLog(#"%#",strTemp);
NSString *realThing = [strTemp stringByReplacingOccurrencesOfString:#"%20" withString:#"\\ "];
//strTemp = [strTemp stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"%#", realThing);
NSString* fullPath = [NSString stringWithFormat:#"/tmp/%#.png", myString];
NSLog(fullPath);
NSError *error = nil;
[[NSFileManager defaultManager] copyItemAtPath:realThing toPath:fullPath error:&error];
if(error) {
NSLog(#"Error!!!");
NSLog(#" error => %# ",error);
}
else {
NSLog(#"Saved to temp directory");
}
Anyone have experience with this? Thanks
Your conversion of the URL to a path is much too complicated and error-prone.
Just use the path method:
NSString *filePath = [[[openPanel URLs] objectAtIndex:0] path];
Alternatively, use copyItemAtURL:... instead of copyItemAtPath:....
You also should check the return value of copyItemAtPath:... as the indicator
of a failure:
if (![[NSFileManager defaultManager] copyItemAtPath:filePath toPath:fullPath error:&error]) {
NSLog(#" error => %# ",error);
}
Compare Handling Error Objects Returned From Methods:
Important: Success or failure is indicated by the return value of the
method. Although Cocoa methods that indirectly return error objects in
the Cocoa error domain are guaranteed to return such objects if the
method indicates failure by directly returning nil or NO, you should
always check that the return value is nil or NO before attempting to
do anything with the NSError object.
You seem to be trying to convert URLs to file paths by hand. Use fileSystemRepresentation instead.

For line Objective-C

I'm making an iOS code interpreter. I have all the checking done but as of now you can only enter one command. I want the user to be able to enter multiple commands into a UITextView. What I plan do with the text view is pass each line the my IF statement line.
Does anyone know of a way to say, pass each line one by one into a if statement line?
- (IBAction)runCommad:(id)sender {
//Alert
NSString *alertCheck = #"alert(";
NSRange alertCheckRange = [code.text rangeOfString : alertCheck];
//Logger
NSString *logCheck = #"log(";
NSRange logCheckRange = [code.text rangeOfString : logCheck];
if (alertCheckRange.location != NSNotFound) {
//If the compiler sees alert()...
NSString *commandEdit;
commandEdit = code.text;
commandEdit = [commandEdit stringByReplacingOccurrencesOfString:#"alert(" withString:#""];
commandEdit = [commandEdit stringByReplacingOccurrencesOfString:#")" withString:#""];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Syn0" message:commandEdit delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}else if (logCheckRange.location != NSNotFound) {
//If the compiler sees log()...
NSString *commandEdit;
commandEdit = code.text;
commandEdit = [commandEdit stringByReplacingOccurrencesOfString:#"log(" withString:#""];
commandEdit = [commandEdit stringByReplacingOccurrencesOfString:#")" withString:#""];
logFile = [NSString stringWithFormat:#"%#\n%#", logFile,commandEdit];
logTextView.text = logFile;
}
}
First, get your string components to evaluate:
NSString *text = [textView text];
NSArray *components = [text componentsSeperatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
You can't use a switch with a string, so you'll need to check for each case with an if:
for (NSString *string in components)
{
if ([string isEqualToString:#"The first string you're matching"])
{
//Do something because you found first string
}
if([string isEqualToString:#"The second string you're matching"])
{
//Do something else
}
}
That's the idea.
Two suggestions, first if you are comfortable with blocks you can use NSString's:
(void)enumerateLinesUsingBlock:(void (^)(NSString *line, BOOL *stop))block
This method will call the block passing it each line in the original string in order. If you want to stop before processing each line you set stop to YES.
Alternatively you can use NSString's:
(NSArray *)componentsSeparatedByString:(NSString *)separator
This will break a string up into components based on separator. Use this in a for enumeration:
for(NSString *nextLine in [originalString componentsSeparatedByString:#"\n"])
{
// process nextLine, break from loop to stop before processing each line
}

Alternative to switch statement in objective C

I am doing a project in which I am loading a table view with JSON data from an asynchronous connection. I am using a switch statement to load each row, like so:
dictionaryData = [responseString JSONValue];
switch (indexPath.row)
{
case 0:
{
NSString *name = [NSString stringWithFormat:#"%# : %# %#",#"Name",[dictionaryData valueForKey:#"firstName"],[dictionaryData valueForKey:#"lastName"]];
cell.textLabel.text = name;
break;
}
case 1:
{
NSString *email = [NSString stringWithFormat:#"%# : %#",#"Email",[dictionaryData valueForKey:#"email"]];
cell.textLabel.text = email; }
break;
There are 8 rows and i have to write 8 switch cases , which i think makes my method too long.
Can anyone tell me that is there any alternative to switch statements.
Replace your switch with an array. Each index in the array will correspond to one of the former cases. The array should be set up with the keys that you need
keyArray = [NSArray arrayWithObjects:#"Name", #"Email", ..., nil];
dictionaryData = [responseString JSONValue];
NSString * rowKey = [keyArray objectAtIndex:[indexPath row]];
[[cell textLabel] setText:[dictionaryData objectForKey:rowKey]];
In some cases an object would be a better alternative.
Update
I detailed how one might approach this (in an overengineered manner) here:
What alternatives to a switch statement could I use to update my UITableViewCells?
The alternative to switch is to use a series of if/else statements, which doesn't make the code any shorter. If your method is too long or too complex, move the body of each case into its own method, and then just call that method from its corresponding case.

getting string from one ViewController to another?

I have been working on my application for a while now. I am stuck on this small problem: setting my text field's text isn't working.The string of the text field is called from another viewcontroller Here is what my code looks like:
1st view controller
-(void)setURL:(NSURL *)src
{
downloadSourceField.text = src;
}
2nd view controller
if ([[booksArray objectAtIndex:indexPath.row] isEqual:[NSString stringWithFormat:#"%#",song_1]])
{
NSString *sc1 = [NSString stringWithFormat:#"tst 1"];
[tc setURL:sc1];
}
else
{
NSString *sc = [NSString stringWithFormat:#"test 2"];
[tc setURL:sc];
}
I think you're trying to assign an NSURL object to an NSString variable. What you should do is
downloadSourceField.text = [src absoluteString];
The absoluteString method will convert your NSURL into an NSString representation.

How to add file contents by dragging that file

I am using the following code to perform drag operation on NSTextView object.
- (BOOL)performDragOperation:(id )sender
{
NSPasteboard *pboard = [sender draggingPasteboard];
if ( [[pboard types] containsObject:NSURLPboardType] )
{
NSURL *fileURL = [NSURL URLFromPasteboard:pboard];
if ([[fileURL path] hasSuffix:#"plist"])
{
NSString *code = [NSString stringWithContentsOfURL:fileURL encoding:NSUTF8StringEncoding error:NULL];
int cnt = [[self string] length];
if (cnt) [self setSelectedRange:NSMakeRange(0, cnt)];
[self insertText:code];
return YES;
}
}
return NO;
}
I have declared this method in the .h file as well.
But after running the code it showing following warnings.
warning: 'AppConroller' may not respond to '-string'
(Messages without a matching method signature will be assumed to return 'id' and accept'...' as arguments.)
warning: 'AppConroller' may not respond to '-setSelectedRange:'
warning: 'AppConroller' may not respond to '-insertText:'
You're sending self (the AppController) messages it doesn't support. I think you mean to have [sender string], [sender setSelectedRange:], and [sender insertText:].
Is it possible it's just a typo? All your warnings refer to "AppConroller", but I bet the class is actually named "AppController".