It appears that using the itms-apps//.... URL scheme doesn't work in iOS 6 with the new App Store to show the product reviews area. Now I'm using the code below, but it just shows you the product. How do you get to the review area to ask for a review and take the user to the right tab of the product displayed?
void DoReview()
{
var spp = new StoreProductParameters(appId);
var productViewController = new SKStoreProductViewController();
// must set the Finished handler before displaying the view controller
productViewController.Finished += (sender2, err) => {
// Apple's docs says to use this method to close the view controller
this.navigationController.DismissViewController(true, null);
MySettings.AskedForReview = true;
};
productViewController.LoadProduct(spp, (ok, err) => { // ASYNC !!!
if (ok)
{
this.navigationController.PresentViewController(productViewController, true, null);
}
else
{
Console.WriteLine(" failed ");
if (err != null)
Console.WriteLine(" with error " + err);
}
});
}
Hello you could try iRate from Nick Lockwood and see if that fits your needs, you can find the MonoTouch bindings of iRate here.
btw it uses the following URL to open AppStore in review mode:
itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id= your-AppID-here
Alex
Related
I have used Flutter Blue for a college work, where I need to create an application to fetch and pass information to an equipment. The passing of this data must be automatic, as in any application (after all the end user should not look for the services and characteristics necessary to carry out the process). The problem is that I am not being able to perform the data passing soon after connecting with the device.
I'm using the App example I downloaded at https://github.com/pauldemarco/flutter_blue, so the basic idea is that as soon as I connect to my bluetooth device I send a message to a certain device. There is already an answered question that has the interest of setting notifications when connecting at Flutter Blue Setting Notifications
I followed the same example but instead of using _setNotification (c) I used the _writeCharacteristic (c), but it does not work.
_connect(BluetoothDevice d) async {
device = d;
// Connect to device
deviceConnection = _flutterBlue
.connect(device, timeout: const Duration(seconds: 4))
.listen(
null,
onDone: _disconnect,
);
// Update the connection state immediately
device.state.then((s) {
setState(() {
deviceState = s;
});
});
// Subscribe to connection changes
deviceStateSubscription = device.onStateChanged().listen((s) {
setState(() {
deviceState = s;
});
if (s == BluetoothDeviceState.connected) {
device.discoverServices().then((s) {
services = s;
for(BluetoothService service in services) {
for(BluetoothCharacteristic c in service.characteristics) {
if(c.uuid == new Guid("06d1e5e7-79ad-4a71-8faa-373789f7d93c")) {
_writeCharacteristic(c);
} else {
print("Nope");
}
}
}
setState(() {
services = s;
});
});
}
});
}
I have changed the original code so that it prints me the notifications as soon as I perform the writing method. The notifications should show me a standard message that is in the firmware of the device, but instead it is printing me the Local Name of the bluetooth chip, being that if I select the service and characteristic manually the return is the correct message.
You'd need to elaborate how you're executing writes on the descriptor - inside _writeCharacteristic(c).
BluetoothDescriptor.write() is a Future per docs, you should be able to catch any errors thrown during write.
Im doing a POC of implementing the NFCTagReader into a xamarin.ios app.
https://developer.xamarin.com/samples/monotouch/ios11/NFCTagReader/
I've taken the NFCTagReader from the xamarin site and set all the appropriate provision settings to get access to the tag reader. The problem is that when i click scan the "Ready to Scan" window pops up as expected then i scan a tag and it shows the little tick on the screen to show that it found but it never breaks into the DidDetect method of my code in the delegate. It will hit the DidInvalidate method and give the code for ReaderSessionInvalidationErrorUserCanceled.
Any ideas what i'm missing. Following is my code snippet:
partial void Scan(UIBarButtonItem sender)
{
InvokeOnMainThread(() =>
{
Session = new NFCNdefReaderSession(this, null, true);
if (Session != null)
{
Session.BeginSession();
}
});
}
#endregion
#region NFCNDEFReaderSessionDelegate
public void DidDetect(NFCNdefReaderSession session, NFCNdefMessage[] messages)
{
foreach (NFCNdefMessage msg in messages)
{
DetectedMessages.Add(msg);
}
DispatchQueue.MainQueue.DispatchAsync(() =>
{
this.TableView.ReloadData();
});
}
public void DidInvalidate(NFCNdefReaderSession session, NSError error)
{
var readerError = (NFCReaderError)(long)error.Code;
if (readerError != NFCReaderError.ReaderSessionInvalidationErrorFirstNDEFTagRead &&
readerError != NFCReaderError.ReaderSessionInvalidationErrorUserCanceled)
{
InvokeOnMainThread(() =>
{
var alertController = UIAlertController.Create("Session Invalidated", error.LocalizedDescription, UIAlertControllerStyle.Alert);
alertController.AddAction(UIAlertAction.Create("Ok", UIAlertActionStyle.Default, null));
DispatchQueue.MainQueue.DispatchAsync(() =>
{
this.PresentViewController(alertController, true, null);
});
});
}
}
Little bit of a blonde moment and was just going to close this question but thought would answer this just in case someone else comes across the same problem as I did.
The problem ended up being caused by the fact that the tags that I was given were blank. Therefore the phone would click when it detected the tag but would never hit the didDetect method. As soon as I wrote something to the NFC tag with an Android tag writer app then DidDetect fired as expected.
This question already has answers here:
Publishing issue, Callkit is included even we are not using it
(2 answers)
Closed 5 years ago.
I have an app which enables an user to make phone call to a certain number. I am doing following:-
private void CallContact(string phone)
{
phone = phone.Replace(" ", "");
var callURL = new NSUrl("tel:" + phone);
try
{
if (UIApplication.SharedApplication.CanOpenUrl(callURL))
{
UIApplication.SharedApplication.OpenUrl(callURL);
}
else
{
var av = new UIAlertView("Not supported",
"Calling is not supported on this device",
null,
"OK",
null);
av.Show();
}
}
catch (Exception ex)
{
return;
}
}
This works fine. But when I tried publishing the app, my app got rejected and the Apple team asked me the following:-
We noticed that your app has CallKit and CallKit Blocker enabled:
⁃Which features of your app require CallKit and CallKit Blocker functionality?
⁃Where, specifically, in the app would users access these features?
I am not using the CallKit functionality anywhere in my app. I searched SO and found that it is shipped with the Xamarin.iOS.dll . It is possible that the way I am making calls in my app uses the CallKit?
Sorry for bein a noob :)
try this solution
partial void BtnContactBillingCall_TouchUpInside (UIButton sender)
{
var confirm = new UIAlertView("","Call "+ mobilenumber + " ?",null,"Cancel","Call");
confirm.Show();
confirm.Clicked += (object senderConfirm, UIButtonEventArgs e) =>
{
if(e.ButtonIndex ==0)
{
}
else
{
var url = new Foundation.NSUrl("tel:"+mBillingPhoneNumber);
UIApplication.SharedApplication.OpenUrl(url);
}
};
}
I have made my Cordova/Ionic app with in app purchases. During test period all works fine, published it live in Google Play and App Store all seems to be fine. Get lots of purchases, tested it myself on different devices and all seems ok. But then after a week the first email came in they purchases an IAP and it was not unlocked (iOS, have any issues heared from Android users). Tow weeks later a second... now I have like 15 people where is does not work and I have seen prove that they have purchased it.
I am using this IAP plugin:
https://github.com/AlexDisler/cordova-plugin-inapppurchase
Before that one I used another IAP plugin, but because of the same problem I started to use the first one:
https://github.com/j3k0/cordova-plugin-purchase
I also made a issue post on github but still no answer:
As I am not allowed to post more links atm, it is issue 113.
The code I use works in 99.9%:
loadProducts = function () {
$ionicLoading.show({ template: spinner + 'Loading...' });
inAppPurchase
.getProducts(productIds)
.then(function (products) {
$ionicLoading.hide();
// Load all products by ID
products.forEach(function (product) {
// Add extra field to the product object
product.owned = false;
switch (product.productId) {
case ncProductProVer:
if (GlobalVars.vars.fullVersion == true) {
product.owned = true;
}
break;
case ncProductNoAds:
if (GlobalVars.vars.noAds == true) {
product.owned = true;
}
break;
}
});
//alert(products[0].productId + ' ' + products[1].productId);
$scope.products = products;
})
.catch(function (err) {
$ionicLoading.hide();
//$cordovaDialogs.alert('Error loading products. Details:\n- Code: ' + err.code + '\n- Message: ' + err.message, 'Error', 'OK')
$scope.CodeError = true;
});
};
// BUY a product
$scope.buy = function (productId) {
$ionicLoading.show({ template: spinner + 'Buying...' });
inAppPurchase
.buy(productId)
.then(function (data) {
$ionicLoading.hide();
enableIAP(productId, true);
})
.then(function () {
$ionicLoading.hide();
loadProducts();
})
.catch(function (err) {
$ionicLoading.hide();
errHandling(err.code, productId);
});
};
// RESTORE in app purchases
$scope.restore = function () {
$ionicLoading.show({ template: spinner + 'Restoring purchases...' });
inAppPurchase
.restorePurchases()
.then(function (purchases) {
$ionicLoading.hide();
purchases.forEach(function (purchase) {
// Unlock the relevant feature based on this product id, if any
// Store the purchase in localStorage
enableIAP(purchase.productId, true);
});
// Reload the productlist
loadProducts();
})
.catch(function (err) {
$ionicLoading.hide();
});
};
I have tried many different things already, but cant figure out what the problem can be or how I can see what goes wrong as the app runs on a device where I don't have access to :).
The only thing I have is that people say the 'Buying...' popup keeps on loading till they close the app and run it again. So the problem must me in the .buy() function and does not give a error back but otherwise it will be in the .catch().
Things I can think of is:
- Apple does not always sends the same string back
- The string send back from Apple contains chars that are not correctly handled by the IAP code
To make things more odd, I managed to get in contact with somebody where it did not work. So I started testing some things as I thought maybe it could be device settings. So I had the iPhone and signed in with my iTunes account, downloaded the app and restored the IAP and it worked. Did the same thing, sign in with their iTunes account, did not work. That person also had an iPad mini, where it all worked as expected, the extra item in the app where unlocked as they should.
Anybody seen this strange behaviour? Been busy many weeks/months already to figure out what it could be.
I am building a food delivery app using Ionic. And I am having problems getting the app to work on mobile for the address creation step. After creating an account the user must create a delivery address, at which point the app figures out what delivery location to use.
Address creation works in Chrome (ionic serve) and in iOS simulator (ionic run ios -l -c -s).
However, once I've uploaded the app to my Ionic View iOS app for testing, it gets stuck at the Address creation step.
But at the address creation step, the Ionic loading wheel starts but it doesn't go away and there is no state transition to the menu.
Here is the implementation in the controller.
Address.create($scope.newAddress, $scope.user)
.then(function(response) { // never gets a response back in Ionic View
console.log("address created");
user.save(null,
{ success: function(user) {
// success callback
}, error: function(error) {
// throw error
}
});
}, function(error) {
// throw error
});
The Address.create() method I have implemented is fairly lengthy:
...
.factory('Address', ['$http', '$q', 'PARSE_HEADERS'
function ($http, $q, PARSE_HEADERS) {
return {
create: function(data, userID) {
var deferred = $q.defer();
var zipArray = ['1111','22222','33333'];
var inZone = false;
var restaurantCoords = {
latitude: 11.11111, longitude: 22.22222
};
for (var i=0, bLen=zipBrooklyn.length; i<bLen; i++) {
if(data.zipCode==zipArray[i]) {
inZone = true;
}
}
if (inZone == true ) { // valid zip
function onSuccess(coords) {
var limit = 3041.66;
var meters = getDistance(coords, restaurantCoords);
if (meters < limit) {
$http.post('https://api.parse.com/1/classes/Address', data, {
headers: PARSE_HEADERS
})
.success(function(addressData) {
deferred.resolve(addressData);
})
.error(function(error, addressData) {
deferred.reject(error);
});
}
function onError() {
deferred.reject("Unable to Geocode the coordinates");
}
// GET COORDS
navigator.geocoder.geocodeString(onSuccess, onError, data.address1 + ',' + data.zipCode);
}
}
return deferred.promise;
}]);
I've stripped out all of the code that I believe was working.
So a valid answer for this question could take multiple forms:
I'd accept an answer giving a decent way to debug apps IN Ionic View.
Or, if someone could provide an answer as to why it might be working in the browser and in iOS Simulator, but not iOS itself, that would be appreciated even more.
Ionic view doesn't support all the plugins yet. please take a look at this link for the list of supported plugins.
Device is always better (First Option). If you have a ios device and apple developer account. You can create and configure the required certificate with the device id and run the app using 'ionic run ios'. Second option is iOS simulator. You can use the simulator for your whole app, though few tasks would need a device.
Even if you use the simulator for the whole development, it is always advisable to test in the device before launcing the app.