Letting website users know that there is an iOS app available - iphone

In iOS6 there is an easy way to present users with the option to download your app when they visit your website and are on an iOS device.
(I know how to detect the user agent, write js, ect. Just looking to see if there is a quick nice library someone wrote for this.)
But, since that is not yet available, are there any good solutions out there to let our users know we have an app, and let them download it? But also, never show the message again if they HAVE downloaded it, or closed that dialog?
EDIT:
Here is what I have used in the past, but removed it because I felt it was annoying to the user. Just looking for lightweight examples.
/**
* Checks if this device is an iphone
*
* #version $Revision: 0.1
*/
puc.isIphone = function(){
return (
(navigator.platform.indexOf("iPhone") != -1) ||
(navigator.platform.indexOf("iPod") != -1)
);
}//end
/**
* Checks if this device is an ipad
*
* #version $Revision: 0.1
*/
puc.isIpad = function(){
return (navigator.platform.indexOf("iPad") != -1);
}//end
/**
* Function that checks if we are using a mobile browser and presents an option to view a differnt site
*
* #access public
*/
puc.mobile = function() {
if (puc.isIphone() || puc.isIpad()) {
// Add link to remove cookie
$('#copyright').append('<p><a id="remove-iphone-cookie">Reset Mobile Preferences</a></p>');
// Allow Deleting of the cookie
$('#remove-iphone-cookie').click(function() {
$.cookie('use_mobile', null);
alert('Preferences have been reset.');
return false;
});
if ($.cookie('use_mobile') == null) {
var conf = confirm('Would you like to download the PUC Mobile iOS app?');
if (conf) {
document.location = 'http://itunes.apple.com/us/app/puc/id424617272?mt=8&ls=1';
$.cookie('use_mobile', 'true');
} else {
// Never ask them again, unless they empty their cookies
$.cookie('use_mobile', 'false');
}
}//end
}//end if mobile
}//end mobile

The first part of your question is easy, you can detect the user-agent on the browser (serch for iPhone, iPod, iPad, etc... More here: http://p2p.wrox.com/content/articles/identifying-iphone-safari-user-agent)
The second part of your question is where you will come up short. You will not be able to determine that the user has the app installed because Apple will not share any user info outside its ecosystem (especially over the web). So you will need to show all users the info at least the first time. You could then set a cookie to track they have seen the info, but there is no guarantee how long that cookie hangs around.
Good Luck!

You could always just send a confirm alert with JavaScript once you have detected an iOS device such as the second example here (http://www.w3schools.com/js/js_popup.asp) but instead of 'you pressed ok' redirecting to AppStore URL and that will open in the AppStore automatically

Well, you can find out if an app is installed.
If the app listens to a custom url scheme you just try to open a url with it and if the browser is still on the page ofter a set timeout it is not installed. This is you implement links that either open the app or the app store.
And that's tricky since you can't cancel if the app is indeed installed, the link will always open your app.

Related

PWA. How to make an offer to the user to install the application?

I can of course force install my pwa on the device. However, existing sites on the market themselves offer the user to install the application. And about the possibility to install my application, the user will not know if he does not want to try (most likely he will not want to).
How to make the user such an offer, I unfortunately have not yet figured out. Articles could not be found (perhaps incorrectly set the search), the analysis of the code of service workers also did not help.
Help please.
On Chrome mobile, the default prompt is very visible. On desktop, less so.
But, Chrome actually has an event for this. If everything is in order for a PWA to be installed, the 'beforeinstallprompt' event is fired. You can simply add a listener to this event, and use that to display a message on your page to inform the user of the possibility to install the PWA.
The following example is written for Angular, but you can get the idea of the event.
ngOnInit() {
/**
* The beforeinstallprompt event is only triggered in certain browsers. This event simply indicates that everything is in order
* for the user to install the PWA. On mobile Chrome, a message is shown by default to the user, but we can also interfere and
* block it. This way, we can show our own message, and continue the event on our own terms.
* In this case, we store the event, and prevent it from continuing. We then show a regular <div> in the HTML, which contains the
* question to install the PWA, and a button to do so. That button then triggers the prompt, which the user can then accept or deny.
* The result of this prompt is mostly irrelevant to the functionality. Our code has no impact on the proceedings of the installation
* after the user has accepted the prompt.
* A possible usecase for the Promise resolved by the prompt, is for metrics. We can use the result to calculate how many users have
* accepted or denied our prompts.
*/
window.addEventListener('beforeinstallprompt', (e) => {
// Prevent Chrome 67 and earlier from automatically showing the prompt
e.preventDefault();
// Stash the event so it can be triggered later.
this.deferredPrompt = e;
console.log('beforeinstallprompt!');
// if askedOnce is true, no need to ask again.
this.showPwaPrompt = !this.askedOnce;
});
}
acceptPwaPrompt() {
this.showPwaPrompt = false;
this.askedOnce = true;
this.deferredPrompt.prompt(); // Wait for the user to respond to the prompt
this.deferredPrompt.userChoice.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
console.log('User accepted the A2HS prompt');
} else {
console.log('User dismissed the A2HS prompt');
}
this.deferredPrompt = null;
});
}

Like option using cordova

I need a web and mobile application which will work on android, iphone and windows as well.
I want to use facebook login for my apps and customer can like my page after login thats why i am using cordova to convert my web app into android app but i need to integrate facebook-like option which i didn't get in plugin.
So i implemented this using oglike
$scope.facebookLike = function() {
if($localStorage.hasOwnProperty("accessToken") === true) {
$http.post("https://graph.facebook.com/me/og.likes?access_token="+$localStorage.accessToken+"&object=https://www.facebook.com/Nxtlife-Technologies-Ltd-UK-180614345644169/?ref=br_rs");
alert("like sucessfully done");
} else {
alert("Not signed in");
$scope.facebookLogin();
}
}
Problem:
The code will not throwing any error but after success message it didin't make any changes to my page. like count is remains same.
og.likes is for Open Graph objects – external URLs, outside of Faceook.
You can not like Facebook pages by any other means than the official Like button.

Facebook UNITY SDK login issue

I just installed the new version of Unity 4.3 and the new facebook sdk and I can't get it working.
I created the app on facebook, copied over the app id to the unity facebook settings as required and copied the Package Name and Class name back to facebook.
Because the Android Key Hash is empty ( even it shouldn't be ) I used the methods posted by others to create one with openssl. I created it and copied over to facebook as required.
After this I created a small script to be able to login.
// Use this for initialization
void Start () {
enabled = false;
FB.Init(SetInit, OnHideUnity);
}
// Update is called once per frame
void Update () {
}
private void SetInit()
{
FbDebug.Log("SetInit");
enabled = true; // "enabled" is a property inherited from MonoBehaviour
if (FB.IsLoggedIn)
{
FbDebug.Log("Already logged in");
OnLoggedIn();
}
}
private void OnHideUnity(bool isGameShown)
{
FbDebug.Log("OnHideUnity");
if (!isGameShown)
{
// pause the game - we will need to hide
Time.timeScale = 0;
}
else
{
// start the game back up - we're getting focus again
Time.timeScale = 1;
}
}
void OnGUI(){
if (!FB.IsLoggedIn)
{
if (GUI.Button(new Rect(179 , 11, 287, 160), "Login to Facebook"))
{
FB.Login("email", LoginCallback);
}
}
}
void LoginCallback(FBResult result)
{
FbDebug.Log("LoginCallback");
Debug.Log("LoginCallback");
if (FB.IsLoggedIn)
{
OnLoggedIn();
}
}
void OnLoggedIn()
{
FbDebug.Log("Logged in. ID: " + FB.UserId);
}
Now when I click on the login button a Facebook window appears requesting permission, after I press ok, it returns, but I'm still not logged in... Can anybody help why is this?
Another strange thing I observed that the LoginCallback gets called as soon as I click on the login button, even though I would think it should only when I gave permission. Anyway when I give permission it returns to my app and nothing happens. I can click on the login button again and same thing happens, login callback called, it asks for permisions, I give the permision and returns back, nothing happened. Can anybody help?
Version 4.3.6 of the sdk should fix this problem. It's available here: https://developers.facebook.com/ We are still waiting for it to be approved on the asset store, so the only place to get it right now is from Facebook's site.
Note - it's still broken (5/2014) IF you use a Mac. Just follow the "Rafael solution", discover your hash properly from public void OnLoginComplete(string message). Cheers
So after being frustrated for a few days with having to trace out the key to my phone, I decided to look into what it was doing.
After some research it turned out that when you published to an android device, facebook would use the keystore that was defined in your publish settings, not your .android/debug.keystore file. So I went in and changed the sdk to make it work the proper way. Essentially I changed the SDK to look at the ProjectSettings instead of the debug directory for grabbing the key hash. In the FacebookAndroidUtils.cs I added the following.
// Using the user defined keystore values instead of the debug one.
degbugKeyHash = GetKeyHash( PlayerSettings.Android.keyaliasName, PlayerSettings.Android.keystoreName, PlayerSettings.Android.keyaliasPass, PlayerSettings.Android.keystorePass );
I created a small repo that provides the fix as well as some gui changes to make it more easy to update the key hash.
Github Facebook Unity SDK 6.1 Fix
Update - Fixed a bug with OS X related to escaping spaces on the string path
Hope this helps!
Take the "email" permission out of the login function and try it. Oops I thought I seen the "publish_actions" permission in there too.
Make sure the loginactivity in the manifest is in portrait.
Instead of implementing everything yourself, try using the free and open source SOOMLA Profile plugin for all of your social network needs:
https://github.com/soomla/unity3d-profile
Also available on the asset store for download:
https://www.assetstore.unity3d.com/en/#!/content/24601
It covers Facebook, Twitter and Google+ and has a unified API for logging in, posting statues, uploading images and getting friends lists. For proper disclosure, I'm one of the founders.

Blackberry FB share prob: low memory

I am using Blackberry Facebook SDK (FacebookBlackBerrySDK-v0.8.25.jar) for facebook integration for my app. I am using the following code.
ApplicationSettings as = new ApplicationSettings(NEXT_URL, APPLICATION_ID, APPLICATION_SECRET, PERMISSIONS);
Facebook fb = Facebook.getInstance(as);
try{
FBUserDetails fbUserDetails = FBUserDetails.getInstance();
String prevUserDatails = fbUserDetails.getFBData();
User user = fb.getCurrentUser();
if(prevUserDatails != null && !prevUserDatails.equals("") && user.getEmail().equals(prevUserDatails)){
if(Dialog.ask(Dialog.D_YES_NO,"Do you want to post using FB account " + prevUserDatails + "?",Dialog.YES)==Dialog.NO){
fb.logout(true);
user = fb.getCurrentUser();
}
}
if(user!= null){
fbUserDetails.persist(user.getEmail());
String result = user.publishStatus(decodedText);
if ((result != null) && !result.trim().equals("")) {
Dialog.alert("Successfully posted to Facebook.");
} else {
Dialog.alert("Share Failed.");
}
}else
Dialog.alert("user is equal to null.");
}catch(FacebookException fe){
fe.printStackTrace();
}
When I am testing the app in Blackberry Strom 9300 (OS version 6.0.0.526), it is running properly first time. But when I am going to share the same text again in a short interval(it is obvious that the posting will fail), system is giving "the memmory available on your device is low. Close some of the items below." and I forced to close the application. Can anyone tell me what is the problem in the above code?
I am having the same issue with my Webworks Blackberry build. The first time I begin using the app it is running fine but when I begin to process other pages on the app I receive a pop-up telling me that "the device memory is too low - please close the following items". Then the app icon changes to what looks like a folder.
I did some research and it appears this is a persistent problem on the Blackberry OS 6. Deleting the app and reinstalling it does not help neither does restarting the app.
Take a look at this link to view deeper issues related to low device memory
http://supportforums.blackberry.com/t5/Web-and-WebWorks-Development/Device-memory-is-Low-issue-for-an-WebWork-app/td-p/1166441/page/16

iPhone browser: Checking if iPhone app is installed from browser

I have web page where I have Button that either opens app (if it installed) or directs to App store if app isn't installed.
It all works if App is installed (I call into "MYAPP://"). However, if app is not installed Safari shows error message "Can not open URL" and that's it. Is there way to disable that message from JScript or is there another way to find out from JScript if app installed (instead of hitting app URL)?
To MODERATOR: I saw someone asked similar question and Moderator wrongly marked it as duplicate. Please understand that question was specifically about doing it from Browser.
Found somewhat suitable solution here
BTW if someone interested in how to do same thing for Android, here is code. We are using Dojo library:
dojo.io.iframe.send({
url: "yourApp://foo/bar",
load: function(resp) {
// nothing to do since it will automagically open App
},
error: function () {
window.location = "go to Android market";
}
});
At Branch we use a form of the code below--note that the iframe works on more browsers. Simply substitute in your app's URI and your App Store link. By the way, using the iframe silences the error if they don't have the app installed. It's great!
<!DOCTYPE html>
<html>
<body>
<script type="text/javascript">
window.onload = function() {
// Deep link to your app goes here
document.getElementById("l").src = "my_app://";
setTimeout(function() {
// Link to the App Store should go here -- only fires if deep link fails
window.location = "https://itunes.apple.com/us/app/my.app/id123456789?ls=1&mt=8";
}, 500);
};
</script>
<iframe id="l" width="1" height="1" style="visibility:hidden"></iframe>
</body>
</html>
If others have better solutions to detect whether the URI scheme call actually failed, please post! I haven't seen one, and I've spent a ton of time looking. All existing solutions just rely on the user still being on the page and the setTimeout firing.
here is a code that works on iOs, even if the "Can not open URL" still show.
window.location = "yourApp://foo/bar";
clickedAt = +new Date;
setTimeout(function() {
if (+new Date - clickedAt < 2000) {
window.location = "go to Android market";
}
}, 500);
Thanks for the android solution.
I've combined a few things and used the following code to check if it's an iOS device before using the try/catch method from chazbot. Unfortunately, the device still throws a pop-up box to the user saying the address is invalid...anyone know if this is expected behavior for trying to open an invalid URL within a "try" block?
var i = 0,
iOS = false,
iDevice = ['iPad', 'iPhone', 'iPod'];
for ( ; i < iDevice.length ; i++ ) {
if( navigator.platform === iDevice[i] ){ iOS = true; break; }
}
try {
//run code that normally breaks the script or throws error
if (iOS) { window.location = "myApp://open";}
}
catch(e) {
//do nothing
}
There are a few things you can do to improve on other answers. Since iOS 9, a link can be opened in a UIWebView or in a SFSafariViewController. You might want to handle them differently.
The SFSafariViewController shares cookies across apps, and with the built in Safari. So in your app you can make a request through a SFSafariViewController that will set a cookie that says "my app was installed". For instance you open your website asking your server to set such cookie. Then anytime you get a request from a SFSafariViewController you can check for that cookie and redirect to MYAPP:// if you find it, or to the app store if you don't. No need to open a webpage and do a javascript redirection, you can do a 301 from your server. Apps like Messages or Safari share those cookies.
The UIWebView is very tricky since it is totally sandboxed and shared no cookies with anything else. So you'll have to fallback to what has been described in other answers:
window.onload = function() {
var iframe = document.createElement("iframe");
var uri = 'MYAPP://';
var interval = setInterval(function() {
// Link to the App Store should go here -- only fires if deep link fails
window.location = "https://itunes.apple.com/us/app/my.app/id123456789?ls=1&mt=8";
}, 500);
iframe.onload = function() {
clearInterval(interval);
iframe.parentNode.removeChild(iframe);
window.location.href = uri;
};
iframe.src = uri;
iframe.setAttribute("style", "display:none;");
document.body.appendChild(iframe);
};
I've found it annoying that this will prompt the user if they want to leave the current app (to go to your app) even when your app is not installed. (empirically that seems only true from a UIWebView, if you do that from the normal Safari for instance that wont happen) but that's all we got!
You can differentiate the UIWebView from the SFSafariViewController from your server since they have different user agent header: the SFSafariViewController contains Safari while the UIWebView doesn't. For instance:
Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E269
-> UIWebView
Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E269 Safari/602.1
-> SFSafariViewController
Other considerations:
in the first approach, you might want to handle uninstalls: if the user uninstalls your app, you still have a cookie that says that the app is there but it's not, so you might end up with the "Can not open URL" message. I've handled it by removing the cookie after a few tries that didn't end up opening the app (which I know because at every app open I'm resetting this failed tries cookie)
In the second case, it's unclear if you're better off using a setInterval or setTimeout. The issue with the timeout is that if it triggers while a prompt is on, it will be ignored. For instance if you open the link from Messenger, the os will ask you "Leave Messenger? You're about to open another app" when the iframe tries to load your app. If you don't respond either way within the 500ms of the timeout, the redirection in the timeout will be ignored.
Finally even though the UIWebView is sandboxed, you can give it a cookie to identify it, pass it in your deeplink, and save this id as corresponding to device with your app in your server when your app opens. Next time, if you see such a cookie in the request coming from the UIWebView, you can check if it matches a known device with the app and redirect directly with a 301 as before.
I think you can still use the app url as a test. Try wrapping it in a try...catch block,
try {
//run code that normally breaks the script or throws error
}
catch(e) {
//do nothing
}