I am using multiple in-app purchases within my app, and I need to check, sometimes for two at once, for example,
if a user has made a purchase for featureA or featureB or featureC
or perhaps they have made A & B but not C... for example;
if ([MKStoreManager featureAPurchased] && [MKStoreManager featureCPurchased] ) {
bannerView_.hidden = YES;
What I am trying to do is say "if you have purchased feature A OR feature C then bannerView will be hidden.
I know how to do it for just one (ie featureA) but if I am trying to check for if BOTH those features have been purchased, that is where I am struggling.
I guess I am doing it wrong, as it does not appear to work correctly? I am probably muddling up the statement using &&?
&& is the operator used for saying 'and'. If you want to say 'or', use ||.
So, you want
if ([MKStoreManager featureAPurchased] || [MKStoreManager featureCPurchased] ) {
bannerView_.hidden = YES;
How are you checking that the user has purchased something? The usual way to check this is either have this information persisted in the app (User Defaults or database) or asking App store with -[SKPaymentQueue restoreCompletedTransactions]. Restoring transactions gives you information about all available products purchased for the user in your app, so this should give you enough to accomplish what you want
Related
I'm currently working on a mobile game using Unity3D and Soomla for the in-app purchases part. Currently I'm trying to implement the 'restore' functionality for non-consumable item (I only have 1 which is "No Ads"). In order to do this; I used "SoomlaStore.RestoreTransactions" functions and restore the item if "OnRestoreTransactionsFinished" received true.
The problem is that whenever the "OnRestoreTransactionsFinished" is called, the value it received will always be TRUE even though that device/account never purchase the item before. According to Soomla website;
success is a boolean value that says if the restore transactions
operation hass succeeded or failed
Am I misunderstanding something here? Does the value will always be true even if the account never purchase the item before? Does this means I need to use something else to check whether the item should be restore and that my way of doing things now are totally wrong? Thank you.
For future readers... OnRestoreTransactionsFinished returns whether or not the transactions have been restored or not. It does not tell which products or anything.
The RestoreTransactions function call will call the OnMarketPurchased event for each item restored, so you can use that to update your app with each item that has been restored.
I am working with GWT / RequestFactory and a set of customer requirements regarding permissions. Let me explain a basic example:
Every user is assigned to a company. Every user should be able to edit company's core data - but only e.g contact information, website etc. Security-relevant ones like BIC/SWIFT, IBAN, Company name and so on can only be changed if the user has a certain permission XY.
So far so good, on the client side I can check the permissions and disable those fields the user is not allowed to edit. But what would be the most elegant way to ensure on the server side that those fields have not been set without permission?
My problem is that I cannot track changes on the server side. Having #PreAuthorize on every setter is not an option too, because it would end in an authorization-massacre in each and every entity.
At the moment I am following a workaround: every field that is secured / depends on a given permission is passed as an argument to the entity-method and is excluded from the proxy. That way, values cannot be set using the proxy and I can check in my server code if the user has permissions. If not, nothing happens. If user has permissions, I set the values manually. But that produces a lot of boilerplate-code and ugly method signatures because the number of values passed to the method could get large.
I hope you understand my issue. I'm looking forward for your opinions and tips. Thank you in advance.
Well, you can receive many answers (different each other), and all of them could be right, so, at the end is your call. Wait for others answers. I am going to give you the approach that I followed (and it worked pretty well). :D.
Under my opinion, the server should do less as possible, so keep the logic for allowing modify each param on the server I think it is not a scalable solution (if your system has 1M users modifying everything at the same time, will your server work fluent?). I prefer let the client do the job (like Roomba :D).
For solving that problem, in our system we implemented an Access Control List solution. You can store in your db, on each user entity, a list with granted permissions. So, when that information arrives to the client (after user's log in, for example), you can get them, and show the fields that he/she is allow to modify.
Something like:
if (canModifyPersonalDetails(user.getAcls(), ...) ) {
//show labels ...
}
if (canModifyBankDetails(user.getAcls(), ...) ) {
//show labels
}
You can not avoid server call for log in, so it is not a big deal send the extra information (think about the ACLs could be simple list of integers 0 means personal details, 1 bank details....).
If you are dealing with very compromised information and you prefer do some stuff on the server, in that case probably I'd set up a security level, when you are persisting/updating your proxy, I'd do something like:
if (isAllowForPersonalDetails(user.getSecurityCode()) {
//update the modified personal details
}
if (isAllowForBankDetails(user.getSecurityCode()) {
//update the modified bank details
}
user.update();
I am a big fan of clear User GUI's, and a very big fan of let the server free as much as possible, so I prefer the first option. But if you have constraints for modifying user entity in db, or you prefer do not modify your views, or any constraint with security, maybe the second option is the best one for you.
Hope that helps!
One of our clients wants to FE log in as two different users at the same time, using one browser. I think this is only possible when using two different browser. IS there any workaround?
Background is this: We wrote a FE extension where user can login and update some of their data. One client is a kind of superuser/admin. He wants to compare and edit data of several users at once.
Authentication in TYPO3 is performed by cookie fe_typo_user and therefore it is not possible to have two users logged in at same time from same browser.
You may advise to use different browsers or virtual machines for your client.
As Viktor wrote - it's not possible. Here I should finish the answer.
Anyway... while you are creating your own plugin you can easily add 'simulate mode' using for an example custom cookies... Block schema is:
[IF isAdmin AND simulateMode == false] {
Display admin's version
} [ELSE] {
Display common user's version
}
You can go even farther and switch the admin to simulate some chosen 'common' user, anyway make sure that will not violate some privacy police.
I am trying to implement in-app purchase for my Windows Store App (Metro App). I was referring to the code samples here, but when I triggered the RequestProductPurchaseAsync method nothing happens.
When I say nothing happens, it means literally nothing. No return results (the result was supposed to be a receipt since I passed in true for includeReceipt). Also, when I re-checked the ProductLicences[string].IsActive flag it will always return me false.
How do I test this out properly? Thanks a lot!
Make sure the app LicenseInformation.IsTrial is false, otherwise it won't work. In-app product purchases require that the app not be in trial. In a published app, the user would see an error stating that you can't do in-app product purchases under trial license. The simulator doesn't show this warning in the in-app purchase simulation dialog during testing.
You can either modify the initial state of the simulation (see the samples for how to do that) or call RequestAppPurchaseAsync(false) during the simulation run to get a full license for the app, then try the product purchase.
We experienced and solved a similar problem.
Using CurrentAppSimulator worked fine, but bringing up the real purchasing UI with CurrentApp did not.
In a production setting await CurrentApp.RequestProductPurchaseAsync(string,bool) seemed to never return (more specifically, it only returns once after the user has logged in -- subsequent calls did not return).
Additionally, after we tried to bring up the purchasing UI in our app, other applications using the purchasing UI had the same problem -- UI never shows.
Here is the problem code:
private async void CommandInvokedHandler(IUICommand command)
{
switch (command.Label)
{
case "Continue":
licenseInformation = CurrentApp.LicenseInformation;
if (!licenseInformation.ProductLicenses[Notes.ProductName].IsActive)
{
try
{
await CurrentApp.RequestProductPurchaseAsync(Notes.ProductName, false);
// The code never steps over
}
The somewhat-obvious problem with the code above is that the request to bring up the in-app purchase UI is made from within a modal dialog box command handler. The request hangs -- never returns. The not-so-obvious part is that it also blocks all subsequent requests from our application and every other application (until the user's session is restarted).
Upon moving the "try" block out of the command handler, and ensuring that there are no modal UI calls contesting the purchase request, purchasing worked without issue.
EDIT: You should restart (or re-login) to test this. Once the purchasing UI breaks, it will not show until you restart or re-login.
There is a small nuance to follow: to be able to purchase anything using CurrentAppSimulator one needs to call CurrentAppSimulator.RequestAppPurchaseAsync before making any purchase requests. After the operation returned by the call is done, you can successfully call CurrentAppSimulator.RequestProductPurchaseAsync (unless the IsTrial value in LicenseInformation element is set to false in the xml).
I've been looking at implementing the new VerificationController to verify in-App-Purchases:
http://developer.apple.com/library/ios/#releasenotes/StoreKit/IAP_ReceiptValidation/_index.html
And I wonder if there is some example anywhere en how to validate a transaction, since it seems that the - (BOOL)verifyPurchase:(SKPaymentTransaction *)transaction; is not enough and it has to be implemented internally to verify the purchase when the data form the server is received.
Another question is if anyone has a clue on what the KNOWN_TRANSACTIONS_KEY is and how to fill it, is it just the product id of the purchase?
In the file "VerificationController.m", check this function:
- (void)saveTransactionId:(NSString *)transactionId
we can see, KNOWN_TRANSACTIONS_KEY is a key to be wrote to NSUserDefaults. So we don't need to touch it.
login iTunes Connect > Manage Your Apps > (click your app) > Manage In-App Purchases > click the link View or generate a shared secret (at bottom-left of the page)
it'll show us:
A shared secret is a unique code that you should use when you make the
call to our servers for your In-App Purchase receipts.
Just click Generate.
You can find a complete implementation over here: https://github.com/evands/iap_validation
RayWenderlich.com Tutorial
This article, In-App Purchases in iOS 6 Tutorial: Consumables and Receipt Validation on the RayWenderlich.com site, offers a download of Apple's code but fleshed-out (including Base64 methods) and tweaked.
You need to perform the validation on a transaction when it changes to one of the completion states:
SKPaymentTransactionStatePurchased
SKPaymentTransactionStateRestored
call the function:
[[VerificationController sharedInstance] verifyPurchase:transaction];
As you say it is not enough to just look at the return value. The function is asynchronous. You need to add some code to VerificationController.m where it says:
#warning Validation succeeded. Unlock content here.
There are also a few other lines with #warning in VerificationController.m where you need to deal with errors.
As for base64 another library you might want to look at using is:
http://www.imthi.com/blog/programming/iphone-sdk-base64-encode-decode.php
When it comes to
KNOWN_TRANSACTIONS_KEY
and
ITC_CONTENT_PROVIDER_SHARED_SECRET
I too would like to know what they are for and why and when they are needed.