Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Realtime Cross Plattform Apps with Angular, ASP.NET Core and SignalR

Realtime Cross Plattform Apps with Angular, ASP.NET Core and SignalR

Fb89953d3a1b1fcb862a186585c37c25?s=128

Fabian Gosebrink

February 16, 2021
Tweet

Transcript

  1. Realtim Cr Platfor App Angular, ASP.NET Cor & Signa R

    wit
  2. Fabian Gosebrink

  3. Realtim Cr Platfor App Angular, ASP.NET Cor & Signa R

    wit
  4. Server Clien

  5. Server Clien

  6. Server Clien HTTP WS

  7. None
  8. Realtim Signa R wit

  9. Pollin

  10. Pollin

  11. Signa R

  12. Signa R WebSocket

  13. Signa R Server Sen Event

  14. Signa R Lon Pollin

  15. Signa R WebSocket Server Sen Event Lon Pollin

  16. namespace server { public class Startup { public void ConfigureServices(IServiceCollection

    services) { // ... services.AddSignalR(); // ... } public void Configure(/* ... */) { // ... app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHub<TodoHub>("/todohub"); }); } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
  17. namespace server { public class Startup { public void ConfigureServices(IServiceCollection

    services) { // ... services.AddSignalR(); // ... } public void Configure(/* ... */) { // ... app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHub<TodoHub>("/todohub"); }); } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public void ConfigureServices(IServiceCollection services) { // ... services.AddSignalR(); // ... } namespace server 1 { 2 public class Startup 3 { 4 5 6 7 8 9 10 11 public void Configure(/* ... */) 12 { 13 // ... 14 app.UseRouting(); 15 16 app.UseEndpoints(endpoints => 17 { 18 endpoints.MapControllers(); 19 endpoints.MapHub<TodoHub>("/todohub"); 20 }); 21 } 22 } 23 } 24
  18. namespace server { public class Startup { public void ConfigureServices(IServiceCollection

    services) { // ... services.AddSignalR(); // ... } public void Configure(/* ... */) { // ... app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHub<TodoHub>("/todohub"); }); } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public void ConfigureServices(IServiceCollection services) { // ... services.AddSignalR(); // ... } namespace server 1 { 2 public class Startup 3 { 4 5 6 7 8 9 10 11 public void Configure(/* ... */) 12 { 13 // ... 14 app.UseRouting(); 15 16 app.UseEndpoints(endpoints => 17 { 18 endpoints.MapControllers(); 19 endpoints.MapHub<TodoHub>("/todohub"); 20 }); 21 } 22 } 23 } 24 services.AddSignalR(); namespace server 1 { 2 public class Startup 3 { 4 public void ConfigureServices(IServiceCollection services) 5 { 6 // ... 7 8 // ... 9 } 10 11 public void Configure(/* ... */) 12 { 13 // ... 14 app.UseRouting(); 15 16 app.UseEndpoints(endpoints => 17 { 18 endpoints.MapControllers(); 19 endpoints.MapHub<TodoHub>("/todohub"); 20 }); 21 } 22 } 23 } 24
  19. namespace server { public class Startup { public void ConfigureServices(IServiceCollection

    services) { // ... services.AddSignalR(); // ... } public void Configure(/* ... */) { // ... app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHub<TodoHub>("/todohub"); }); } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public void ConfigureServices(IServiceCollection services) { // ... services.AddSignalR(); // ... } namespace server 1 { 2 public class Startup 3 { 4 5 6 7 8 9 10 11 public void Configure(/* ... */) 12 { 13 // ... 14 app.UseRouting(); 15 16 app.UseEndpoints(endpoints => 17 { 18 endpoints.MapControllers(); 19 endpoints.MapHub<TodoHub>("/todohub"); 20 }); 21 } 22 } 23 } 24 services.AddSignalR(); namespace server 1 { 2 public class Startup 3 { 4 public void ConfigureServices(IServiceCollection services) 5 { 6 // ... 7 8 // ... 9 } 10 11 public void Configure(/* ... */) 12 { 13 // ... 14 app.UseRouting(); 15 16 app.UseEndpoints(endpoints => 17 { 18 endpoints.MapControllers(); 19 endpoints.MapHub<TodoHub>("/todohub"); 20 }); 21 } 22 } 23 } 24 public void Configure(/* ... */) { // ... app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHub<TodoHub>("/todohub"); }); } } } namespace server 1 { 2 public class Startup 3 { 4 public void ConfigureServices(IServiceCollection services) 5 { 6 // ... 7 services.AddSignalR(); 8 // ... 9 } 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
  20. namespace server { public class Startup { public void ConfigureServices(IServiceCollection

    services) { // ... services.AddSignalR(); // ... } public void Configure(/* ... */) { // ... app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHub<TodoHub>("/todohub"); }); } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public void ConfigureServices(IServiceCollection services) { // ... services.AddSignalR(); // ... } namespace server 1 { 2 public class Startup 3 { 4 5 6 7 8 9 10 11 public void Configure(/* ... */) 12 { 13 // ... 14 app.UseRouting(); 15 16 app.UseEndpoints(endpoints => 17 { 18 endpoints.MapControllers(); 19 endpoints.MapHub<TodoHub>("/todohub"); 20 }); 21 } 22 } 23 } 24 services.AddSignalR(); namespace server 1 { 2 public class Startup 3 { 4 public void ConfigureServices(IServiceCollection services) 5 { 6 // ... 7 8 // ... 9 } 10 11 public void Configure(/* ... */) 12 { 13 // ... 14 app.UseRouting(); 15 16 app.UseEndpoints(endpoints => 17 { 18 endpoints.MapControllers(); 19 endpoints.MapHub<TodoHub>("/todohub"); 20 }); 21 } 22 } 23 } 24 public void Configure(/* ... */) { // ... app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHub<TodoHub>("/todohub"); }); } } } namespace server 1 { 2 public class Startup 3 { 4 public void ConfigureServices(IServiceCollection services) 5 { 6 // ... 7 services.AddSignalR(); 8 // ... 9 } 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 app.UseRouting(); namespace server 1 { 2 public class Startup 3 { 4 public void ConfigureServices(IServiceCollection services) 5 { 6 // ... 7 services.AddSignalR(); 8 // ... 9 } 10 11 public void Configure(/* ... */) 12 { 13 // ... 14 15 16 app.UseEndpoints(endpoints => 17 { 18 endpoints.MapControllers(); 19 endpoints.MapHub<TodoHub>("/todohub"); 20 }); 21 } 22 } 23 } 24
  21. namespace server { public class Startup { public void ConfigureServices(IServiceCollection

    services) { // ... services.AddSignalR(); // ... } public void Configure(/* ... */) { // ... app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHub<TodoHub>("/todohub"); }); } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public void ConfigureServices(IServiceCollection services) { // ... services.AddSignalR(); // ... } namespace server 1 { 2 public class Startup 3 { 4 5 6 7 8 9 10 11 public void Configure(/* ... */) 12 { 13 // ... 14 app.UseRouting(); 15 16 app.UseEndpoints(endpoints => 17 { 18 endpoints.MapControllers(); 19 endpoints.MapHub<TodoHub>("/todohub"); 20 }); 21 } 22 } 23 } 24 services.AddSignalR(); namespace server 1 { 2 public class Startup 3 { 4 public void ConfigureServices(IServiceCollection services) 5 { 6 // ... 7 8 // ... 9 } 10 11 public void Configure(/* ... */) 12 { 13 // ... 14 app.UseRouting(); 15 16 app.UseEndpoints(endpoints => 17 { 18 endpoints.MapControllers(); 19 endpoints.MapHub<TodoHub>("/todohub"); 20 }); 21 } 22 } 23 } 24 public void Configure(/* ... */) { // ... app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHub<TodoHub>("/todohub"); }); } } } namespace server 1 { 2 public class Startup 3 { 4 public void ConfigureServices(IServiceCollection services) 5 { 6 // ... 7 services.AddSignalR(); 8 // ... 9 } 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 app.UseRouting(); namespace server 1 { 2 public class Startup 3 { 4 public void ConfigureServices(IServiceCollection services) 5 { 6 // ... 7 services.AddSignalR(); 8 // ... 9 } 10 11 public void Configure(/* ... */) 12 { 13 // ... 14 15 16 app.UseEndpoints(endpoints => 17 { 18 endpoints.MapControllers(); 19 endpoints.MapHub<TodoHub>("/todohub"); 20 }); 21 } 22 } 23 } 24 app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHub<TodoHub>("/todohub"); }); namespace server 1 { 2 public class Startup 3 { 4 public void ConfigureServices(IServiceCollection services) 5 { 6 // ... 7 services.AddSignalR(); 8 // ... 9 } 10 11 public void Configure(/* ... */) 12 { 13 // ... 14 app.UseRouting(); 15 16 17 18 19 20 21 } 22 } 23 } 24
  22. namespace server { public class Startup { public void ConfigureServices(IServiceCollection

    services) { // ... services.AddSignalR(); // ... } public void Configure(/* ... */) { // ... app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHub<TodoHub>("/todohub"); }); } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public void ConfigureServices(IServiceCollection services) { // ... services.AddSignalR(); // ... } namespace server 1 { 2 public class Startup 3 { 4 5 6 7 8 9 10 11 public void Configure(/* ... */) 12 { 13 // ... 14 app.UseRouting(); 15 16 app.UseEndpoints(endpoints => 17 { 18 endpoints.MapControllers(); 19 endpoints.MapHub<TodoHub>("/todohub"); 20 }); 21 } 22 } 23 } 24 services.AddSignalR(); namespace server 1 { 2 public class Startup 3 { 4 public void ConfigureServices(IServiceCollection services) 5 { 6 // ... 7 8 // ... 9 } 10 11 public void Configure(/* ... */) 12 { 13 // ... 14 app.UseRouting(); 15 16 app.UseEndpoints(endpoints => 17 { 18 endpoints.MapControllers(); 19 endpoints.MapHub<TodoHub>("/todohub"); 20 }); 21 } 22 } 23 } 24 public void Configure(/* ... */) { // ... app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHub<TodoHub>("/todohub"); }); } } } namespace server 1 { 2 public class Startup 3 { 4 public void ConfigureServices(IServiceCollection services) 5 { 6 // ... 7 services.AddSignalR(); 8 // ... 9 } 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 app.UseRouting(); namespace server 1 { 2 public class Startup 3 { 4 public void ConfigureServices(IServiceCollection services) 5 { 6 // ... 7 services.AddSignalR(); 8 // ... 9 } 10 11 public void Configure(/* ... */) 12 { 13 // ... 14 15 16 app.UseEndpoints(endpoints => 17 { 18 endpoints.MapControllers(); 19 endpoints.MapHub<TodoHub>("/todohub"); 20 }); 21 } 22 } 23 } 24 app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHub<TodoHub>("/todohub"); }); namespace server 1 { 2 public class Startup 3 { 4 public void ConfigureServices(IServiceCollection services) 5 { 6 // ... 7 services.AddSignalR(); 8 // ... 9 } 10 11 public void Configure(/* ... */) 12 { 13 // ... 14 app.UseRouting(); 15 16 17 18 19 20 21 } 22 } 23 } 24 endpoints.MapHub<TodoHub>("/todohub"); namespace server 1 { 2 public class Startup 3 { 4 public void ConfigureServices(IServiceCollection services) 5 { 6 // ... 7 services.AddSignalR(); 8 // ... 9 } 10 11 public void Configure(/* ... */) 12 { 13 // ... 14 app.UseRouting(); 15 16 app.UseEndpoints(endpoints => 17 { 18 endpoints.MapControllers(); 19 20 }); 21 } 22 } 23 } 24
  23. Hub

  24. Hub namespace server.Hubs { public class TodoHub : Hub {

    public async Task MySuperDuperAction(object data) { await Clients.All.SendAsync("myclientmethod", data); } } } 1 2 3 4 5 6 7 8 9 10
  25. public class TodosController : ControllerBase { private readonly IHubContext<TodoHub> _todoHubContext;

    public TodosController( IHubContext<TodoHub> todoHubContext ) { _todoHubContext = todoHubContext; } [HttpPost(Name = nameof(AddTodo))] public async Task<ActionResult> AddTodo( [FromBody] TodoCreateDto todoCreateDto) { // ... do http things await _todoHubContext.Clients.All.SendAsync("todo-added", newTodoEntity); return CreatedAtRoute(/* ... */); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
  26. None
  27. None
  28. None
  29. @microsoft/signalr

  30. None
  31. None
  32. None
  33. None
  34. None
  35. Dem

  36. Cr Platfor

  37. Ma

  38. Ma Window

  39. Ma Window Lin

  40. Mobil

  41. Mobil Desktop

  42. Mobil Desktop Web

  43. s muc mor ...

  44. Cordov

  45. Apache Cordova is an open- source mobile development framework. It

    allows you to use standard web technologies - HTML5, CSS3, and JavaScript for cross-platform development. " "
  46. None
  47. $ npm install cordova -g

  48. $ cordova create myFirstApp

  49. ├── www │ ├── css │ │ └── index.css │

    ├── img │ │ └── logo.png │ ├── js │ │ └── index.js │ └── index.html ├── .gitignore ├── config.xml └── package.json 1 2 3 4 5 6 7 8 9 10 11
  50. ├── www │ ├── css │ │ └── index.css │

    ├── img │ │ └── logo.png │ ├── js │ │ └── index.js │ └── index.html ├── .gitignore ├── config.xml └── package.json 1 2 3 4 5 6 7 8 9 10 11 ├── www 1 │ ├── css 2 │ │ └── index.css 3 │ ├── img 4 │ │ └── logo.png 5 │ ├── js 6 │ │ └── index.js 7 │ └── index.html 8 ├── .gitignore 9 ├── config.xml 10 └── package.json 11
  51. ├── www │ ├── css │ │ └── index.css │

    ├── img │ │ └── logo.png │ ├── js │ │ └── index.js │ └── index.html ├── .gitignore ├── config.xml └── package.json 1 2 3 4 5 6 7 8 9 10 11 ├── www 1 │ ├── css 2 │ │ └── index.css 3 │ ├── img 4 │ │ └── logo.png 5 │ ├── js 6 │ │ └── index.js 7 │ └── index.html 8 ├── .gitignore 9 ├── config.xml 10 └── package.json 11 │ ├── css │ │ └── index.css │ ├── img │ │ └── logo.png │ ├── js │ │ └── index.js │ └── index.html ├── www 1 2 3 4 5 6 7 8 ├── .gitignore 9 ├── config.xml 10 └── package.json 11
  52. ├── www │ ├── css │ │ └── index.css │

    ├── img │ │ └── logo.png │ ├── js │ │ └── index.js │ └── index.html ├── .gitignore ├── config.xml └── package.json 1 2 3 4 5 6 7 8 9 10 11 ├── www 1 │ ├── css 2 │ │ └── index.css 3 │ ├── img 4 │ │ └── logo.png 5 │ ├── js 6 │ │ └── index.js 7 │ └── index.html 8 ├── .gitignore 9 ├── config.xml 10 └── package.json 11 │ ├── css │ │ └── index.css │ ├── img │ │ └── logo.png │ ├── js │ │ └── index.js │ └── index.html ├── www 1 2 3 4 5 6 7 8 ├── .gitignore 9 ├── config.xml 10 └── package.json 11 ├── config.xml ├── www 1 │ ├── css 2 │ │ └── index.css 3 │ ├── img 4 │ │ └── logo.png 5 │ ├── js 6 │ │ └── index.js 7 │ └── index.html 8 ├── .gitignore 9 10 └── package.json 11
  53. <?xml version='1.0' encoding='utf-8'?> <widget id="com.offering.solutions" ...> <name>Gatherr</name> <description>Gatherr - Demo

    Application</description> <author email="mail@offering.solutions" href="https://offering.solutions"> Offering Solutions Software </author> <content src="index.html" /> <access origin="*" /> <allow-intent href="gettogetherapp:*" /> <allow-intent href="http://*/*" /> <allow-intent href="https://*/*" /> <allow-intent href="tel:*" /> <allow-intent href="mailto:*" /> <allow-intent href="geo:*" /> <platform name="android"> <allow-intent href="market:*" /> </platform> <engine name="android" spec="~9.0.0" /> <plugin name="cordova-plugin-camera" spec="~4.0.2" /> <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> <variable name="URL_SCHEME" value="gatherrapp" /> <variable name="ANDROID_SCHEME" value=" " /> <variable name="ANDROID_HOST" value=" " /> <variable name="ANDROID_PATHPREFIX" value="/" /> </plugin> <preference name="Scheme" value="https" /> <preference name="android-minSdkVersion" value="22" /> </widget> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
  54. <name>Gatherr</name> <description>Gatherr - Demo Application</description> <author email="mail@offering.solutions" href="https://offering.solution Offering Solutions

    Software </author> <content src="index.html" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 3 4 5 6 7 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29
  55. <name>Gatherr</name> <description>Gatherr - Demo Application</description> <author email="mail@offering.solutions" href="https://offering.solution Offering Solutions

    Software </author> <content src="index.html" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 3 4 5 6 7 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <access origin="*" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29
  56. <name>Gatherr</name> <description>Gatherr - Demo Application</description> <author email="mail@offering.solutions" href="https://offering.solution Offering Solutions

    Software </author> <content src="index.html" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 3 4 5 6 7 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <access origin="*" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <allow-intent href="gettogetherapp:*" /> <allow-intent href="http://*/*" /> <allow-intent href="https://*/*" /> <allow-intent href="tel:*" /> <allow-intent href="mailto:*" /> <allow-intent href="geo:*" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 <access origin="*" /> 10 11 12 13 14 15 16 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29
  57. <name>Gatherr</name> <description>Gatherr - Demo Application</description> <author email="mail@offering.solutions" href="https://offering.solution Offering Solutions

    Software </author> <content src="index.html" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 3 4 5 6 7 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <access origin="*" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <allow-intent href="gettogetherapp:*" /> <allow-intent href="http://*/*" /> <allow-intent href="https://*/*" /> <allow-intent href="tel:*" /> <allow-intent href="mailto:*" /> <allow-intent href="geo:*" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 <access origin="*" /> 10 11 12 13 14 15 16 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <platform name="android"> <allow-intent href="market:*" /> </platform> g p g Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 19 20 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <variable name="ANDROID_HOST" value=" " /> 30 <variable name="ANDROID_PATHPREFIX" value="/" /> 31 </plugin> 32 33 <preference name="Scheme" value="https" /> 34
  58. <name>Gatherr</name> <description>Gatherr - Demo Application</description> <author email="mail@offering.solutions" href="https://offering.solution Offering Solutions

    Software </author> <content src="index.html" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 3 4 5 6 7 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <access origin="*" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <allow-intent href="gettogetherapp:*" /> <allow-intent href="http://*/*" /> <allow-intent href="https://*/*" /> <allow-intent href="tel:*" /> <allow-intent href="mailto:*" /> <allow-intent href="geo:*" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 <access origin="*" /> 10 11 12 13 14 15 16 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <platform name="android"> <allow-intent href="market:*" /> </platform> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 19 20 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <engine name="android" spec="~9.0.0" /> <content src="index.html" /> 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <variable name="ANDROID_HOST" value=" " /> 30 <variable name="ANDROID_PATHPREFIX" value="/" /> 31 </plugin> 32 33 <preference name="Scheme" value="https" /> 34 <preference name="android-minSdkVersion" value="22" /> 35 </widget> 36
  59. <name>Gatherr</name> <description>Gatherr - Demo Application</description> <author email="mail@offering.solutions" href="https://offering.solution Offering Solutions

    Software </author> <content src="index.html" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 3 4 5 6 7 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <access origin="*" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <allow-intent href="gettogetherapp:*" /> <allow-intent href="http://*/*" /> <allow-intent href="https://*/*" /> <allow-intent href="tel:*" /> <allow-intent href="mailto:*" /> <allow-intent href="geo:*" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 <access origin="*" /> 10 11 12 13 14 15 16 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <platform name="android"> <allow-intent href="market:*" /> </platform> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 19 20 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <engine name="android" spec="~9.0.0" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> <content src="index.html" /> 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <variable name="ANDROID_HOST" value=" " /> 30 <variable name="ANDROID_PATHPREFIX" value="/" /> 31 </plugin> 32 33 <preference name="Scheme" value="https" /> 34 <preference name="android-minSdkVersion" value="22" /> 35 </widget> 36
  60. <name>Gatherr</name> <description>Gatherr - Demo Application</description> <author email="mail@offering.solutions" href="https://offering.solution Offering Solutions

    Software </author> <content src="index.html" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 3 4 5 6 7 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <access origin="*" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <allow-intent href="gettogetherapp:*" /> <allow-intent href="http://*/*" /> <allow-intent href="https://*/*" /> <allow-intent href="tel:*" /> <allow-intent href="mailto:*" /> <allow-intent href="geo:*" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 <access origin="*" /> 10 11 12 13 14 15 16 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <platform name="android"> <allow-intent href="market:*" /> </platform> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 19 20 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <engine name="android" spec="~9.0.0" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> <variable name="URL_SCHEME" value="gatherrapp" /> <variable name="ANDROID_SCHEME" value=" " /> <variable name="ANDROID_HOST" value=" " /> <variable name="ANDROID_PATHPREFIX" value="/" /> </plugin> <content src="index.html" /> 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 27 28 29 30 31 32 33 <preference name="Scheme" value="https" /> 34 <preference name="android-minSdkVersion" value="22" /> 35 </widget> 36
  61. <name>Gatherr</name> <description>Gatherr - Demo Application</description> <author email="mail@offering.solutions" href="https://offering.solution Offering Solutions

    Software </author> <content src="index.html" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 3 4 5 6 7 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <access origin="*" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <allow-intent href="gettogetherapp:*" /> <allow-intent href="http://*/*" /> <allow-intent href="https://*/*" /> <allow-intent href="tel:*" /> <allow-intent href="mailto:*" /> <allow-intent href="geo:*" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 <access origin="*" /> 10 11 12 13 14 15 16 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <platform name="android"> <allow-intent href="market:*" /> </platform> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 19 20 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <engine name="android" spec="~9.0.0" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> <variable name="URL_SCHEME" value="gatherrapp" /> <variable name="ANDROID_SCHEME" value=" " /> <?xml version='1.0' encoding='utf-8'?> 1 <widget id="com.offering.solutions" ...> 2 <name>Gatherr</name> 3 <description>Gatherr - Demo Application</description> 4 <author email="mail@offering.solutions" href="https://offering.solution 5 Offering Solutions Software 6 </author> 7 <content src="index.html" /> 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 27 28 29 <preference name="Scheme" value="https" /> <preference name="android-minSdkVersion" value="22" /> <content src="index.html" /> 8 9 <access origin="*" /> 10 11 <allow-intent href="gettogetherapp:*" /> 12 <allow-intent href="http://*/*" /> 13 <allow-intent href="https://*/*" /> 14 <allow-intent href="tel:*" /> 15 <allow-intent href="mailto:*" /> 16 <allow-intent href="geo:*" /> 17 18 <platform name="android"> 19 <allow-intent href="market:*" /> 20 </platform> 21 22 <engine name="android" spec="~9.0.0" /> 23 24 <plugin name="cordova-plugin-camera" spec="~4.0.2" /> 25 26 <plugin name="cordova-plugin-customurlscheme" spec="^4.3.0"> 27 <variable name="URL_SCHEME" value="gatherrapp" /> 28 <variable name="ANDROID_SCHEME" value=" " /> 29 <variable name="ANDROID_HOST" value=" " /> 30 <variable name="ANDROID_PATHPREFIX" value="/" /> 31 </plugin> 32 33 34 35 </widget> 36
  62. $ cordova plugin add cordova-plugin-camera

  63. cordova platform add android cordova platform add ios cordova build

    1 2 3 4
  64. cordova platform add android cordova platform add ios cordova build

    1 2 3 4 cordova platform add android 1 cordova platform add ios 2 3 cordova build 4
  65. cordova platform add android cordova platform add ios cordova build

    1 2 3 4 cordova platform add android 1 cordova platform add ios 2 3 cordova build 4 cordova platform add ios cordova platform add android 1 2 3 cordova build 4
  66. cordova platform add android cordova platform add ios cordova build

    1 2 3 4 cordova platform add android 1 cordova platform add ios 2 3 cordova build 4 cordova platform add ios cordova platform add android 1 2 3 cordova build 4 cordova build cordova platform add android 1 cordova platform add ios 2 3 4
  67. None
  68. None
  69. None
  70. None
  71. None
  72. Dem

  73. Electro

  74. Electron is a tool for building Cross- Platform Desktop Apps

    with Javascript, Html and CSS " "
  75. None
  76. None
  77. Chromiu

  78. None
  79. None
  80. an man mor ...

  81. $ npm install electron -g

  82. ├── index.html ├── index.js └── package.json

  83. { "name": "your-app", "version": "0.1.0", "main": "index.js", "scripts": { "start":

    "electron ." } } 1 2 3 4 5 6 7 8
  84. { "name": "your-app", "version": "0.1.0", "main": "index.js", "scripts": { "start":

    "electron ." } } 1 2 3 4 5 6 7 8 "main": "index.js", { 1 "name": "your-app", 2 "version": "0.1.0", 3 4 "scripts": { 5 "start": "electron ." 6 } 7 } 8
  85. const { app, BrowserWindow } = require('electron'); createWindow = ()

    => { // Create the browser window. const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, }, }); // and load the index.html of the app. win.loadFile('index.html'); }; app.whenReady().then(createWindow); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
  86. const { app, BrowserWindow } = require('electron'); createWindow = ()

    => { // Create the browser window. const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, }, }); // and load the index.html of the app. win.loadFile('index.html'); }; app.whenReady().then(createWindow); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const { app, BrowserWindow } = require('electron'); 1 2 createWindow = () => { 3 // Create the browser window. 4 const win = new BrowserWindow({ 5 width: 800, 6 height: 600, 7 webPreferences: { 8 nodeIntegration: true, 9 }, 10 }); 11 12 // and load the index.html of the app. 13 win.loadFile('index.html'); 14 }; 15 16 app.whenReady().then(createWindow); 17
  87. const { app, BrowserWindow } = require('electron'); createWindow = ()

    => { // Create the browser window. const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, }, }); // and load the index.html of the app. win.loadFile('index.html'); }; app.whenReady().then(createWindow); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const { app, BrowserWindow } = require('electron'); 1 2 createWindow = () => { 3 // Create the browser window. 4 const win = new BrowserWindow({ 5 width: 800, 6 height: 600, 7 webPreferences: { 8 nodeIntegration: true, 9 }, 10 }); 11 12 // and load the index.html of the app. 13 win.loadFile('index.html'); 14 }; 15 16 app.whenReady().then(createWindow); 17 createWindow = () => { // Create the browser window. const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, }, }); // and load the index.html of the app. win.loadFile('index.html'); }; const { app, BrowserWindow } = require('electron'); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 app.whenReady().then(createWindow); 17
  88. const { app, BrowserWindow } = require('electron'); createWindow = ()

    => { // Create the browser window. const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, }, }); // and load the index.html of the app. win.loadFile('index.html'); }; app.whenReady().then(createWindow); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const { app, BrowserWindow } = require('electron'); 1 2 createWindow = () => { 3 // Create the browser window. 4 const win = new BrowserWindow({ 5 width: 800, 6 height: 600, 7 webPreferences: { 8 nodeIntegration: true, 9 }, 10 }); 11 12 // and load the index.html of the app. 13 win.loadFile('index.html'); 14 }; 15 16 app.whenReady().then(createWindow); 17 createWindow = () => { // Create the browser window. const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, }, }); // and load the index.html of the app. win.loadFile('index.html'); }; const { app, BrowserWindow } = require('electron'); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 app.whenReady().then(createWindow); 17 const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, }, }); const { app, BrowserWindow } = require('electron'); 1 2 createWindow = () => { 3 // Create the browser window. 4 5 6 7 8 9 10 11 12 // and load the index.html of the app. 13 win.loadFile('index.html'); 14 }; 15 16 app.whenReady().then(createWindow); 17
  89. const { app, BrowserWindow } = require('electron'); createWindow = ()

    => { // Create the browser window. const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, }, }); // and load the index.html of the app. win.loadFile('index.html'); }; app.whenReady().then(createWindow); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const { app, BrowserWindow } = require('electron'); 1 2 createWindow = () => { 3 // Create the browser window. 4 const win = new BrowserWindow({ 5 width: 800, 6 height: 600, 7 webPreferences: { 8 nodeIntegration: true, 9 }, 10 }); 11 12 // and load the index.html of the app. 13 win.loadFile('index.html'); 14 }; 15 16 app.whenReady().then(createWindow); 17 createWindow = () => { // Create the browser window. const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, }, }); // and load the index.html of the app. win.loadFile('index.html'); }; const { app, BrowserWindow } = require('electron'); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 app.whenReady().then(createWindow); 17 const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, }, }); const { app, BrowserWindow } = require('electron'); 1 2 createWindow = () => { 3 // Create the browser window. 4 5 6 7 8 9 10 11 12 // and load the index.html of the app. 13 win.loadFile('index.html'); 14 }; 15 16 app.whenReady().then(createWindow); 17 win.loadFile('index.html'); const { app, BrowserWindow } = require('electron'); 1 2 createWindow = () => { 3 // Create the browser window. 4 const win = new BrowserWindow({ 5 width: 800, 6 height: 600, 7 webPreferences: { 8 nodeIntegration: true, 9 }, 10 }); 11 12 // and load the index.html of the app. 13 14 }; 15 16 app.whenReady().then(createWindow); 17
  90. const { app, BrowserWindow } = require('electron'); createWindow = ()

    => { // Create the browser window. const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, }, }); // and load the index.html of the app. win.loadFile('index.html'); }; app.whenReady().then(createWindow); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const { app, BrowserWindow } = require('electron'); 1 2 createWindow = () => { 3 // Create the browser window. 4 const win = new BrowserWindow({ 5 width: 800, 6 height: 600, 7 webPreferences: { 8 nodeIntegration: true, 9 }, 10 }); 11 12 // and load the index.html of the app. 13 win.loadFile('index.html'); 14 }; 15 16 app.whenReady().then(createWindow); 17 createWindow = () => { // Create the browser window. const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, }, }); // and load the index.html of the app. win.loadFile('index.html'); }; const { app, BrowserWindow } = require('electron'); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 app.whenReady().then(createWindow); 17 const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, }, }); const { app, BrowserWindow } = require('electron'); 1 2 createWindow = () => { 3 // Create the browser window. 4 5 6 7 8 9 10 11 12 // and load the index.html of the app. 13 win.loadFile('index.html'); 14 }; 15 16 app.whenReady().then(createWindow); 17 win.loadFile('index.html'); const { app, BrowserWindow } = require('electron'); 1 2 createWindow = () => { 3 // Create the browser window. 4 const win = new BrowserWindow({ 5 width: 800, 6 height: 600, 7 webPreferences: { 8 nodeIntegration: true, 9 }, 10 }); 11 12 // and load the index.html of the app. 13 14 }; 15 16 app.whenReady().then(createWindow); 17 app.whenReady().then(createWindow); const { app, BrowserWindow } = require('electron'); 1 2 createWindow = () => { 3 // Create the browser window. 4 const win = new BrowserWindow({ 5 width: 800, 6 height: 600, 7 webPreferences: { 8 nodeIntegration: true, 9 }, 10 }); 11 12 // and load the index.html of the app. 13 win.loadFile('index.html'); 14 }; 15 16 17
  91. <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Hello World!</title> </head>

    <body> <h1>Hello World!</h1> </body> </html> 1 2 3 4 5 6 7 8 9 10
  92. $ electron .

  93. None
  94. None
  95. Process Mai

  96. Process Renderer

  97. None
  98. None
  99. None
  100. ├── assets │ ... ├── 6.2c6c97b8608a85a82adc.js ├── common.42c8477e0640407ae045.js ├── favicon.ico

    ├── icon.ico ├── index.html ├── index.js ├── main.8bb24261aa275d6a43db.js ├── package.json ├── polyfills-es5.739d51467cc1d8efbfae.js ├── polyfills.ef4ae634e106e395892c.js ├── runtime.061b6e0597d9fe17b937.js ├── scripts.82aad45f2fad02beee3c.js ├── styles.f503a9ab21b5d570c8af.css 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  101. ├── assets │ ... ├── 6.2c6c97b8608a85a82adc.js ├── common.42c8477e0640407ae045.js ├── favicon.ico

    ├── icon.ico ├── index.html ├── index.js ├── main.8bb24261aa275d6a43db.js ├── package.json ├── polyfills-es5.739d51467cc1d8efbfae.js ├── polyfills.ef4ae634e106e395892c.js ├── runtime.061b6e0597d9fe17b937.js ├── scripts.82aad45f2fad02beee3c.js ├── styles.f503a9ab21b5d570c8af.css 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ├── assets │ ... ├── 6.2c6c97b8608a85a82adc.js ├── common.42c8477e0640407ae045.js ├── favicon.ico ├── index.html ├── main.8bb24261aa275d6a43db.js ├── polyfills-es5.739d51467cc1d8efbfae.js ├── polyfills.ef4ae634e106e395892c.js ├── runtime.061b6e0597d9fe17b937.js ├── scripts.82aad45f2fad02beee3c.js ├── styles.f503a9ab21b5d570c8af.css 1 2 3 4 5 ├── icon.ico 6 7 ├── index.js 8 9 ├── package.json 10 11 12 13 14 15
  102. ├── assets │ ... ├── 6.2c6c97b8608a85a82adc.js ├── common.42c8477e0640407ae045.js ├── favicon.ico

    ├── icon.ico ├── index.html ├── index.js ├── main.8bb24261aa275d6a43db.js ├── package.json ├── polyfills-es5.739d51467cc1d8efbfae.js ├── polyfills.ef4ae634e106e395892c.js ├── runtime.061b6e0597d9fe17b937.js ├── scripts.82aad45f2fad02beee3c.js ├── styles.f503a9ab21b5d570c8af.css 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ├── assets │ ... ├── 6.2c6c97b8608a85a82adc.js ├── common.42c8477e0640407ae045.js ├── favicon.ico ├── index.html ├── main.8bb24261aa275d6a43db.js ├── polyfills-es5.739d51467cc1d8efbfae.js ├── polyfills.ef4ae634e106e395892c.js ├── runtime.061b6e0597d9fe17b937.js ├── scripts.82aad45f2fad02beee3c.js ├── styles.f503a9ab21b5d570c8af.css 1 2 3 4 5 ├── icon.ico 6 7 ├── index.js 8 9 ├── package.json 10 11 12 13 14 15 ├── icon.ico ├── index.js ├── package.json ├── assets 1 │ ... 2 ├── 6.2c6c97b8608a85a82adc.js 3 ├── common.42c8477e0640407ae045.js 4 ├── favicon.ico 5 6 ├── index.html 7 8 ├── main.8bb24261aa275d6a43db.js 9 10 ├── polyfills-es5.739d51467cc1d8efbfae.js 11 ├── polyfills.ef4ae634e106e395892c.js 12 ├── runtime.061b6e0597d9fe17b937.js 13 ├── scripts.82aad45f2fad02beee3c.js 14 ├── styles.f503a9ab21b5d570c8af.css 15
  103. None
  104. Communicatio

  105. Communicatio IPC

  106. mai proces const { ipcMain } = require('electron') ipcMain.on('asynchronous-message', (event,

    arg) => { console.log(arg) // prints "ping" event.reply('asynchronous-reply', 'pong') }) ipcMain.on('synchronous-message', (event, arg) => { console.log(arg) // prints "ping" event.returnValue = 'pong' }) 1 2 3 4 5 6 7 8 9 10 11
  107. mai proces const { ipcMain } = require('electron') ipcMain.on('asynchronous-message', (event,

    arg) => { console.log(arg) // prints "ping" event.reply('asynchronous-reply', 'pong') }) ipcMain.on('synchronous-message', (event, arg) => { console.log(arg) // prints "ping" event.returnValue = 'pong' }) 1 2 3 4 5 6 7 8 9 10 11 const { ipcMain } = require('electron') 1 2 ipcMain.on('asynchronous-message', (event, arg) => { 3 console.log(arg) // prints "ping" 4 event.reply('asynchronous-reply', 'pong') 5 }) 6 7 ipcMain.on('synchronous-message', (event, arg) => { 8 console.log(arg) // prints "ping" 9 event.returnValue = 'pong' 10 }) 11
  108. mai proces const { ipcMain } = require('electron') ipcMain.on('asynchronous-message', (event,

    arg) => { console.log(arg) // prints "ping" event.reply('asynchronous-reply', 'pong') }) ipcMain.on('synchronous-message', (event, arg) => { console.log(arg) // prints "ping" event.returnValue = 'pong' }) 1 2 3 4 5 6 7 8 9 10 11 const { ipcMain } = require('electron') 1 2 ipcMain.on('asynchronous-message', (event, arg) => { 3 console.log(arg) // prints "ping" 4 event.reply('asynchronous-reply', 'pong') 5 }) 6 7 ipcMain.on('synchronous-message', (event, arg) => { 8 console.log(arg) // prints "ping" 9 event.returnValue = 'pong' 10 }) 11 ipcMain.on('asynchronous-message', (event, arg) => { console.log(arg) // prints "ping" event.reply('asynchronous-reply', 'pong') }) const { ipcMain } = require('electron') 1 2 3 4 5 6 7 ipcMain.on('synchronous-message', (event, arg) => { 8 console.log(arg) // prints "ping" 9 event.returnValue = 'pong' 10 }) 11
  109. mai proces const { ipcMain } = require('electron') ipcMain.on('asynchronous-message', (event,

    arg) => { console.log(arg) // prints "ping" event.reply('asynchronous-reply', 'pong') }) ipcMain.on('synchronous-message', (event, arg) => { console.log(arg) // prints "ping" event.returnValue = 'pong' }) 1 2 3 4 5 6 7 8 9 10 11 const { ipcMain } = require('electron') 1 2 ipcMain.on('asynchronous-message', (event, arg) => { 3 console.log(arg) // prints "ping" 4 event.reply('asynchronous-reply', 'pong') 5 }) 6 7 ipcMain.on('synchronous-message', (event, arg) => { 8 console.log(arg) // prints "ping" 9 event.returnValue = 'pong' 10 }) 11 ipcMain.on('asynchronous-message', (event, arg) => { console.log(arg) // prints "ping" event.reply('asynchronous-reply', 'pong') }) const { ipcMain } = require('electron') 1 2 3 4 5 6 7 ipcMain.on('synchronous-message', (event, arg) => { 8 console.log(arg) // prints "ping" 9 event.returnValue = 'pong' 10 }) 11 ipcMain.on('synchronous-message', (event, arg) => { console.log(arg) // prints "ping" event.returnValue = 'pong' }) const { ipcMain } = require('electron') 1 2 ipcMain.on('asynchronous-message', (event, arg) => { 3 console.log(arg) // prints "ping" 4 event.reply('asynchronous-reply', 'pong') 5 }) 6 7 8 9 10 11
  110. renderer proces const { ipcRenderer } = require('electron'); // prints

    "pong" console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) ipcRenderer.on('asynchronous-reply', (event, arg) => { console.log(arg) // prints "pong" }) ipcRenderer.send('asynchronous-message', 'ping') 1 2 3 4 5 6 7 8 9 10
  111. renderer proces const { ipcRenderer } = require('electron'); // prints

    "pong" console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) ipcRenderer.on('asynchronous-reply', (event, arg) => { console.log(arg) // prints "pong" }) ipcRenderer.send('asynchronous-message', 'ping') 1 2 3 4 5 6 7 8 9 10 const { ipcRenderer } = require('electron'); 1 2 // prints "pong" 3 console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) 4 5 ipcRenderer.on('asynchronous-reply', (event, arg) => { 6 console.log(arg) // prints "pong" 7 }) 8 9 ipcRenderer.send('asynchronous-message', 'ping') 10
  112. renderer proces const { ipcRenderer } = require('electron'); // prints

    "pong" console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) ipcRenderer.on('asynchronous-reply', (event, arg) => { console.log(arg) // prints "pong" }) ipcRenderer.send('asynchronous-message', 'ping') 1 2 3 4 5 6 7 8 9 10 const { ipcRenderer } = require('electron'); 1 2 // prints "pong" 3 console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) 4 5 ipcRenderer.on('asynchronous-reply', (event, arg) => { 6 console.log(arg) // prints "pong" 7 }) 8 9 ipcRenderer.send('asynchronous-message', 'ping') 10 // prints "pong" console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) const { ipcRenderer } = require('electron'); 1 2 3 4 5 ipcRenderer.on('asynchronous-reply', (event, arg) => { 6 console.log(arg) // prints "pong" 7 }) 8 9 ipcRenderer.send('asynchronous-message', 'ping') 10
  113. renderer proces const { ipcRenderer } = require('electron'); // prints

    "pong" console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) ipcRenderer.on('asynchronous-reply', (event, arg) => { console.log(arg) // prints "pong" }) ipcRenderer.send('asynchronous-message', 'ping') 1 2 3 4 5 6 7 8 9 10 const { ipcRenderer } = require('electron'); 1 2 // prints "pong" 3 console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) 4 5 ipcRenderer.on('asynchronous-reply', (event, arg) => { 6 console.log(arg) // prints "pong" 7 }) 8 9 ipcRenderer.send('asynchronous-message', 'ping') 10 // prints "pong" console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) const { ipcRenderer } = require('electron'); 1 2 3 4 5 ipcRenderer.on('asynchronous-reply', (event, arg) => { 6 console.log(arg) // prints "pong" 7 }) 8 9 ipcRenderer.send('asynchronous-message', 'ping') 10 ipcRenderer.on('asynchronous-reply', (event, arg) => { console.log(arg) // prints "pong" }) ipcRenderer.send('asynchronous-message', 'ping') const { ipcRenderer } = require('electron'); 1 2 // prints "pong" 3 console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) 4 5 6 7 8 9 10
  114. mai proces var os = require('os'); var cpus = os.cpus();

    1 2 3
  115. mai proces var os = require('os'); var cpus = os.cpus();

    1 2 3 var os = require('os'); 1 2 var cpus = os.cpus(); 3
  116. mai proces var os = require('os'); var cpus = os.cpus();

    1 2 3 var os = require('os'); 1 2 var cpus = os.cpus(); 3 var cpus = os.cpus(); var os = require('os'); 1 2 3
  117. mai proces let startSendCpuValues = () => { setInterval(() =>

    { cpuValues.getCPUUsage(percentage => { if (mainWindow) { mainWindow.webContents.send( 'newCpuValue', (percentage * 100).toFixed(2) ); } }); }, 1000); }; 1 2 3 4 5 6 7 8 9 10 11 12
  118. mai proces let startSendCpuValues = () => { setInterval(() =>

    { cpuValues.getCPUUsage(percentage => { if (mainWindow) { mainWindow.webContents.send( 'newCpuValue', (percentage * 100).toFixed(2) ); } }); }, 1000); }; 1 2 3 4 5 6 7 8 9 10 11 12 let startSendCpuValues = () => { setInterval(() => { cpuValues.getCPUUsage(percentage => { if (mainWindow) { mainWindow.webContents.send( 'newCpuValue', (percentage * 100).toFixed(2) ); } }); }, 1000); }; 1 2 3 4 5 6 7 8 9 10 11 12
  119. mai proces let startSendCpuValues = () => { setInterval(() =>

    { cpuValues.getCPUUsage(percentage => { if (mainWindow) { mainWindow.webContents.send( 'newCpuValue', (percentage * 100).toFixed(2) ); } }); }, 1000); }; 1 2 3 4 5 6 7 8 9 10 11 12 let startSendCpuValues = () => { setInterval(() => { cpuValues.getCPUUsage(percentage => { if (mainWindow) { mainWindow.webContents.send( 'newCpuValue', (percentage * 100).toFixed(2) ); } }); }, 1000); }; 1 2 3 4 5 6 7 8 9 10 11 12 cpuValues.getCPUUsage(percentage => { }); let startSendCpuValues = () => { 1 setInterval(() => { 2 3 if (mainWindow) { 4 mainWindow.webContents.send( 5 'newCpuValue', 6 (percentage * 100).toFixed(2) 7 ); 8 } 9 10 }, 1000); 11 }; 12
  120. mai proces let startSendCpuValues = () => { setInterval(() =>

    { cpuValues.getCPUUsage(percentage => { if (mainWindow) { mainWindow.webContents.send( 'newCpuValue', (percentage * 100).toFixed(2) ); } }); }, 1000); }; 1 2 3 4 5 6 7 8 9 10 11 12 let startSendCpuValues = () => { setInterval(() => { cpuValues.getCPUUsage(percentage => { if (mainWindow) { mainWindow.webContents.send( 'newCpuValue', (percentage * 100).toFixed(2) ); } }); }, 1000); }; 1 2 3 4 5 6 7 8 9 10 11 12 cpuValues.getCPUUsage(percentage => { }); let startSendCpuValues = () => { 1 setInterval(() => { 2 3 if (mainWindow) { 4 mainWindow.webContents.send( 5 'newCpuValue', 6 (percentage * 100).toFixed(2) 7 ); 8 } 9 10 }, 1000); 11 }; 12 mainWindow.webContents.send( 'newCpuValue', (percentage * 100).toFixed(2) ); let startSendCpuValues = () => { 1 setInterval(() => { 2 cpuValues.getCPUUsage(percentage => { 3 if (mainWindow) { 4 5 6 7 8 } 9 }); 10 }, 1000); 11 }; 12
  121. renderer proces @Injectable({ providedIn: 'root' }) export class CpuValueService {

    private onNewCpuValue = new Subject<string>(); get newCpuValue(){ return this.onNewCpuValue.asObservable(); } constructor(private electronService: ElectronService) { if (environment.desktop) { this.registerCpuEvent(); } } private registerCpuEvent() { if (this.electronService.ipcRenderer) { this.electronService.ipcRenderer.on( 'newCpuValue', 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
  122. renderer proces @Injectable({ providedIn: 'root' }) export class CpuValueService {

    private onNewCpuValue = new Subject<string>(); get newCpuValue(){ return this.onNewCpuValue.asObservable(); } constructor(private electronService: ElectronService) { if (environment.desktop) { this.registerCpuEvent(); } } private registerCpuEvent() { if (this.electronService.ipcRenderer) { this.electronService.ipcRenderer.on( 'newCpuValue', 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 constructor(private electronService: ElectronService) { if (environment.desktop) { this.registerCpuEvent(); } } @Injectable({ providedIn: root }) 1 export class CpuValueService { 2 private onNewCpuValue = new Subject<string>(); 3 4 get newCpuValue(){ 5 return this.onNewCpuValue.asObservable(); 6 } 7 8 9 10 11 12 13 14 private registerCpuEvent() { 15 if (this.electronService.ipcRenderer) { 16 this.electronService.ipcRenderer.on( 17 'newCpuValue', 18 (event: any, data: any) => { 19 this.onNewCpuValue.next(data); 20 } 21
  123. renderer proces @Injectable({ providedIn: 'root' }) export class CpuValueService {

    private onNewCpuValue = new Subject<string>(); get newCpuValue(){ return this.onNewCpuValue.asObservable(); } constructor(private electronService: ElectronService) { if (environment.desktop) { this.registerCpuEvent(); } } private registerCpuEvent() { if (this.electronService.ipcRenderer) { this.electronService.ipcRenderer.on( 'newCpuValue', 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 constructor(private electronService: ElectronService) { if (environment.desktop) { this.registerCpuEvent(); } } @Injectable({ providedIn: 'root' }) 1 export class CpuValueService { 2 private onNewCpuValue = new Subject<string>(); 3 4 get newCpuValue(){ 5 return this.onNewCpuValue.asObservable(); 6 } 7 8 9 10 11 12 13 14 private registerCpuEvent() { 15 if (this.electronService.ipcRenderer) { 16 this.electronService.ipcRenderer.on( 17 'newCpuValue', 18 private registerCpuEvent() { if (this.electronService.ipcRenderer) { this.electronService.ipcRenderer.on( 'newCpuValue', (event: any, data: any) => { this.onNewCpuValue.next(data); } ); } } } 7 8 constructor(private electronService: ElectronService) { 9 if (environment.desktop) { 10 this.registerCpuEvent(); 11 } 12 } 13 14 15 16 17 18 19 20 21 22 23 24 } 25
  124. renderer proces @Injectable({ providedIn: 'root' }) export class CpuValueService {

    private onNewCpuValue = new Subject<string>(); get newCpuValue(){ return this.onNewCpuValue.asObservable(); } constructor(private electronService: ElectronService) { if (environment.desktop) { this.registerCpuEvent(); } } private registerCpuEvent() { if (this.electronService.ipcRenderer) { this.electronService.ipcRenderer.on( 'newCpuValue', 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 constructor(private electronService: ElectronService) { if (environment.desktop) { this.registerCpuEvent(); } } @Injectable({ providedIn: 'root' }) 1 export class CpuValueService { 2 private onNewCpuValue = new Subject<string>(); 3 4 get newCpuValue(){ 5 return this.onNewCpuValue.asObservable(); 6 } 7 8 9 10 11 12 13 14 private registerCpuEvent() { 15 if (this.electronService.ipcRenderer) { 16 this.electronService.ipcRenderer.on( 17 'newCpuValue', 18 private registerCpuEvent() { if (this.electronService.ipcRenderer) { this.electronService.ipcRenderer.on( 'newCpuValue', @Injectable({ providedIn: 'root' }) 1 export class CpuValueService { 2 private onNewCpuValue = new Subject<string>(); 3 4 get newCpuValue(){ 5 return this.onNewCpuValue.asObservable(); 6 } 7 8 constructor(private electronService: ElectronService) { 9 if (environment.desktop) { 10 this.registerCpuEvent(); 11 } 12 } 13 14 15 16 17 18 private onNewCpuValue = new Subject<string>(); get newCpuValue(){ return this.onNewCpuValue.asObservable(); } @Injectable({ providedIn: 'root' }) 1 export class CpuValueService { 2 3 4 5 6 7 8 constructor(private electronService: ElectronService) { 9 if (environment.desktop) { 10 this.registerCpuEvent(); 11 } 12 } 13 14 private registerCpuEvent() { 15 if (this.electronService.ipcRenderer) { 16 this.electronService.ipcRenderer.on( 17 'newCpuValue', 18
  125. $ npm install electron-packager -g

  126. $ electron-packager .temp/desktop

  127. $ electron-packager .temp/desktop --platform=linux, win32

  128. Automatic Updates Crash Reports Content Tracing Installation Packages

  129. None
  130. Dem

  131. What about variation points? " "

  132. None
  133. Dependenc Injectio

  134. @Injectable({ providedIn: 'root', }) export abstract class AbstractCameraService { abstract

    getPhoto(...): Observable<Photo>; } 1 2 3 4 5 6
  135. @Injectable({ providedIn: 'root', useFactory: cameraFactory, deps: [PlatformInformationService], }) export abstract

    class AbstractCameraService { abstract getPhoto(...): Observable<Photo>; } 1 2 3 4 5 6 7 8
  136. export function cameraFactory( platformInformationService: PlatformInformationService ): AbstractCameraService { return platformInformationService.isMobile

    ? new MobileCameraService() : new DesktopCameraService(); } @Injectable({ providedIn: 'root', useFactory: cameraFactory, deps: [PlatformInformationService], }) export abstract class AbstractCameraService { abstract getPhoto(...): Observable<Photo>; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  137. import { AbstractCameraService, Photo } from '@workspace/features/camera'; @Component({ ... })

    export class ProfileDetailsComponent { constructor( private cameraService: AbstractCameraService ) {} pictureClicked() { this.cameraService.getPhoto() .subscribe((result: Photo) => { // ... }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
  138. import { AbstractCameraService, Photo } from '@workspace/features/camera'; @Component({ ... })

    export class ProfileDetailsComponent { constructor( private cameraService: AbstractCameraService ) {} pictureClicked() { this.cameraService.getPhoto() .subscribe((result: Photo) => { // ... }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import { AbstractCameraService, Photo } from '@workspace/features/camera'; 1 2 3 4 @Component({ ... }) 5 export class ProfileDetailsComponent { 6 7 constructor( 8 private cameraService: AbstractCameraService 9 ) {} 10 11 pictureClicked() { 12 this.cameraService.getPhoto() 13 .subscribe((result: Photo) => { 14 // ... 15 }); 16 } 17 } 18
  139. import { AbstractCameraService, Photo } from '@workspace/features/camera'; @Component({ ... })

    export class ProfileDetailsComponent { constructor( private cameraService: AbstractCameraService ) {} pictureClicked() { this.cameraService.getPhoto() .subscribe((result: Photo) => { // ... }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import { AbstractCameraService, Photo } from '@workspace/features/camera'; 1 2 3 4 @Component({ ... }) 5 export class ProfileDetailsComponent { 6 7 constructor( 8 private cameraService: AbstractCameraService 9 ) {} 10 11 pictureClicked() { 12 this.cameraService.getPhoto() 13 .subscribe((result: Photo) => { 14 // ... 15 }); 16 } 17 } 18 constructor( private cameraService: AbstractCameraService ) {} import { 1 AbstractCameraService, Photo 2 } from '@workspace/features/camera'; 3 4 @Component({ ... }) 5 export class ProfileDetailsComponent { 6 7 8 9 10 11 pictureClicked() { 12 this.cameraService.getPhoto() 13 .subscribe((result: Photo) => { 14 // ... 15 }); 16 } 17 } 18
  140. import { AbstractCameraService, Photo } from '@workspace/features/camera'; @Component({ ... })

    export class ProfileDetailsComponent { constructor( private cameraService: AbstractCameraService ) {} pictureClicked() { this.cameraService.getPhoto() .subscribe((result: Photo) => { // ... }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import { AbstractCameraService, Photo } from '@workspace/features/camera'; 1 2 3 4 @Component({ ... }) 5 export class ProfileDetailsComponent { 6 7 constructor( 8 private cameraService: AbstractCameraService 9 ) {} 10 11 pictureClicked() { 12 this.cameraService.getPhoto() 13 .subscribe((result: Photo) => { 14 // ... 15 }); 16 } 17 } 18 constructor( private cameraService: AbstractCameraService ) {} import { 1 AbstractCameraService, Photo 2 } from '@workspace/features/camera'; 3 4 @Component({ ... }) 5 export class ProfileDetailsComponent { 6 7 8 9 10 11 pictureClicked() { 12 this.cameraService.getPhoto() 13 .subscribe((result: Photo) => { 14 // ... 15 }); 16 } 17 } 18 pictureClicked() { this.cameraService.getPhoto() .subscribe((result: Photo) => { // ... }); } import { 1 AbstractCameraService, Photo 2 } from '@workspace/features/camera'; 3 4 @Component({ ... }) 5 export class ProfileDetailsComponent { 6 7 constructor( 8 private cameraService: AbstractCameraService 9 ) {} 10 11 12 13 14 15 16 17 } 18
  141. None
  142. Securit

  143. Mobil Desktop Web

  144. OAut 2 OIDC

  145. https://bit.ly/3mMHyKY

  146. Alternative

  147. None
  148. Progressiv Web App

  149. Realtim Cr Platfor App Angular, ASP.NET Cor & Signa R

    wit
  150. an yo !

  151. Fabian Gosebrink