/// <summary> /// Creates a new instance of the <see cref="MainViewModel"/> class. /// For unit tests. /// </summary> protected internal MainViewModel( ILogService logService, INeuronService neuronService, IUiDispatcher uiDispatcher, ITagProfile tagProfile, INavigationService navigationService, INetworkService networkService, IImageCacheService imageCacheService, IContractOrchestratorService contractOrchestratorService, IThingRegistryOrchestratorService thingThingRegistryOrchestratorService) : base(neuronService ?? DependencyService.Resolve <INeuronService>(), uiDispatcher ?? DependencyService.Resolve <IUiDispatcher>()) { this.logService = logService ?? DependencyService.Resolve <ILogService>(); this.tagProfile = tagProfile ?? DependencyService.Resolve <ITagProfile>(); this.navigationService = navigationService ?? DependencyService.Resolve <INavigationService>(); this.networkService = networkService ?? DependencyService.Resolve <INetworkService>(); imageCacheService = imageCacheService ?? DependencyService.Resolve <IImageCacheService>(); this.contractOrchestratorService = contractOrchestratorService ?? DependencyService.Resolve <IContractOrchestratorService>(); this.thingRegistryOrchestratorService = thingThingRegistryOrchestratorService ?? DependencyService.Resolve <IThingRegistryOrchestratorService>(); this.photosLoader = new PhotosLoader(this.logService, this.networkService, this.NeuronService, this.UiDispatcher, imageCacheService); this.UpdateLoggedOutText(true); this.ViewMyContractsCommand = new Command(async() => await ViewMyContracts(), () => this.IsConnected); this.ScanQrCodeCommand = new Command(async() => await ScanQrCode(), () => this.IsConnected); this.ViewWalletCommand = new Command(async() => await ViewWallet(), () => this.IsConnected); }
/// <summary> /// Create a new instance of the <see cref="AppShell"/> class. /// </summary> public AppShell() { this.ViewModel = new AppShellViewModel(); this.neuronService = DependencyService.Resolve <INeuronService>(); this.networkService = DependencyService.Resolve <INetworkService>(); this.navigationService = DependencyService.Resolve <INavigationService>(); this.logService = DependencyService.Resolve <ILogService>(); this.uiDispatcher = DependencyService.Resolve <IUiDispatcher>(); this.contractOrchestratorService = DependencyService.Resolve <IContractOrchestratorService>(); this.thingRegistryOrchestratorService = DependencyService.Resolve <IThingRegistryOrchestratorService>(); InitializeComponent(); SetTabBarIsVisible(this, false); RegisterRoutes(); }
///<inheritdoc/> public App() { this.startupProfiler = new Profiler("Startup", ProfilerThreadType.Sequential); // Comment out to remove startup profiling. this.startupProfiler?.Start(); this.startupProfiler?.NewState("Init"); AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException; AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; InitializeComponent(); try { this.startupProfiler?.NewState("Types"); Assembly appAssembly = this.GetType().Assembly; if (!Types.IsInitialized) { // Define the scope and reach of Runtime.Inventory (Script, Serialization, Persistence, IoC, etc.): Types.Initialize( appAssembly, // Allows for objects defined in this assembly, to be instantiated and persisted. typeof(Database).Assembly, // Indexes default attributes typeof(ObjectSerializer).Assembly, // Indexes general serializers typeof(FilesProvider).Assembly, // Indexes special serializers typeof(RuntimeSettings).Assembly, // Allows for persistence of settings in the object database typeof(InternetContent).Assembly, // Common Content-Types typeof(XML).Assembly, // XML Content-Type typeof(MarkdownDocument).Assembly, // Markdown support typeof(XmppClient).Assembly, // Serialization of general XMPP objects typeof(ContractsClient).Assembly, // Serialization of XMPP objects related to digital identities and smart contracts typeof(ProvisioningClient).Assembly, // Serialization of XMPP objects related to thing registries, provisioning and decision support. typeof(SensorClient).Assembly, // Serialization of XMPP objects related to sensors typeof(ControlClient).Assembly, // Serialization of XMPP objects related to actuators typeof(ConcentratorClient).Assembly, // Serialization of XMPP objects related to concentrators typeof(Expression).Assembly, // Indexes basic script functions typeof(XmppServerlessMessaging).Assembly, // Indexes End-to-End encryption mechanisms typeof(TagConfiguration).Assembly, // Indexes persistable objects typeof(RegistrationStep).Assembly); // Indexes persistable objects } this.startupProfiler?.NewState("SDK"); // Create Services this.sdk = TagIdSdk.Create(appAssembly, this.startupProfiler, new XmppConfiguration().ToArray()); this.imageCacheService = new ImageCacheService(this.sdk.SettingsService, this.sdk.LogService); this.sdk.RegisterSingleton <IImageCacheService, ImageCacheService>(this.imageCacheService); this.contractOrchestratorService = new ContractOrchestratorService(this.sdk.TagProfile, this.sdk.UiDispatcher, this.sdk.NeuronService, this.sdk.NavigationService, this.sdk.LogService, this.sdk.NetworkService, this.sdk.SettingsService); this.sdk.RegisterSingleton <IContractOrchestratorService, ContractOrchestratorService>(this.contractOrchestratorService); this.thingRegistryOrchestratorService = new ThingRegistryOrchestratorService(this.sdk.TagProfile, this.sdk.UiDispatcher, this.sdk.NeuronService, this.sdk.NavigationService, this.sdk.LogService, this.sdk.NetworkService); this.sdk.RegisterSingleton <IThingRegistryOrchestratorService, ThingRegistryOrchestratorService>(this.thingRegistryOrchestratorService); // Set resolver DependencyResolver.ResolveUsing(type => { object obj = this.sdk.Resolve(type); if (!(obj is null)) { return(obj); } if (Types.GetType(type.FullName) is null) { return(null); // Type not managed by Runtime.Inventory. Xamarin.Forms resolves this using its default mechanism. } return(Types.Instantiate(true, type)); }); // Get the db started right away to save startup time. this.sdk.StorageService.Init(this.startupProfiler?.CreateThread("Database", ProfilerThreadType.Sequential)); // Register log listener (optional) this.sdk.LogService.AddListener(new AppCenterEventSink(this.sdk.LogService)); } catch (Exception e) { e = Waher.Events.Log.UnnestException(e); this.startupProfiler?.Exception(e); DisplayBootstrapErrorPage(e.Message, e.StackTrace); return; } // Start page try { this.startupProfiler?.NewState("MainPage"); this.MainPage = new AppShell(); } catch (Exception e) { e = Waher.Events.Log.UnnestException(e); this.startupProfiler?.Exception(e); this.sdk.LogService.SaveExceptionDump("StartPage", e.ToString()); } this.startupProfiler?.MainThread.Idle(); }
/// <summary> /// Scans a QR Code, and depending on the actual result, takes different actions. This typically means navigating to an appropriate page. /// </summary> /// <param name="logService">The log service to use for logging.</param> /// <param name="neuronService">The Neuron service for XMPP access</param> /// <param name="navigationService">The navigation service for page navigation.</param> /// <param name="uiDispatcher">The ui dispatcher for main thread access.</param> /// <param name="contractOrchestratorService">The contract orchestrator service.</param> /// <param name="thingRegistryOrchestratorService">The thing registry orchestrator service.</param> /// <param name="commandName">The command name to display on the button when scanning.</param> /// <param name="action">An optional callback that will be called after scan, but before page navigation.</param> /// <returns></returns> public static async Task ScanQrCodeAndHandleResult( ILogService logService, INeuronService neuronService, INavigationService navigationService, IUiDispatcher uiDispatcher, IContractOrchestratorService contractOrchestratorService, IThingRegistryOrchestratorService thingRegistryOrchestratorService, string commandName, Func <string, Task> action = null) { string decodedText = await IdApp.QrCode.ScanQrCode(navigationService, AppResources.Open); if (string.IsNullOrWhiteSpace(decodedText)) { return; } try { if (!Uri.TryCreate(decodedText, UriKind.Absolute, out Uri uri)) { await uiDispatcher.DisplayAlert(AppResources.ErrorTitle, AppResources.CodeNotRecognized); return; } switch (uri.Scheme.ToLower()) { case Constants.UriSchemes.UriSchemeIotId: string legalId = Constants.UriSchemes.GetCode(decodedText); await contractOrchestratorService.OpenLegalIdentity(legalId, AppResources.ScannedQrCode); break; case Constants.UriSchemes.UriSchemeIotSc: string contractId = Constants.UriSchemes.GetCode(decodedText); await contractOrchestratorService.OpenContract(contractId, AppResources.ScannedQrCode); break; case Constants.UriSchemes.UriSchemeIotDisco: if (neuronService.ThingRegistry.IsIoTDiscoClaimURI(decodedText)) { await thingRegistryOrchestratorService.OpenClaimDevice(decodedText); } else if (neuronService.ThingRegistry.IsIoTDiscoSearchURI(decodedText)) { await thingRegistryOrchestratorService.OpenSearchDevices(decodedText); } else { await uiDispatcher.DisplayAlert(AppResources.ErrorTitle, $"{AppResources.InvalidIoTDiscoveryCode}{Environment.NewLine}{Environment.NewLine}{decodedText}"); } break; case Constants.UriSchemes.UriSchemeTagSign: string request = Constants.UriSchemes.GetCode(decodedText); await contractOrchestratorService.TagSignature(request); break; default: if (!await Launcher.TryOpenAsync(uri)) { await uiDispatcher.DisplayAlert(AppResources.ErrorTitle, $"{AppResources.QrCodeNotUnderstood}{Environment.NewLine}{Environment.NewLine}{decodedText}"); } break; } } catch (Exception ex) { logService.LogException(ex); await uiDispatcher.DisplayAlert(ex); } }