How can you get Original Application Version in Production?












1















We recently transitioned a purchasable app to the "freemium" model. We are using Bundle.main.appStoreReceiptURL to pull the receipt and then check the "original_application_version" to see if a user downloaded an older paid version from the App Store, or if they downloaded a newer free version with a non-consumable in app purchase to upgrade to the full version.



This works perfectly when in testing Sandbox, but in Production, older versions of the app are not properly verifying that they were downloaded prior to the freemium version.



The following code is called with productionStoreURL and the receipt obtained from Bundle.main.appStoreReceiptURL:



private let productionStoreURL = URL(string: "https://buy.itunes.apple.com/verifyReceipt")
private let sandboxStoreURL = URL(string: "https://sandbox.itunes.apple.com/verifyReceipt")

private func verifyIfPurchasedBeforeFreemium(_ storeURL: URL, _ receipt: Data) {
do {
let requestContents:Dictionary = ["receipt-data": receipt.base64EncodedString()]
let requestData = try JSONSerialization.data(withJSONObject: requestContents, options: )

var storeRequest = URLRequest(url: storeURL)
storeRequest.httpMethod = "POST"
storeRequest.httpBody = requestData

URLSession.shared.dataTask(with: storeRequest) { (data, response, error) in
DispatchQueue.main.async {
if data != nil {
do {
let jsonResponse = try JSONSerialization.jsonObject(with: data!, options: ) as! [String: Any?]

if let statusCode = jsonResponse["status"] as? Int {
if statusCode == 21007 {
print("Switching to test against sandbox")
self.verifyIfPurchasedBeforeFreemium(self.sandboxStoreURL!, receipt)
}
}

if let receiptResponse = jsonResponse["receipt"] as? [String: Any?], let originalVersion = receiptResponse["original_application_version"] as? String {
if self.isPaidVersionNumber(originalVersion) {
// Update to full paid version of app
UserDefaults.standard.set(true, forKey: upgradeKeys.isUpgraded)
NotificationCenter.default.post(name: .UpgradedVersionNotification, object: nil)
}
}
} catch {
print("Error: " + error.localizedDescription)
}
}
}
}.resume()
} catch {
print("Error: " + error.localizedDescription)
}
}

private func isPaidVersionNumber(_ originalVersion: String) -> Bool {
let pattern:String = "^\d+\.\d+"
do {
let regex = try NSRegularExpression(pattern: pattern, options: )
let results = regex.matches(in: originalVersion, options: , range: NSMakeRange(0, originalVersion.count))

let original = results.map {
Double(originalVersion[Range($0.range, in: originalVersion)!])
}

if original.count > 0, original[0]! < firstFreemiumVersion {
print("App purchased prior to Freemium model")
return true
}
} catch {
print("Paid Version RegEx Error.")
}
return false
}


The first freemium version is 3.2, which is our current build. All previous builds were 3.1.6 or earlier.



The Production URL shouldn't be the issue, or else it wouldn't kick back the 21007 status code to trigger the Sandbox validation for us. However, troubleshooting this is particularly tricky since we can't test against the Apple's Production URL itself.



Does anyone have any insight as to why this would work in Sandbox but not Production?










share|improve this question

























  • Not an answer to the specific problem that you're asking about, but I'd strongly recommend reconsidering the use of UserDefaults to track if paid features should be made available. Tools exist that made it easy to modify user defaults values, even on non-jailbroken devices. This article details how user defaults can be exploited.

    – Jamie Edge
    Dec 31 '18 at 20:45













  • @JamieEdge Thanks for the tip! I will definitely change this. Does CoreData share the same risks as UserDefaults? It seems excessive to validate the receipt every time the user opens.

    – Brandogs
    Dec 31 '18 at 21:10













  • Yeah, storing data on the filesystem (such as the underlying SQLite database which would be used with Core Data) will almost always carry this sort of risk, as values are stored within the application's sandbox directory which can be viewed and modified (UserDefaults uses a plist file within the sandbox). The keychain is more difficult to modify on a non-jailbroken device - values might be extractable from the a backup, however I'm not aware of any simple way to modify the values (however it very much may be possible).

    – Jamie Edge
    Dec 31 '18 at 21:27
















1















We recently transitioned a purchasable app to the "freemium" model. We are using Bundle.main.appStoreReceiptURL to pull the receipt and then check the "original_application_version" to see if a user downloaded an older paid version from the App Store, or if they downloaded a newer free version with a non-consumable in app purchase to upgrade to the full version.



This works perfectly when in testing Sandbox, but in Production, older versions of the app are not properly verifying that they were downloaded prior to the freemium version.



The following code is called with productionStoreURL and the receipt obtained from Bundle.main.appStoreReceiptURL:



private let productionStoreURL = URL(string: "https://buy.itunes.apple.com/verifyReceipt")
private let sandboxStoreURL = URL(string: "https://sandbox.itunes.apple.com/verifyReceipt")

private func verifyIfPurchasedBeforeFreemium(_ storeURL: URL, _ receipt: Data) {
do {
let requestContents:Dictionary = ["receipt-data": receipt.base64EncodedString()]
let requestData = try JSONSerialization.data(withJSONObject: requestContents, options: )

var storeRequest = URLRequest(url: storeURL)
storeRequest.httpMethod = "POST"
storeRequest.httpBody = requestData

URLSession.shared.dataTask(with: storeRequest) { (data, response, error) in
DispatchQueue.main.async {
if data != nil {
do {
let jsonResponse = try JSONSerialization.jsonObject(with: data!, options: ) as! [String: Any?]

if let statusCode = jsonResponse["status"] as? Int {
if statusCode == 21007 {
print("Switching to test against sandbox")
self.verifyIfPurchasedBeforeFreemium(self.sandboxStoreURL!, receipt)
}
}

if let receiptResponse = jsonResponse["receipt"] as? [String: Any?], let originalVersion = receiptResponse["original_application_version"] as? String {
if self.isPaidVersionNumber(originalVersion) {
// Update to full paid version of app
UserDefaults.standard.set(true, forKey: upgradeKeys.isUpgraded)
NotificationCenter.default.post(name: .UpgradedVersionNotification, object: nil)
}
}
} catch {
print("Error: " + error.localizedDescription)
}
}
}
}.resume()
} catch {
print("Error: " + error.localizedDescription)
}
}

private func isPaidVersionNumber(_ originalVersion: String) -> Bool {
let pattern:String = "^\d+\.\d+"
do {
let regex = try NSRegularExpression(pattern: pattern, options: )
let results = regex.matches(in: originalVersion, options: , range: NSMakeRange(0, originalVersion.count))

let original = results.map {
Double(originalVersion[Range($0.range, in: originalVersion)!])
}

if original.count > 0, original[0]! < firstFreemiumVersion {
print("App purchased prior to Freemium model")
return true
}
} catch {
print("Paid Version RegEx Error.")
}
return false
}


The first freemium version is 3.2, which is our current build. All previous builds were 3.1.6 or earlier.



The Production URL shouldn't be the issue, or else it wouldn't kick back the 21007 status code to trigger the Sandbox validation for us. However, troubleshooting this is particularly tricky since we can't test against the Apple's Production URL itself.



Does anyone have any insight as to why this would work in Sandbox but not Production?










share|improve this question

























  • Not an answer to the specific problem that you're asking about, but I'd strongly recommend reconsidering the use of UserDefaults to track if paid features should be made available. Tools exist that made it easy to modify user defaults values, even on non-jailbroken devices. This article details how user defaults can be exploited.

    – Jamie Edge
    Dec 31 '18 at 20:45













  • @JamieEdge Thanks for the tip! I will definitely change this. Does CoreData share the same risks as UserDefaults? It seems excessive to validate the receipt every time the user opens.

    – Brandogs
    Dec 31 '18 at 21:10













  • Yeah, storing data on the filesystem (such as the underlying SQLite database which would be used with Core Data) will almost always carry this sort of risk, as values are stored within the application's sandbox directory which can be viewed and modified (UserDefaults uses a plist file within the sandbox). The keychain is more difficult to modify on a non-jailbroken device - values might be extractable from the a backup, however I'm not aware of any simple way to modify the values (however it very much may be possible).

    – Jamie Edge
    Dec 31 '18 at 21:27














1












1








1


1






We recently transitioned a purchasable app to the "freemium" model. We are using Bundle.main.appStoreReceiptURL to pull the receipt and then check the "original_application_version" to see if a user downloaded an older paid version from the App Store, or if they downloaded a newer free version with a non-consumable in app purchase to upgrade to the full version.



This works perfectly when in testing Sandbox, but in Production, older versions of the app are not properly verifying that they were downloaded prior to the freemium version.



The following code is called with productionStoreURL and the receipt obtained from Bundle.main.appStoreReceiptURL:



private let productionStoreURL = URL(string: "https://buy.itunes.apple.com/verifyReceipt")
private let sandboxStoreURL = URL(string: "https://sandbox.itunes.apple.com/verifyReceipt")

private func verifyIfPurchasedBeforeFreemium(_ storeURL: URL, _ receipt: Data) {
do {
let requestContents:Dictionary = ["receipt-data": receipt.base64EncodedString()]
let requestData = try JSONSerialization.data(withJSONObject: requestContents, options: )

var storeRequest = URLRequest(url: storeURL)
storeRequest.httpMethod = "POST"
storeRequest.httpBody = requestData

URLSession.shared.dataTask(with: storeRequest) { (data, response, error) in
DispatchQueue.main.async {
if data != nil {
do {
let jsonResponse = try JSONSerialization.jsonObject(with: data!, options: ) as! [String: Any?]

if let statusCode = jsonResponse["status"] as? Int {
if statusCode == 21007 {
print("Switching to test against sandbox")
self.verifyIfPurchasedBeforeFreemium(self.sandboxStoreURL!, receipt)
}
}

if let receiptResponse = jsonResponse["receipt"] as? [String: Any?], let originalVersion = receiptResponse["original_application_version"] as? String {
if self.isPaidVersionNumber(originalVersion) {
// Update to full paid version of app
UserDefaults.standard.set(true, forKey: upgradeKeys.isUpgraded)
NotificationCenter.default.post(name: .UpgradedVersionNotification, object: nil)
}
}
} catch {
print("Error: " + error.localizedDescription)
}
}
}
}.resume()
} catch {
print("Error: " + error.localizedDescription)
}
}

private func isPaidVersionNumber(_ originalVersion: String) -> Bool {
let pattern:String = "^\d+\.\d+"
do {
let regex = try NSRegularExpression(pattern: pattern, options: )
let results = regex.matches(in: originalVersion, options: , range: NSMakeRange(0, originalVersion.count))

let original = results.map {
Double(originalVersion[Range($0.range, in: originalVersion)!])
}

if original.count > 0, original[0]! < firstFreemiumVersion {
print("App purchased prior to Freemium model")
return true
}
} catch {
print("Paid Version RegEx Error.")
}
return false
}


The first freemium version is 3.2, which is our current build. All previous builds were 3.1.6 or earlier.



The Production URL shouldn't be the issue, or else it wouldn't kick back the 21007 status code to trigger the Sandbox validation for us. However, troubleshooting this is particularly tricky since we can't test against the Apple's Production URL itself.



Does anyone have any insight as to why this would work in Sandbox but not Production?










share|improve this question
















We recently transitioned a purchasable app to the "freemium" model. We are using Bundle.main.appStoreReceiptURL to pull the receipt and then check the "original_application_version" to see if a user downloaded an older paid version from the App Store, or if they downloaded a newer free version with a non-consumable in app purchase to upgrade to the full version.



This works perfectly when in testing Sandbox, but in Production, older versions of the app are not properly verifying that they were downloaded prior to the freemium version.



The following code is called with productionStoreURL and the receipt obtained from Bundle.main.appStoreReceiptURL:



private let productionStoreURL = URL(string: "https://buy.itunes.apple.com/verifyReceipt")
private let sandboxStoreURL = URL(string: "https://sandbox.itunes.apple.com/verifyReceipt")

private func verifyIfPurchasedBeforeFreemium(_ storeURL: URL, _ receipt: Data) {
do {
let requestContents:Dictionary = ["receipt-data": receipt.base64EncodedString()]
let requestData = try JSONSerialization.data(withJSONObject: requestContents, options: )

var storeRequest = URLRequest(url: storeURL)
storeRequest.httpMethod = "POST"
storeRequest.httpBody = requestData

URLSession.shared.dataTask(with: storeRequest) { (data, response, error) in
DispatchQueue.main.async {
if data != nil {
do {
let jsonResponse = try JSONSerialization.jsonObject(with: data!, options: ) as! [String: Any?]

if let statusCode = jsonResponse["status"] as? Int {
if statusCode == 21007 {
print("Switching to test against sandbox")
self.verifyIfPurchasedBeforeFreemium(self.sandboxStoreURL!, receipt)
}
}

if let receiptResponse = jsonResponse["receipt"] as? [String: Any?], let originalVersion = receiptResponse["original_application_version"] as? String {
if self.isPaidVersionNumber(originalVersion) {
// Update to full paid version of app
UserDefaults.standard.set(true, forKey: upgradeKeys.isUpgraded)
NotificationCenter.default.post(name: .UpgradedVersionNotification, object: nil)
}
}
} catch {
print("Error: " + error.localizedDescription)
}
}
}
}.resume()
} catch {
print("Error: " + error.localizedDescription)
}
}

private func isPaidVersionNumber(_ originalVersion: String) -> Bool {
let pattern:String = "^\d+\.\d+"
do {
let regex = try NSRegularExpression(pattern: pattern, options: )
let results = regex.matches(in: originalVersion, options: , range: NSMakeRange(0, originalVersion.count))

let original = results.map {
Double(originalVersion[Range($0.range, in: originalVersion)!])
}

if original.count > 0, original[0]! < firstFreemiumVersion {
print("App purchased prior to Freemium model")
return true
}
} catch {
print("Paid Version RegEx Error.")
}
return false
}


The first freemium version is 3.2, which is our current build. All previous builds were 3.1.6 or earlier.



The Production URL shouldn't be the issue, or else it wouldn't kick back the 21007 status code to trigger the Sandbox validation for us. However, troubleshooting this is particularly tricky since we can't test against the Apple's Production URL itself.



Does anyone have any insight as to why this would work in Sandbox but not Production?







ios swift receipt-validation






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 31 '18 at 20:33







Brandogs

















asked Dec 31 '18 at 18:56









BrandogsBrandogs

228




228













  • Not an answer to the specific problem that you're asking about, but I'd strongly recommend reconsidering the use of UserDefaults to track if paid features should be made available. Tools exist that made it easy to modify user defaults values, even on non-jailbroken devices. This article details how user defaults can be exploited.

    – Jamie Edge
    Dec 31 '18 at 20:45













  • @JamieEdge Thanks for the tip! I will definitely change this. Does CoreData share the same risks as UserDefaults? It seems excessive to validate the receipt every time the user opens.

    – Brandogs
    Dec 31 '18 at 21:10













  • Yeah, storing data on the filesystem (such as the underlying SQLite database which would be used with Core Data) will almost always carry this sort of risk, as values are stored within the application's sandbox directory which can be viewed and modified (UserDefaults uses a plist file within the sandbox). The keychain is more difficult to modify on a non-jailbroken device - values might be extractable from the a backup, however I'm not aware of any simple way to modify the values (however it very much may be possible).

    – Jamie Edge
    Dec 31 '18 at 21:27



















  • Not an answer to the specific problem that you're asking about, but I'd strongly recommend reconsidering the use of UserDefaults to track if paid features should be made available. Tools exist that made it easy to modify user defaults values, even on non-jailbroken devices. This article details how user defaults can be exploited.

    – Jamie Edge
    Dec 31 '18 at 20:45













  • @JamieEdge Thanks for the tip! I will definitely change this. Does CoreData share the same risks as UserDefaults? It seems excessive to validate the receipt every time the user opens.

    – Brandogs
    Dec 31 '18 at 21:10













  • Yeah, storing data on the filesystem (such as the underlying SQLite database which would be used with Core Data) will almost always carry this sort of risk, as values are stored within the application's sandbox directory which can be viewed and modified (UserDefaults uses a plist file within the sandbox). The keychain is more difficult to modify on a non-jailbroken device - values might be extractable from the a backup, however I'm not aware of any simple way to modify the values (however it very much may be possible).

    – Jamie Edge
    Dec 31 '18 at 21:27

















Not an answer to the specific problem that you're asking about, but I'd strongly recommend reconsidering the use of UserDefaults to track if paid features should be made available. Tools exist that made it easy to modify user defaults values, even on non-jailbroken devices. This article details how user defaults can be exploited.

– Jamie Edge
Dec 31 '18 at 20:45







Not an answer to the specific problem that you're asking about, but I'd strongly recommend reconsidering the use of UserDefaults to track if paid features should be made available. Tools exist that made it easy to modify user defaults values, even on non-jailbroken devices. This article details how user defaults can be exploited.

– Jamie Edge
Dec 31 '18 at 20:45















@JamieEdge Thanks for the tip! I will definitely change this. Does CoreData share the same risks as UserDefaults? It seems excessive to validate the receipt every time the user opens.

– Brandogs
Dec 31 '18 at 21:10







@JamieEdge Thanks for the tip! I will definitely change this. Does CoreData share the same risks as UserDefaults? It seems excessive to validate the receipt every time the user opens.

– Brandogs
Dec 31 '18 at 21:10















Yeah, storing data on the filesystem (such as the underlying SQLite database which would be used with Core Data) will almost always carry this sort of risk, as values are stored within the application's sandbox directory which can be viewed and modified (UserDefaults uses a plist file within the sandbox). The keychain is more difficult to modify on a non-jailbroken device - values might be extractable from the a backup, however I'm not aware of any simple way to modify the values (however it very much may be possible).

– Jamie Edge
Dec 31 '18 at 21:27





Yeah, storing data on the filesystem (such as the underlying SQLite database which would be used with Core Data) will almost always carry this sort of risk, as values are stored within the application's sandbox directory which can be viewed and modified (UserDefaults uses a plist file within the sandbox). The keychain is more difficult to modify on a non-jailbroken device - values might be extractable from the a backup, however I'm not aware of any simple way to modify the values (however it very much may be possible).

– Jamie Edge
Dec 31 '18 at 21:27












1 Answer
1






active

oldest

votes


















1














It looks like it was not a problem with obtaining the receipt at all.



Some of the older values for original_application_version were not formatted correctly, preventing us from obtaining the app version to compare against.






share|improve this answer
























  • Can you tell something about how they were formatted? I am now checking original_application_version in a production app by detecting if the string contains dots (full stops) but not a single user is getting the correct result.

    – Mr. Zystem
    yesterday













  • There is no guarantee about how it will be formatted since original_application_version uses the Build field, which developers can set however they want. However, you can check what these values have been in the past by logging into App Store Connect, opening your app, and then opening the Activity tab. Expand each version and look at the values listed in the Build column. Those are the values that are being returned for the original_application_version for that given build.

    – Brandogs
    11 hours ago













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53990592%2fhow-can-you-get-original-application-version-in-production%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














It looks like it was not a problem with obtaining the receipt at all.



Some of the older values for original_application_version were not formatted correctly, preventing us from obtaining the app version to compare against.






share|improve this answer
























  • Can you tell something about how they were formatted? I am now checking original_application_version in a production app by detecting if the string contains dots (full stops) but not a single user is getting the correct result.

    – Mr. Zystem
    yesterday













  • There is no guarantee about how it will be formatted since original_application_version uses the Build field, which developers can set however they want. However, you can check what these values have been in the past by logging into App Store Connect, opening your app, and then opening the Activity tab. Expand each version and look at the values listed in the Build column. Those are the values that are being returned for the original_application_version for that given build.

    – Brandogs
    11 hours ago


















1














It looks like it was not a problem with obtaining the receipt at all.



Some of the older values for original_application_version were not formatted correctly, preventing us from obtaining the app version to compare against.






share|improve this answer
























  • Can you tell something about how they were formatted? I am now checking original_application_version in a production app by detecting if the string contains dots (full stops) but not a single user is getting the correct result.

    – Mr. Zystem
    yesterday













  • There is no guarantee about how it will be formatted since original_application_version uses the Build field, which developers can set however they want. However, you can check what these values have been in the past by logging into App Store Connect, opening your app, and then opening the Activity tab. Expand each version and look at the values listed in the Build column. Those are the values that are being returned for the original_application_version for that given build.

    – Brandogs
    11 hours ago
















1












1








1







It looks like it was not a problem with obtaining the receipt at all.



Some of the older values for original_application_version were not formatted correctly, preventing us from obtaining the app version to compare against.






share|improve this answer













It looks like it was not a problem with obtaining the receipt at all.



Some of the older values for original_application_version were not formatted correctly, preventing us from obtaining the app version to compare against.







share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 5 at 19:19









BrandogsBrandogs

228




228













  • Can you tell something about how they were formatted? I am now checking original_application_version in a production app by detecting if the string contains dots (full stops) but not a single user is getting the correct result.

    – Mr. Zystem
    yesterday













  • There is no guarantee about how it will be formatted since original_application_version uses the Build field, which developers can set however they want. However, you can check what these values have been in the past by logging into App Store Connect, opening your app, and then opening the Activity tab. Expand each version and look at the values listed in the Build column. Those are the values that are being returned for the original_application_version for that given build.

    – Brandogs
    11 hours ago





















  • Can you tell something about how they were formatted? I am now checking original_application_version in a production app by detecting if the string contains dots (full stops) but not a single user is getting the correct result.

    – Mr. Zystem
    yesterday













  • There is no guarantee about how it will be formatted since original_application_version uses the Build field, which developers can set however they want. However, you can check what these values have been in the past by logging into App Store Connect, opening your app, and then opening the Activity tab. Expand each version and look at the values listed in the Build column. Those are the values that are being returned for the original_application_version for that given build.

    – Brandogs
    11 hours ago



















Can you tell something about how they were formatted? I am now checking original_application_version in a production app by detecting if the string contains dots (full stops) but not a single user is getting the correct result.

– Mr. Zystem
yesterday







Can you tell something about how they were formatted? I am now checking original_application_version in a production app by detecting if the string contains dots (full stops) but not a single user is getting the correct result.

– Mr. Zystem
yesterday















There is no guarantee about how it will be formatted since original_application_version uses the Build field, which developers can set however they want. However, you can check what these values have been in the past by logging into App Store Connect, opening your app, and then opening the Activity tab. Expand each version and look at the values listed in the Build column. Those are the values that are being returned for the original_application_version for that given build.

– Brandogs
11 hours ago







There is no guarantee about how it will be formatted since original_application_version uses the Build field, which developers can set however they want. However, you can check what these values have been in the past by logging into App Store Connect, opening your app, and then opening the Activity tab. Expand each version and look at the values listed in the Build column. Those are the values that are being returned for the original_application_version for that given build.

– Brandogs
11 hours ago






















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53990592%2fhow-can-you-get-original-application-version-in-production%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Monofisismo

Angular Downloading a file using contenturl with Basic Authentication

Olmecas