I’m having several issues while trying to run an application on iOS.
Important informations:
- The whole project was firstly created on a windows 10 machine where Android was tested: every single feature was tested on two different physical devices (a Lenovo tablet and a Nexus 5X phone).
- The project was then migrated to a Macbook air running MacOSx Sierra. Latest version of ionic was installed asweel, along with every single cordova configuration needed (and Xcode updates).
- The project was copied from the windows 10 machine (excluding node modules) on an external drive.
- A brand new blank project was created on the mac machine. After the project was correctly created, all the files but node_modules were used to overwrite all the existing files.
- These command were ran (in this order precisely):
npm install
— Plugins Installation (manual)
— Relevant plugin: https://ionicframework.com/docs/native/native-storage/
ionic cordova plugin add cordova-plugin-nativestorage
npm install --save @ionic-native/native-storage
ionic cordova platform add ios
The application structure is a regular ionic 2 one with tabs.
In the NgModule, I’m properly importing the NativeStorage and injecting it into the providers:
providers: [{provide: ErrorHandler, useClass: IonicErrorHandler}, NativeStorage]
Moreover, I’m also defining this in the imports section:
imports: [
IonicModule.forRoot(MyApp),
IonicStorageModule.forRoot({
name: '__agentidb',
driverOrder: ['sqlite', 'websql', 'indexxeddb']
}),
BrowserModule,
FormsModule,
HttpModule
],
The module usage I’m doing is the following:
I have a generic angular 2 service called “Database”, where I’m using the NativeStorage module in the constructor. Relevant code:
import { Injectable } from '@angular/core';
import { NativeStorage } from '@ionic-native/native-storage';
export class DatabaseError {
public reason: string = "";
constructor(reason) {
this.reason = reason;
}
}
export enum ERROR_CODES {
NATIVE_WRITE_FAILED = 1,
ITEM_NOT_FOUND = 2,
NULL_REFERENCE = 3,
UNDEFINED_TYPE = 4,
JSON_ERROR = 5,
WRONG_PARAMETER = 6
}
@Injectable()
export class DatabaseService {
constructor(private nativeStorage: NativeStorage) {
}
Relevant injection structure:
app.component.ts -> app.component.html (app)
|----- mainscreen.component.ts -> mainscreen.component.html(<mainscreen>)
| ---- login.component.ts (actively uses the user service which is using the database service)
the app.component.ts relevant part is:
@Component({
templateUrl: 'app.html',
viewProviders: [API, UserService, DatabaseService, ArticlesService, ClientsService, SplashScreen, StatusBar]
})
export class MyApp {
The login component (which is meant to inherit the UserService and DatabaseServer), uses the UserService to check whether there already is some data in any database.
Surprisingly, no service constructor seems to be called whatsoever, I don’t have any console.log being called, and whenever any call from the login component gets to the database server it just silently fails without even throwing any single issue.
I’ve checked the console, and the first fail happens when I try to set a value on an object which is meant to be compiled in the UserService constructor:
constructor(private database: DatabaseService) {
this.ServiceReady = new ReplaySubject<boolean>();
console.log("attempting to call table exists of <User>");
this.database.table_exists("User").then((exists) => {
if (exists) {
console.log("table exists already.");
// check if property exists in table.
this.database.key_exists("User","LoggedUser").then((res) => {
if (res) {
this.initUser();
}
else {
console.log("key does not exist.");
}
});
}
else {
// Table does not exists..
console.log("table does not exist yet. creating one.");
this.database.create_table("User",{
LoggedUser: {}
}).then( (res) => {
console.log("create table said: " + res);
this.initUser();
});
}
});
}
Basically, no console log is shown from this console.log, not even the very first one, and no exception/log is being thrown whatsoever.
Surprisingly, running this on windows creates no issues and the project works perfectly on any android physical device, while in iOS it looks like that “this.database.table_exists” is failing, despite it is not throwing any single error.
table_exists function for reference:
public table_exists(tablename: string): Promise<boolean> {
return new Promise( (resolve, reject) => {
this.nativeStorage.getItem(tablename).then((res) => {
if (res != null) {
resolve(true);
}
else {
resolve(false);
}
}).catch((err) => {
if (err.code === ERROR_CODES.ITEM_NOT_FOUND) {
resolve (false);
}
else {
throw "Error while reading data.";
}
});
});
}
Relevant package.json:
"dependencies": {
"@angular/common": "4.1.0",
"@angular/compiler": "4.1.0",
"@angular/compiler-cli": "4.1.0",
"@angular/core": "4.1.0",
"@angular/forms": "4.1.0",
"@angular/http": "4.1.0",
"@angular/platform-browser": "4.1.0",
"@angular/platform-browser-dynamic": "4.1.0",
"@ionic-native/core": "3.6.1",
"@ionic-native/native-storage": "3.8.1",
"@ionic-native/network": "3.8.1",
"@ionic-native/splash-screen": "3.6.1",
"@ionic-native/status-bar": "3.6.1",
"cordova-android": "^6.2.3",
"cordova-ios": "^4.4.0",
"cordova-plugin-console": "^1.0.5",
"cordova-plugin-device": "^1.1.4",
"cordova-plugin-nativestorage": "^2.2.2",
"cordova-plugin-splashscreen": "^4.0.3",
"cordova-plugin-statusbar": "^2.2.2",
"cordova-plugin-whitelist": "^1.3.1",
"cordova-sqlite-storage": "^2.0.4",
"ionic-angular": "3.2.1",
"ionic-plugin-keyboard": "^2.2.1",
"ionicons": "3.0.0",
"rxjs": "5.1.1",
"sw-toolbox": "3.6.0",
"zone.js": "0.8.10"
},
"devDependencies": {
"@ionic/app-scripts": "1.3.7",
"typescript": "2.2.1",
"@ionic/cli-plugin-ionic-angular": "1.0.0",
"@ionic/cli-plugin-cordova": "1.0.0"
},
"description": "An Ionic project",
"cordova": {
"plugins": {
"cordova-sqlite-storage": {},
"cordova-plugin-console": {},
"cordova-plugin-device": {},
"cordova-plugin-splashscreen": {},
"cordova-plugin-statusbar": {},
"cordova-plugin-whitelist": {},
"ionic-plugin-keyboard": {},
"cordova-plugin-nativestorage": {}
},
"platforms": [
"android",
"ios"
]
}
Any idea?