ios distribution preproduction and production version - ios

I am developing an app for iPad which is using webservices. In current version I have a constant string which is the address of the server. Each time I want to check something I just change the address (from production, freezed version of app to preproduction, version that is equal to repository). The problem is I would like to have two versions of an app on iPad, but I think as long as the bundle identifier is the same it isn't possible. What is the proper way of doing so without creating another project? Can I have "two targets" which can distribute both versions of app with the only difference being the webservice address?
This problem will escalate when application will be delivered to the client, because whenever I will deploy test version the "freezed" version will be deleted.
Should I change the bundle identifier each time I change webservice address before deploy? Or maybe there is some "automated" way of doing so?
Thanks in advance

I wouldn't rely on the bundle identifier for your service call as you will end up with many version of your API in the server that you need to maintain. What you can do is to create a new target on your project and add a Pre processor macro to your Build settings and then you reference on that macro in your code to decide which URL use.
Then on your code:
- (NSURL *)url {
NSString *urlString = #"your://standars.url";
#if APITEST
urlString = #"your://test.url";
#endif
return [NSURL URLWithString:urlString];
}

Related

Is it possible to have Fabric and AppStore builds at the same time?

I have an app for iPhone and always sending a testing builds to client. At the same time I have an App Store version of this app. Client wants to have beta and stable app version on device at the same time. Is it possible to do without creating a new app with another bundle id?
You can only have on app on your device with the same BundleID.
If you want both the appstore version and a test version you will need to create a new BundleID for this test version.
I suspect you could do this using separate IDs for the debug and built app and using multiple schemes to share the code base between them.
Check out this article that will help
http://nilsou.com/blog/2013/07/29/how-to-have-two-versions-of-the-same-app-on-your-device/
--Edit--
Just noticed you specifically don't want different bundles due to Push Notifications. We got around this by letting our back end services know which app we were using, and targeting the different services based on which app they use. You can do this by defining preprocessor macros like this: Add preprocessor macro to a target in xcode 6
... then reference them just before you call your back end service to register your device like this...
#ifdef ENTERPRISE
env = GLOBAL_PushNotificationEnvironmentEnt;
#endif
#ifdef DEBUG
// In debug mode, the environment should be set to Development
env = GLOBAL_PushNotificationEnvironmentDev;
#endif
if (notificationsOnBool) {
[service RegisterPushNotificationTarget:self
TargetType:GLOBAL_PushNotificationTargetType
TargetToken:deviceID
DeviceName:[UIDevice currentDevice].name
EnvironmentType:env];
}
... then in your back end code you do something like this (psuedo-code)
if (device.env == Fabric) {
sendNotification(fabricService);
} else {
sendNotification(prodService);
}

How to get containing application version from it's extension on iOS8?

I have an app with an extension on iOS8.
In extension, I make calls to my own API server with parameters those include "application version".
I can keep extension version and app version equal on every application deployment to App Store.
I can set application version to shared NSUserDefaults that can be read by extension.
I don't prefer above solutions. Is there anyway to get the containing application's version dynamically?
Have you ever tried to access infoDictionary? You can reach many information about your app from that.
For current version;
[NSString stringWithFormat:#"current version = %#", [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleShortVersionString"]]

How does flurry analytics track my apps version number?

I'm viewing my top used version numbers in flurry for my app. It appears flurry is using the build number field (bundle version) in my plist to report what version a particular app is. Is this true? If so, can I have use a different field in my plist? (i.e Bundle Version string short) How? I frequently change the build number and I want to see something like 1.0.1 (a version) instead of 28 (a build number) in flurry.
I got bit by this too, it seems bizarre to me they would use the build number by default. I added an auto-incrementing build number script and by the time I next checked Flurry, it showed about 100 different "versions", each just a new build. Ugh, what a mess.
The good news is the Flurry API provides a way to explicitly set the reported app version at runtime. I have a #define in my prefix file that links to the "short version string", which in Apple's system is basically your user-facing app version (e.g. "1.0.2"), and is probably the one you want to be tracked in Flurry.
#define kAppVersion [[NSBundle mainBundle] objectForInfoDictionaryKey:#"CFBundleShortVersionString"]
Doing it this way means that you don't have to remember to set the version in more than one place. Set it in your target's "Identity" section or in the Info.plist file and you're done.
Then in my app delegate's application:didFinishLaunchingWithOptions: method, when I start up Flurry collections, I tell it to use that.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[Flurry setCrashReportingEnabled:YES];
[Flurry setAppVersion:kAppVersion]; // <-- will now report your short version string
[Flurry startSession:kFlurryAPIKey];
// ...
}
Above method is deprecated instead user as below.
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
Flurry.startSession("xxxxxxxxxxxxxxxxxxx", with: FlurrySessionBuilder
.init()
.withCrashReporting(true)
.withLogLevel(FlurryLogLevelAll).withAppVersion(version))
}

improper advertising identifier [IDFA] usage, but it doesn't

While uploading app-file to itunesconnect the XCode says: improper advertising identifier [IDFA] usage...etc.
But I do not use this feature in my project. I've tried to find any
[[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]
calling. Futhermore, I'm just fixing a bug of my app, I hadn't included such features since my first release. The first release didn't said about IDFA-usage.
Well, this error happened about 15 days ago and it wasn't clear what is the reason till Apple released the Xcode update the same day and everything went smooth after that. Again, today I get the same message though I tried to upload the same builds for an app which I submitted 8 days ago.
I think we have just to wait for a few hours and see what will happen.
EDIT: Here is a link to show people complain about it at that time and how it was solved without doing anything: LINK
UPDATE: For anyone who uses PlayHaven ads, this may be helpful to avoid this error. Comment the 2 following sections:
In the file PHAdRequest.m (Lines 35-44)
/* if (![PHAPIRequest optOutStatus] && [ASIdentifierManager class])
{
NSUUID *uuid = [[ASIdentifierManager sharedManager] advertisingIdentifier];
NSString *uuidString = [uuid UUIDString];
if (0 < [uuidString length])
{
theIdentifiers[#"ifa"] = uuidString;
}
}*/
In PHAPIRequest.m (Lines 379-383):
/* if ([ASIdentifierManager class])
{
NSNumber *trackingEnabled = [NSNumber numberWithBool:[[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]];
[combinedParams setValue:trackingEnabled forKey:#"tracking"];
}*/
This is a temporary workaround till PlayHaven updates their SDK.
I had provided this answer on another similar question and it seems to have been of help & I think my answer is particularly suited also to this question...
I had a similar error in an update to an app that had previously updated fine and then a few days ago was causing an error, after Apple made a recent change. I wasn't using any ads but do have Facebook integration (which needs the AdSupport framework). I believe, after searching the net, that Facebook uses the advertising ID for its own analysis purposes so, even though I'm not including ads in my app, the validation and upload processes through xCode were failing with the error "Your app contains the Advertising Identifier [IDFA] API..."
I searched and found that I needed to download the Facebook SDK source code, update the FBUtility.m to remove the references to the advertisingID but, in fact, I simply needed to:
1) download the source code for the latest SDK, which I did from here: https://github.com/facebook/facebook-ios-sdk (I downloaded the zip file from github to my documents folder)
2) build the framework - open the terminal. Use cd documents at the command prompt, then use this command: sudo scripts/build_framework.sh, which will run the build_framework.sh script that is in the scripts subfolder within the downloaded Facebook SDK folder
3) Remove the old FacebookSDK.framework from your Xcode project and add the new one (in my case, I navigated to documents/facebook-ios-sdk/build & choose the FacebookSDK.framework folder
4) Archive the project and it should (it was in my case) be good to upload
Hope that helps someone along the way - I've been at this for days!!
Simply upload your binary as you've been doing this while, and broadly classify IDFA in two categories:
publisher: You use third-party ad-networks library to display ad. Choose the 1st option in IDFA -> "Serve advertisements within the app". You're a publisher since you show ads, but do not perform advertising for your own app.
Advertiser: You use third-party libraries to track conversions for your app, as well as track 'goals' in your app. You directly do not show ads in your app. Choose the 2nd & 3rd option in IDFA -> "Attribute this app installation to a previously served ad". AND "Attribute an action taken within this app to a previously served advertisement".
Mixed: You track conversions for your app, as well as display ads in your app. Choose all three options.
In case of PlayHaven, setup PH_USE_AD_SUPPORT to 0 will disable the AdSupport framework.
PHConstants.h
/**
* By default, PlayHaven will require the AdSupport framework. Projects using a version of
* Xcode older than 4.5 may define \c PH_USE_AD_SUPPORT to be 0.
*
* #note By disabling the AdSupport framework, the SDK will not be able to collect the IFA
**/
#ifndef PH_USE_AD_SUPPORT
#define PH_USE_AD_SUPPORT 1
#endif
Work for me to fix "improper advertising identifier" when submit.

Install IPA using itms-services from disk on iOS device [duplicate]

I'm trying to install an iOS app from a plist on the device's filesystem.
NSString *launchNewPlistURL = [NSString stringWithFormat:#"itms-services://?action=download-manifest&url=file://%#",[self saveFilePath]];
[[UIApplication sharedApplication]openURL:[NSURL URLWithString:launchNewPlistURL]];
And I'm prompted with "(null) would like to install {myappname}". Usually (null) is the domain name the plist is coming from, but in this case it's null as it's a local file.
Is there anyway to specify the title in the plist or pass a fake domain name in the url?
Thanks,
Dan
You can use the project MongooseDaemon to create an HTTP local server.
With a domain similar to: http://192.168.xxx.xxx/yourplist.plist to install it.
Anyhow, I think you can't use it with an large IPA. I have tried with my IPA greater than 15MB and it is very, very slow to start the install.
I was in a similar situation, and went through the route of using Mongoose originally, but just today stumbled upon CocoaHttpServer.
With Mongoose, I was only getting about a 20% success rate serving up local plist/IPA files. Sometimes the localhost would like to install dialog never came up, sometimes install started and failed about halfway in, and sometimes it actually worked. Even worse, once an App failed, I had to completely uninstall and reinstall it, so all data was lost. I was never able to successfully "fix" a failed install.
So far, with just about 10-15 minutes of testing, the CocoaHttpServer hasn't failed, yet. I know this is a very small sample size, but my Mongoose success rate was around 10%.
self.httpServer = [[HTTPServer alloc] init];
[self.httpServer setType:#"_http._tcp."];
[self.httpServer setPort:8080];
//This is just a path where I save my IPA and Plist file locally.
//In my case it's /{NSDocumentDirectory}/install/
[self.httpServer setDocumentRoot:[self pathForLocalInstallFiles]];
Then the URL to the plist on the disk:
NSURL *plistUrl = [NSURL URLWithString:#"itms-services://?action=download-manifest&url=http://localhost:8080/appname.plist"];
[[UIApplication sharedApplication] openURL:plistUrl];
Inside the plist, where you have your URL that points to the local IPA file, I had success using either file:// or http://localhost/.

Resources