My iPhone application needs to provide different features in some local markets, so I need to be able to determine where the devices "home" market is or from which store it was downloaded (if applicable).
I've tried almost all variations of NSLocale but I always seem to be able to change one or more of the settings.
I need to disable one tab if they are not in the US/CA for legal reasons, and I'd prefer to keep just the single binary.
Does anyone know how to do this?
Thanks
You could get the country code using
NSString *countryCode = [[NSLocale currentLocale] objectForKey: NSLocaleCountryCode];
But I'd imagine that data is quite easy to fake (it's dependent on the user's settings rather than where they actually live). It depends how secure your app needs to be - I would recommend uploading a separate binary for US/CA users if this is a major concern.
Related
I have an app submitted to the app store that was rejected due to:
2.30 Apps that do not comply with the Mac OS X File System documentation will be rejected
They claim my app is modifying the ~/Library/Preferences/com.apple.spaces.plist file which is unsupported.
My app is in fact modifying that file, but only with NSUserDefaults via: (I'm omitting some code for brevity...)
NSMutableDictionary *spacesDefaults =
[[NSUserDefaults standardUserDefaults] persistentDomainForName:#"com.apple.spaces"];
NSMutableDictionary *dict = [spacesDefaults objectForKey:#"app-bindings"];
NSString *bundleId = [[[NSBundle mainBundle] bundleIdentifier] lowercaseString];
[dict setObject:#"AllSpaces" forKey:bundleId];
[spacesDefaults setObject:dict forKey:#"app-bindings"];
[[NSUserDefaults standardUserDefaults] setPersistentDomain:spacesDefaults
forName:#"com.apple.spaces"];
It seems to me that this falls under the first bullet of "File-System Usage Requirements for the Mac App Store" http://developer.apple.com/library/mac/#releasenotes/General/SubmittingToMacAppStore/_index.html#//apple_ref/doc/uid/TP40010572
* You may use Apple frameworks such as User Defaults, Calendar Store, and Address Book that implicitly write to files in specific locations, including locations is not allowed to access directly.
Does anyone know why this would get rejected? I just don't see it...
Thanks!
This is a really important issue that I bemoaned on the Apple Dev Forums...
And I suppose that filing a Feedback Request might have an effect, someday... But apparently this LAME restriction.. which limits an App's ability to do ANYTHING outside the sandbox.. EVEN IF it's something your user can do... This is a serious step backwards in the ability of third-party apps on the mac to perform SIMPLE, implicit commands by the user.
This seems like a fundamental paradigm shift on Apple's part. Here's the jist of the above forum listing..
NSUserDefaults can be used only for our own app,
and sandboxing will not allow to modify other apps defaults
Additionally, you cannot modify in any way ANY other app's .plist, via XML, or otherwise.
And, no, doing defaults write via a task or terminal on another domain, besides YOUR OWN APP is outlawed as well. Ugh, it's very annoying.
I would like to have an app which simple opens different websites for different languages. So the main purpose of the app is simple to redirect to an web app. My questions:
does Apple allow such apps (in the Appstore of course) ?
how can it be achived to be listed in the different istores (by country, according to the language)
how to I open different websites for different languages?
Thank You!
Apple does allow Apps that just contain UIWebView pointing to a website.
Use NSString *countryCode = [locale objectForKey: NSLocaleCountryCode];
to find the Country code
Using a simple condition, set the URL relavent to the country code.
1) Yes, it is allowed, though discouraged and highly annoying. I immediately uninstall apps that do this.
2) You'll have to setup localization for your app for each language you would like to represent
3) You simply setup a web site, and write it in the language you would like on the site. Localization will save time here, too.
Although this might draw some traffic to your sites, it is not a good business model and you should probably try to make your app do something of benefit for the user. If your app is useful, you will get more than enough traffic to your sites through gentle prodding or in-app announcements of some kind.
First I need to mention that I'm not a developper, but I can probably work my way around enough in xcode to fix this little issue.
I submitted an application to the app store (that was developped by someone else who's not available right now), but it was rejected because it's "geolocked", meaning the application can only be accessed if you set your international "Region format" setting to Canada.
I need to know what modification I need to make in order for this app to work on all region formats. Is it a string I need to change or is it hidden in a plist file ? I have the feeling the fix is quite easy to apply.
I’ve never heard of an iPhone app using region formats to prohibit launches. I suspect your developer put this code in either out of naïveté or malice; either way, you’ll need to look for a section of code that inspects the region settings.
I'm not aware of something like "geolocking" of iOS application. The only thing you can do, which is quite close to your question, is to set in which countries is this application available. This can be set in iTunes Connect.
For business reasons the project I'm working on has the requirement to determine which country's itunes store an app has been purchased from.
Knowing where the user is at the time of purchase (via location services etc) is not suitable and they would prefer to have 1 universal binary rather than having to have a separate binary for every store.
Is this something the application can determine at run-time?
Note: the specific answer is NO. You can NOT get the app store country. (As of mid-2010.)
For general readers, the following could be useful ... it is quite a nuisance to collect exactly these code three fragments together:
// to ("usually") get the preferred language from those we supplied in bundle
// [[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0]
// to ("often") get the preferred language regardless
// [ [NSBundle preferredLocalizationsFromArray:[NSLocale ISOCountryCodes]] objectAtIndex:0]
// to ("fairly reliably") get the user's chosen language setting...
// [ [NSLocale preferredLanguages] objectAtIndex:0]
Cheers
Have you tried hidden using in-app purchases to determine the store?
Hmm, could this be regarded as a violation of a customers right to privacy? I would imagine you have already looked at the reporting done back to you from the app store. If it's not in that data, I would imagine you won't be able to get it.
What are accepted methods to reduce iPhone application piracy, which do not violate Apple's evaluation process?
If my application "phones home" to provide the unique device ID on which it runs, what other information would I need to collect (e.g., the Apple ID used to purchase the application) to create a valid registration token that authorizes use of the application? Likewise, what code would I use to access that extra data?
What seem to be the best available technical approaches to this problem, at the present time?
(Please refrain from non-programming answers about how piracy is inevitable, etc. I know piracy is inevitable. I am interested in programming-based answers that discuss how to reduce it. Thanks in advance for your understanding.)
UPDATE
Please visit and read
Thanks to chpwn in the comments.
Code that's way too old! - 11th May 2009
For now there's an easier way to detect if your iPhone application has been cracked for piracy use. This does not involve you to check the iPhone unique IDs against a list of accepted IDs.
Currently there are three things crackers do:
Edit the Info.plist file
Decode the Info.plist from binary to
UTF-8 or ASCII
Add a key-pair to Info.plist{SignerIdentity,
Apple iPhone OS Application Signing}
The last one is easiest to check with this code:
NSBundle *bundle = [NSBundle mainBundle];
NSDictionary *info = [bundle infoDictionary];
if ([info objectForKey: #"SignerIdentity"] != nil)
{ /* do something */ }
Generally we don't have SignerIdentity in any of the App Store applications we build so checking for nil then performing set instructions should make it more difficult for crackers and pirates.
I can't take credit for this so please visit How to Thwart iPhone IPA Crackers. There's loads of information there about piracy on iPhone and how to curb it.
As pointed out by Andrey Tarantsov in the comments, looking for the "SignerIdentity" string in the binary (using an app like HexEdit) and replacing it is pretty easy.
You could encode that string, but then again all you have to do is change one char of it and the app is not going to look for the "SignerIdentity" key anymore but for some other key that probably doesn't exist (therefore is null). That key being null, the app thinks it isn't cracked (since SignerIdentity should be null if the app isn't cracked).
Instead, I'd rather check the size of the info.plist and compare it to a reference value. I noticed Simulator and Devices builds don't have the same info.plist file size. Same goes for Debug, Release and Distribution builds. Therefore, make sure you set the reference value using the info.plist file size for the Device Distribution Build.
How to look for the filesize at launch:
It looks like saving MD5 checksum of Plist and checking CryptID should do well till some time.
Check iTunesMetadata.plist for the date of Purchace as sometimes, when an app is cracked, that date is changed to something outrageous.
Also check to see if the purchacer name field exists. In my experience with cracking apps for personal use, that is usually removed. If anyone knows how the anti dump protection of Temple Run works, you could use that in conjunction with some protection that poedCrackMod can't get (google poedCrackMod create hackulo.us account, go to dev center look for poedCrackMod, install it on iDevice).
Clutch which will not crack things with Temple Run like protection, has a feature called OverDrive intended to silence an app's crack detection. poedCrackMod has LamestPatch, which isn't as good. Also poedCrackMod is an open source bash script that can be reverse engineered. To recap, you have an app that has copy protection that can't be circumvented with clutch / overdrive but can be cracked with poedCrackMod. However poedCrackMod can't circumvent the app's in app piracy checks. It is hard to manually patch integrety checks in the app's executable. So your app is hard to crack.