For -[UIApplicationDelegate application:openURL:sourceApplication:annotation:], can the URL ever be nil? I'm asking because I saw someone put in a check if (url) // ..., but isn't that unnecessary? I.e., doesn't this method always get called with a non-nil NSURL argument for openURL?
Assuming an external invocation (ie from another app trying to open yours), then I would assume it is non-nil, however perhaps (unlikely I know) you call it internally in which case it might be?
Assumptions however are dangerous!
It would therefore seem prudent to sanity check the value before doing something that might cause a crash should the value be nil.
Seems OK to check if you ask me.
According to Apple Documentation, the url parameter is:
A object representing a URL (Universal
Resource Locator). See Apple URL
Scheme Reference for Apple-registered
schemes for URLs.
You have to register your application to accept specific URLs.
This article shows how it is done.
This would lead me to believe that this method would not be called unless it adhered to a URL Schema specified by the application.
If it is being called internally, than you would know whether you would need to check for nil or not. As for an outside application calling it, I can't see how that would happen.
Related
When using the PayPal JS v2 SDK, we usually a get device_data parameter in the call back.
I wasn't able to find any reference to this parameter, except in the Braintree::Transaction.sale documentation.
In production we intermittently see that no device_data parameter comes with the call back.
Is this expected behavior?
What causes it, and are there any implications?
Should we simply omit passing device_data on to Braintree::Transaction.sale?
device_data is a piece of parameter that contains various information about the customer device for fraud detection. Things like, device_session_id, fraud_merchant_id, correlation_id will be part of the device data. All these information are for fraud detection and risk information.
This is something which you should provide whenever you look for support in the future.
I am not sure if this is an issue/intended to have no device_data returned in the callback, perhaps you should give them a call at 877.434.2894 or email their Support team to check if there is an issue on this.
However, if you are not passing the device_data parameter in Braintree::Transaction.sale, I suppose that is fine. But the best practice is to have that piece of information.
I was looking for this on google and I found some articles on it They say it is used for HigherOrderMessaging and I tried to read the code to but everything was over my head can any body give simple example of it how we can use them? They were saying its used for passing returned object from method to another object. And another question when I develop apps never came situation where I need to use something like this.
In Objective-C, a trampoline is an object returned by a method that exposes some kind of message interface. When messages are received, it bounces the message on to another object.
Example One:
Return a proxy of a service client. When methods are invoked on the proxy, it first checks if the user has permission to proceed.
Example Two:
Make all the objects in an array do something:
[[windowsArray do] setHidesOnDeactivate:YES];
I have read about the CoreTelephony class and in this CTClass can check caller and find state of call....
But when and how to use this......
I think my application goes to background when call start..
help please or correct me......
It is not possible with the official SDK. The best that you can do is determine if the user is on a call. You can do this by inspecting the size of the status bar frame.
[UIApplication sharedApplication].statusBarFrame
If your asking if you can track phone calls in the background, you can't in all situations.
If you want to know if, at any point in time, when your running, you can. You can access the 'CTCallCenter' currentCalls property and it will give you the state of the call at that point in time.
If you want to track if a incomming call the cause of your application going to the background, you can use the 'CTCallCenter' callEventHandler property.
Not quite sure what you're trying to accomplish but after the call ends the user should automatically be brought back to the app.
It's not possible to get this information with the current SDK, most likely for privacy reasons. I'd recommend filing a feature request with Apple (http://radar.apple.com) however, I doubt it's something they're likely to include in the future.
In advance, please excuse my lack of understanding for iPhone/Objective-C Best Practices; I come from a .NET/C# background.
Although, I've read many posts regarding exception handling for the iPhone, I'm still not exactly clear on what most people do for production code. Also, I haven't been able to find any open source apps with error handling that I would normally expect. Here are my questions:
1) If an unexpected result occurs that would cause the application to eventually fail, would you throw an exception or just wait for it to fail later? For example,
if (![fileManager createDirectoryAtPath: myNewDir
withIntermediateDirectories: YES
attributes: nil
error: &myError]) {
// My app shouldn't continue. Should I raise an exception?
// Or should I just log it and then wait for it to crash later?
}
2) Do you validate parameters? For example, in C# I would usually check for null, and if needed throw an ArgumentNullException.
3) When an app crashes, does the crash info get logged automatically or do I need to set the unhandled exception handler? Can I show a UIAlertView within this method to inform the user something bad happened, instead of having the app just disappear? (If so, I couldn't get it to work.)
4) And finally, why don't I see anyone actually using #try/#catch/#finally? It's used extensively in C#, but I haven't found open source apps using it. (Maybe I'm just looking at the wrong apps.)
Ad 1. The example you give is a somewhat classical example of when one should use a "checked exception" in Java. The caller of the method has to be prepared, that the call can fail for reasons which are outside of what it can control. In particular, in the example given, I would allow the error descriptor object allow to propagate back to the caller:
- (BOOL) prepareDirectories: (NSString*) path error: (NSError**) location {
if( ![fileManager createDirectoryAtPath: path
withIntermediateDirectories: YES
attributes: nil
error: location] ) {
return NO;
}
// ... additional set-up here
return YES;
}
If the error is really not recoverable, you may actually raise an exception, but that will also forfeit any chance to show a proper error message to the user of your application.
Ad 2. Yes, parameter validation is definitely something you should do. And raising an exception for unexpected nils is entirely appropriate. A bad parameter is a "programmer's error" and you cannot guarantee, that the program is still in a consistent state. For example, NSArray raises an exception, if you try to get an element using an non-existent index.
Ad 3. When the app crashes due to an uncaught exception, the fact is logged automatically. You can catch the exception if you really want to display an error message. However, the app is likely to be in an inconsistent state, and should not be allowed to continue, so simply allowing it to go down seems the best solution here.
Ad 4. I don't know.
In the specific case you mention, you should present a notification to the user about what just happened with instructions on how to fix the situation. Except in extreme circumstances your app should not quit. You should let the user fix whatever is wrong, then try again.
Parameter validation depends on a lot of factors. One thing to keep in mind is that in Obj-C it's perfectly valid to send messages to nil (nothing happens if you do) so in a lot of situations you don't need to check for nil. If I'm in a model class I always validate parameters in methods. If I'm not I almost never validate anything, type checking is good enough.
Some information should be logged but it's always helpful to log more specific information to your situation. Ideally you shouldn't ever reach the unhandled exception state.
Cocoa classes will rarely throw exceptions for environmental reasons, they are almost always because you did something wrong. For example, you wouldn't usually put a #try/#catch block around [NSString stringWithString:] because the only way it'll throw an exception is if you try and pass nil. Make sure you aren't passing nil and you won't have to worry about catching exceptions. When a method might fail because of something outside of your control, they usually communicate via an NSError. See the - (BOOL)save:(NSError **)error method of NSManagedObjectContext for example.
How do you determine (programmatically) if an iPhone/iPod is:
Jail broken
Running a cracked copy of your software
Pinch Media can detect if a phone is jail broken or the software running is cracked, does anyone know how they do this? Are there any libraries?
Here is one of the ways to detect if your app was cracked.
In short: the cracking usually requires changing the Info.plist. Since it's regular file you have access to, it's pretty easy to determine such changes.
Detecting a jailbroken phone is as easy as checking for the presence of /private/var/lib/apt/ folder. Although this doesn't detect Installer-only users, by now most have have installed Cydia, Icy or RockYourPhone (all of which use apt)
To detect pirated users, the easiest way is to check for the presence of a SignerIdentity key in your app's Info.plist. Since advanced crackers can easily find the standard [[[NSBundle mainBundle] infoDictionary] objectForKey: #"SignerIdentity"] checks, it is best to obscure these calls using the Objective C runtime available via #import <objc/runtime.h> or use alternative equivalents.
Just to expand on zakovyrya's reply, you could use the following code:
if ([[[NSBundle mainBundle] infoDictionary] objectForKey: #"SignerIdentity"] != nil) {
// Jailbroken
}
HOWEVER, the person jailbreaking your app can hexedit your program and as such, they could edit the string #"SignerIdentity" to read #"siNGeridentity" or something else which would return nil, and thus pass.
So if you use this (or any of the other suggestions from http://thwart-ipa-cracks.blogspot.com/2008/11/detection.html):
Don't expect it to work forever
Don't use this information to break/hinder your app in any way (otherwise they'll have cause to hexedit it, so your app won't know it is jailbroken)
Probably wise to obfuscate this bit of the code. For example, you could put the base64 encoded reversed string in your code, and then decode it in the app by reversing the process.
Validate your validation later in your code (e.g. when I said SignerIdentity, did it actually say SignerIdentity or siNGeridentity?)
Don't tell people on a public website like stackoverflow how you do it
Keep in mind it is only a guide and is not fool-proof (nor cracker-proof!) - with great power comes great responsibility.
To expand on yonel's and Benjie's comments above:
1) Landon Fuller's method relying on encryption check, linked above by yonel, seem to be the only one still not defeated by automated cracking tools. I would not be overly worried about Apple changing the state of the LC_ENCRYPTION_INFO header any time soon. It does seem to have some unpredictable effects on jailbroken iphones (even when the user has purchased a copy...)
At any rate, I would not take any rash action against a user based on that code...
2) To complement Benjie's comment re. obfuscation (an absolute necessity when dealing with any string values in your anti-piracy code): a similar but perhaps even easier way is to always check a salted hashed version of the value you are looking for. For example (even though that check is no longer efficient), you would check each MainBundle's key name as md5(keyName + "some secret salt") against the appropriate constant... Rather basic, but sure to defeat any attempt at locating the string.
Of course, this requires you to be able to indirectly query the value you want to compare (for example by going through an array containing it). But this is most often the case.