[Solved] Platform specific pages


#1

Hi All,
I want to create a page with a videoplayer. For Android I want use the cordova video plugin for this. On iOS and the web version i want to use the html5 video tag.
So I need two different pages for Android and not Android. In Ionic v1 there were merges for this but those are no more supported as far I can see.
Any hints for an approach?
thx,
patrik


The best way to serve different pages for each platform?
#2

You are looking for https://ionicframework.com/docs/api/platform/Platform/


#3

Hi Sujan12,
thx for the tip. With this I’m able to check if its Android and can based on this pass my navigation the android or non Android page:

    if (this.platform.is('android')) {
      this.navCtrl.push('VideoAndroidPage');
    } else {
      this.navCtrl.push('VideoPage');
    }

But needs to be checked everywhere where I call the page. Is there a more elegant/automated approach for this?
thx,
patrik


#4

Maybe you should check inside a provider while opening the app for the platform.

Device provider

pages;

ionViewDidLoad(){
    if(this.platform.is('android')) {
        pages = {
            'VideoAndroidPage'
        }
    } else {
        pages = {
            'VideoPage'
        }
    }
}

Create of the pages a global variable so you can use it in home.ts.


#5

Hi wthijmen,
thx for the tip. So I created a provider:


@Injectable()
export class DeviceProvider {
  
  public pages:any = new Map([['VideoPage', 'VideoPage']]);

  constructor(public platform: Platform) {
    if(this.platform.is('android')) {
      this.pages.set('VideoPage' , 'VideoAndroidPage');
    } 
  }

  getPage(page: string):string {
    let result:string = this.pages.get(page);
    if (typeof result  == 'undefined') 
      result = page;
    return result;
  }

}

added it to my app providers and included it on the page where I need it:

  constructor(
              private deviceProvider: DeviceProvider,
              public navCtrl: NavController, 
              public navParams: NavParams) {
  }

  navVideo(){
    this.navCtrl.push(this.deviceProvider.getPage('VideoPage'));
  }

This works so far. Is there a way to make the deviceProvider usable globally without injecting it within the constructor?
thx,
patrik


#6

Hi Patrik,

I refer your to this post:

I hope I helped you further.


#7

What exactly does that mean?
When you enter that page?

Can you not just use the same page and do different things in there depending on that platform? Much cleaner.


#8

Hi Sujan12,
using the same page was my first approach. But for Android I need the cordova video plugin which won’t be available if you open the app using a browser and giving me the error that the plugin is not available (of course).
So I ended up with the idea of loading a different page for Android.
The only thing which I didn’t like was that from every part of my app where the video page could be opened this if-condition. With the deviceProvider as a singleton this should be ok.
But if you have a cleaner solution I would be thankful :slight_smile:
best,
patrik


#9

Hi wthijmen,
I already added my service to the app.module.ts in the providers section. So I assume it will be instantiated only once.
I just want to avoid to pass this service always to the constructor of the pages (and the import section).
Just a global call like:

DeviceProvider.getPage('VideoPage');

Is this possible?
thx,
patrik


#10

Hi @patrikd,

I don’t think so, so far as I know.
At this moment I’m doing it this way for all my providers.

Just to import them.
I got one other solution for you.
Not sure if it’s working.
Explained below:

Common provider
Create 1 common provider. Import all other providers inside this provider.
After that you only have to call the common provider inside your pages.

CommonProvider.ts

import { DeviceProvider} from "../../providers/device/device";

@Injectable()
export class CommonProvider{
    constructor(private device: Device){
    }

    deviceGetPage(param)
    {
        this.device.getPage(param);
    }
}

And then in your page as example home.ts you do the following:

import { CommonProvider } from '../../providers/common/common';

and in your constructor you add

private common: CommonProvider

and then you can make a call from the home.ts with:

this.common.deviceGetPage('VideoPage');

I hope it helped you further :slight_smile:


#11

Hi wthijmen,
will do so.
thx,
patrik


#12

Hi @patrikd,

If it’s the solution for your problem can you mark it as solution?
So other people will know the solution for in the future.

Thanks.
Have a nice day!


#13

I consider the CommonProvider idiom an antipattern. It obscures which pages are using what functionality, which impairs readability, maintainability, and testability.


#14

True, but do you got a another solution for this issue?
I’m just including everything on every page for my self because I dont need every provider on any page.


#15

The problem I have with CommonProvider isn’t related to the topic of the thread, really. My solution to the thread topic would be to have only one video player page with conditional template segments enabled via ngIf depending on the platform. That way nobody but that page has to care about any of this.


#16

I understand,
But sometimes it’s easyer to create new pages.

At this moment im developing 2 apps in 1.
I create for both sides of the app a specific page because in every ‘app’ it can show other things without doing ngIf check for platform on every element