Compiling issues on STTwitter for OSX App - objective-c

I've been working on an app for OSX (not my own, one that I am to maintain) that needs Twitter integrations and found the STTwitter wrapper. It says it's compatible down to OSX 10.7. However, when I try to compile it, I run into several compilation issues that I've tracked I think I've tracked down to not being able to compile with Objective-C literal subscripts.
I tries using the workaround suggested across the web for adding my own interfaces, but that didn't seem to help.
The first compilation error I get is "Array subscript is not an integer" at the following chunk of code in NSError+STTwitter.m:
NSMutableDictionary *md = [NSMutableDictionary dictionary];
md[NSLocalizedDescriptionKey] = message;
if(underlyingError) md[NSUnderlyingErrorKey] = underlyingError;
if(rateLimitLimit) md[kSTTwitterRateLimitLimit] = rateLimitLimit;
if(rateLimitRemaining) md[kSTTwitterRateLimitRemaining] = rateLimitRemaining;
if(rateLimitResetDate) md[kSTTwitterRateLimitResetDate] = rateLimitResetDate;
If I comment that code out, just to see what happens (the literal substring I believe), I get more issues in STTwitterOS.m
NSString *value = [keyValue[1] stringByReplacingOccurrencesOfString:#"\"" withString:#""];
[md setObject:value forKey:keyValue[0]];
Those give "Bad receiver type NSArray" and "Sending NSArray to parameter of incompatible type 'id
Any help would be appreciated. My objective c coding isn't that great....

Related

Xcode 4.5.1 new warning (potentially insecure)

I upgraded my Xcode to Version 4.5.1 and suddenly previous app development had 'potentially insecure' during build.
it generally applies to declaring this type of construct:
NSString *userChoice = [NSString stringWithFormat:label1a.text]; //Warning at pulling string from label1a.text
[usrAnswer setObject:userChoice forKey:#"1"];
is this a serious warning? How do i rectify this?
You are not using a format string. Just do this:
NSString *userChoice = label1a.text;
I see a lot of people create strings with stringWithFormat:. Only use that when you are actually creating a string with format specifiers.

Casting Objective-C Objects

I've been wondering this for a while, and Google hasn't provided me with the information I want. How fast does the casting process take? Does it depend on the number of fields an object has? Is it something to be avoided at all costs? Does it differ on x32, x64 and ARM machines?
Casting is only for the compiler to issue you better warnings. At runtime casting has no performance hit. All objects are just objects. You send messages to those objects.
The runtime doesn't care what type you gave when you had a pointer to that object in your code. It will send the message no matter what.
For example:
NSArray *myString = [NSString stringWithFormat:#"Hello"];
NSNumber *longerString = [(NSString *)myString stringByAppendingString:#" World"];
NSLog(#"%#", longerString);
Will log Hello World. You really give types to things so the compiler can check, but the runtime only knows that you're passing a message to an object. It will use the class of the object to look up the method to call from the message name, but it doesn't care what you typed at compile time.
You could have also done:
id myString = [NSString stringWithFormat:#"Hello"];
id longerString = [myString stringByAppendingString:#" World"];
NSLog(#"%#", longerString);
And the runtime will do the exact same thing, but the compiler will match up your types differently and generate warnings/errors based on different semantics (basically, does any object say it responds to this message).

NSString may not respond to EncryptAES- Xcode Warning

It seems like I have the correct code, and it compiles, runs, and builds. BUT it does not carry out certain lines of code because of the following error: "NSString may not respond to EncryptAES"
The code where the warning occurs is contained below:
- (IBAction)Encrypt {
//Change the Input String to Data
NSData *objNSData = [NSData dataWithData:[Input dataUsingEncoding: NSUTF8StringEncoding]];
//Encrypt the Data
objNSData = [Input EncryptAES:Keyword.text]; //Line with Warning
I have searched StackOverflow for problems like this and figured that to cure this error I should use some sort of code like this in my header file:
#interface  NSString
-(NSString*)AESEncrypt:????
#end
Would this fix the warning? If so, then what do I put where the questions go?
If this code will not fix the problem then what do I do to get rid of this error and make the code function?
EDIT: I have also tried this using NSData, I get the same resulting warning
You're calling EncryptAES class method against "Input" which based on your comment and code above ([Input dataUsingEncoding...) appears to be an NSString.
NSString does not offer an EncryptAES method:
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html
Checkout these SO posts:
AES Encryption for an NSString on the iPhone
uses: http://pastie.org/426530
iPhone - AES256 Encryption Using Built In Library
See here. Apparently EncryptAES is a "category" for NSData. I doubt that it will work on an NSString.

Xcode. Question about syntax error checking

Xcode looked at this line and did not complain. Project built, code crashed at runtime.
NSString *randomName = [NSString stringWithFormat:#"%#, %#, %#",
[randomAjectiveList objectAtIndex:ajectiveIndex],
[randomNounList objectAtIndex:nounIndex]];
Naturally, come to think about it, i have one too many "%#" in place, one more then actual arguments. Correct code should look as follows
NSString *randomName = [NSString stringWithFormat:#"%#, %#",
[randomAjectiveList objectAtIndex:ajectiveIndex],
[randomNounList objectAtIndex:nounIndex]];
I ask you though ... why didn't Xcode complain? Seems like such an obvious thing to do with param counters. Shouldn't this be checked at compile time? Is it specific to "%#", perhaps?
Please advise.
Based on a quick check, you're 100% right that this isn't checked at compile time, seemingly even by the static analyser. Conversely, NSLog is checked. So on my machine, with XCode 4.0.2, the following:
[NSString stringWithFormat:#"%d %# %#"];
NSLog(#"%d %# %#");
Produces a warning on the NSLog of "More '%' conversions than data arguments" but fails to comment on the NSString.
So, the difference could be fixed function calls versus dynamic calls. The compiler can't actually be completely certain where the NSString call will go because it's possible you'll have declared a category or used the low-level runtime to adjust the NSString selector table at runtime.
However, especially given the problems you'll almost immediately encounter if you start modifying the behaviour of the Foundation classes, like you I'd have expected at least a warning.

Cocoa QTKit and recording movies

I'm new with the whole QTKit and I was looking for some feedback on the following code that I am attempting to use to display the camera's image and record movies.
- (void)initializeMovie {
NSLog(#"Hi!");
QTCaptureSession* mainSession = [[QTCaptureSession alloc] init];
QTCaptureDevice* deviceVideo = [QTCaptureDevice defaultInputDeviceWithMediaType:#"QTMediaTypeVideo"];
QTCaptureDevice* deviceAudio = [QTCaptureDevice defaultInputDeviceWithMediaType:#"QTMediaTypeSound"];
NSError* error;
[deviceVideo open:&error];
[deviceAudio open:&error];
QTCaptureDeviceInput* video = [QTCaptureDeviceInput deviceInputWithDevice:deviceVideo];
QTCaptureDeviceInput* audio = [QTCaptureDeviceInput deviceInputWithDevice:deviceAudio];
[mainSession addInput:video error:&error];
[mainSession addInput:audio error:&error];
QTCaptureMovieFileOutput* output = [[QTCaptureMovieFileOutput alloc] init];
[output recordToOutputFileURL:[NSURL URLWithString:#"Users/chasemeadors/Desktop/capture1.mov"]];
[mainSession addOutput:output error:&error];
[movieView setCaptureSession:mainSession];
[mainSession startRunning];
}
Also, I'm not sure about the whole error parameter that the methods keep calling for, I saw the "&error" symbol in an example but I don't know what it means.
I'm also getting an error "cannot initialize a device that is not open" when I explicitly open the devices.
If anyone could help me sort this out, it'd be a great help, thanks.
QTCaptureDevice* deviceVideo = [QTCaptureDevice defaultInputDeviceWithMediaType:#"QTMediaTypeVideo"];
QTCaptureDevice* deviceAudio = [QTCaptureDevice defaultInputDeviceWithMediaType:#"QTMediaTypeSound"];
Pass the actual constants here, not string literals containing their names. There's no guarantee that QTMediaTypeVideo is defined to #"QTMediaTypeVideo"; it could be #"Ollie ollie oxen free", and even if it is what you expect now, it could change at any time.
[output recordToOutputFileURL:[NSURL URLWithString:#"Users/chasemeadors/Desktop/capture1.mov"]];
Don't assume that the current working directory is /. Always use absolute paths. (I know this is test code; in real code, of course, you would have run an NSSavePanel and gotten the path from there.)
Also, I'm not sure about the whole error parameter that the methods keep calling for, I saw the "&error" symbol in an example but I don't know what it means.
The & means you're taking the address of a variable, which in this case is error. You're passing this address (a.k.a. pointer) to the error: argument of one of QTKit's methods. The method will, if it encounters an error, create an NSError object and store it at that address—i.e., in your variable. This is called “return-by-reference” (the “reference” being the pointer you provided).
I'm also getting an error "cannot initialize a device that is not open" when I explicitly open the devices.
Which method returns the error? Are you talking about an NSError, or just a Console message? If the latter, check your NSError variable and see what the problem method left behind.
This, incidentally, is why you should bail out if any of the QTKit methods returns an error: one of the subsequent messages may clobber it with a new error if you don't.
Also, you may want to look at the MyRecorder sample code. It's a fully functional video recorder based on the QTKit Capture API. The code is reasonably simple and should be easy to understand.