{"id":34609488,"url":"https://github.com/mwager/atonego","last_synced_at":"2026-03-13T08:32:30.360Z","repository":{"id":8976602,"uuid":"10720805","full_name":"mwager/atonego","owner":"mwager","description":"The AtOneGo sources (backend/frontend)","archived":false,"fork":false,"pushed_at":"2017-03-04T14:00:47.000Z","size":62138,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-26T02:39:30.900Z","etag":null,"topics":["backbone","hybrid","ionic2","javascript","openshift","phonegap","typescript"],"latest_commit_sha":null,"homepage":"http://at-one-go.com","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"freifunkhamburg/start-ffhh","license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mwager.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-06-16T13:56:31.000Z","updated_at":"2017-03-02T20:11:34.000Z","dependencies_parsed_at":"2022-08-27T01:52:04.173Z","dependency_job_id":null,"html_url":"https://github.com/mwager/atonego","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/mwager/atonego","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mwager%2Fatonego","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mwager%2Fatonego/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mwager%2Fatonego/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mwager%2Fatonego/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mwager","download_url":"https://codeload.github.com/mwager/atonego/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mwager%2Fatonego/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30462286,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-13T06:34:02.089Z","status":"ssl_error","status_checked_at":"2026-03-13T06:33:49.182Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backbone","hybrid","ionic2","javascript","openshift","phonegap","typescript"],"created_at":"2025-12-24T14:01:37.575Z","updated_at":"2026-03-13T08:32:30.340Z","avatar_url":"https://github.com/mwager.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AtOneGo\n\n_make webapp \u0026\u0026 make ios \u0026\u0026 make android - an experiment with JavaScript/NodeJS and Phonegap_\n\n[![Build Status](https://travis-ci.org/mwager/atonego.png?branch=master)](https://travis-ci.org/mwager/atonego)\n\n![AtOneGo](https://atonego-mwager.rhcloud.com/app/images/logo.png)\n\nThis is the repo of the app [AtOneGo](http://at-one-go.com)\n\n* [View in iTunes store](https://itunes.apple.com/us/app/atonego/id668972250)\n* [View in Google Play store](https://play.google.com/store/apps/details?id=de.mwager.atonego)\n* [Try the WebApp](https://atonego-mwager.rhcloud.com/app)\n\nThis file contains the documentation for developers.\n\nAuthor: Michael Wager \u003cmail@mwager.de\u003e\n\n\n## TechStack - Overview ##\n\n### App\n\nNative App via Phonegap for iOS and Android. (WebApp served via Node.js)\n\n* Zepto 1.0\n* Require.js\n* Lodash/Backbone.js 1.0.0\n* SocketIO (0.9.x, __not used anymore__)\n* mobiscroll (date \u0026 time scroller)\n* Parts from Html5Boilerplate v4.X\n* Grunt\n* Inspired by the [TodoMVC project](http://todomvc.com) and [Yeoman](http://yeoman.io)\n* Phonegap (v3.x)\n\n### API and Website via Node.js ([at-one-go.com](http://at-one-go.com))\n\n* Express framework (v3)\n* Mongoose (v3)\n* see `api/package.json`\n* Hosting at [OpenShift](http://openshift.com) (free plan)\n\n### Testing\n\n* Mocha: bdd client- and serverside\n* PhantomJS/CasperJS: headless webkit testing\n* testem\n\n### Cordova/Phonegap ###\n\n#### Plugins: ####\n\nInstalliere alle Plugins:\n\nNOTE: To update cordova plugins we need to remove and re-add !\n\n    cordova plugin add org.apache.cordova.console \u0026\u0026 \\\n    cordova plugin add org.apache.cordova.device  \u0026\u0026 \\\n    cordova plugin add org.apache.cordova.dialogs \u0026\u0026 \\\n    cordova plugin add org.apache.cordova.network-information \u0026\u0026 \\\n    cordova plugin add org.apache.cordova.splashscreen \u0026\u0026 \\\n    cordova plugin add org.apache.cordova.statusbar \u0026\u0026 \\\n    cordova plugin add org.apache.cordova.vibration \u0026\u0026 \\\n    cordova plugin add org.apache.cordova.globalization \u0026\u0026 \\\n    cordova plugin add https://github.com/phonegap-build/PushPlugin.git\n\nRemove all:\n\n    cordova plugin rm org.apache.cordova.console \u0026\u0026 \\\n    cordova plugin rm org.apache.cordova.device  \u0026\u0026 \\\n    cordova plugin rm org.apache.cordova.dialogs \u0026\u0026 \\\n    cordova plugin rm org.apache.cordova.network-information \u0026\u0026 \\\n    cordova plugin rm org.apache.cordova.splashscreen \u0026\u0026 \\\n    cordova plugin rm org.apache.cordova.statusbar \u0026\u0026 \\\n    cordova plugin rm org.apache.cordova.vibration \u0026\u0026 \\\n    cordova plugin rm org.apache.cordova.globalization \u0026\u0026 \\\n    cordova plugin rm com.phonegap.plugins.PushPlugin \u0026\u0026 \\\n    rm -rf plugins/ios.json \u0026\u0026 rm plugins/android.json\n\n\n## Relevant directories \u0026 files ##\n\n* __`/app`                    - app sources (yeoman requirejs/backbone boilerplate)__\n* __`/api`                    - node.js sources (REST API, SocketIO, DB, Tests, etc)__\n* `/api_deployment`           - The openshift repo (we just copy the sources from `api` to this directory and push it up to openshift)\n* `/api/server/website`       - Static files of the website at-one-go.com\n* `/api/server/website/app`   - The WebApp will be served from here (optimized sources from `/dist` will be copied to this directory via `make webapp`)\n* __`/api/server/test`        - All backend tests__\n* __`/test`                   - All frontend tests__\n* `/dist`                     - Created via Grunt. The optimized sources will be used in the phonegap app and the webapp\n* `/mobile/`                  - Phonegap project directory (v3.x)\n* `/docs`                     - All software documentation\n\n### Files\n* `Makefile`                  - The Makefile for everything\n* `/app/index.html`           - The base html file for the phonegap app (goes to `/mobile/ios/www/` or `/mobile/android/assets/www/` via Makefile)\n* `/app/webapp.html`          - The base html file for the web app (goes to `api/server/website/app/` via Makefile)\n\n#### Important client side JavaScript files\n* `/app/scripts/config.js`            - The RequireJS config file for development (see also `/app/scripts/config.production.js`)\n* `/app/scripts/main.js`              - The main bootstrapper, all initial event handling (domready/deviceready, global click/touch handlers, global ajax config...)\n* `/app/scripts/router.js`            - The AppRouter, all client side navigation is done via history api (pushstate is on phonegap apps not needed). All routes of the app are defined here, and the router takes care of the rendering of root-views (screens)\n\n\n\n## Local installation ##\n\n#### 1. The App\n\n    $ cd path/to/your/projects\n    $ git clone repo-url.git atonego\n    $ cd atonego\n    # install local build system using grunt [optional]\n    $ npm install\n    # NOTE: The folder `atonego` should be served via a locally installed webserver like apache\n    $ open http://127.0.0.1/atonego # should serve index.html now\n\n__Via phonegap__\n\n$ make ios_build_dev \u0026\u0026 clear \u0026\u0026 t mobile/ios/cordova/console.log\n\nCheckout the `Makefile` for more information.\n\n\n\n#### 2. The API\n\nA RESTful API for the app is written in JavaScript using Node.js, the website at-one-go.com and the webapp will be served through Node.js too.\n\nNOTE: The production config file `api/server/config/environments/production.json` is not under version control.\n\n    $ cd api\n    $ npm install       # install dependencies only once\n    $ mongod \u0026          # start mongodb if not already running\n    $ node server.js    # start the node app in development mode\n\nNow checkout something like:\n\n* [http://127.0.0.1/atonego/app](http://127.0.0.1/atonego/app)\n* [http://127.0.0.1:4000/api](http://127.0.0.1:4000/api)\n* [http://127.0.0.1:4000](http://127.0.0.1:4000/api)\n\n\n\n## Code quality \u0026\u0026 -style ##\n\n### Static code analysis via JSHint (back end \u0026\u0026 front end)\n\n    # in the project root run:\n    $ jshint . # see .jshintrc and .jshintignore\n\n__Before committing, jshint MUST return zero:__\n\n    $ jshint .      # see .jshintrc and .jshintignore\n    $ echo $?       # output 0 ?\n\n    # enable jshint git \"pre-commit\" hook\n    touch .git/hooks/pre-commit \u0026\u0026 chmod +x .git/hooks/pre-commit\n    echo \"jshint .\" \u003e .git/hooks/pre-commit\n\n### Codestyle\n\nInspired from [here](https://github.com/tastejs/todomvc/blob/gh-pages/codestyle.md)\n\n* Space indentation (4)\n* Single-quotes\n* Semicolons\n* Strict mode\n* No trailing whitespace\n* Variables at the top of the scope (where possible)\n* Multiple variable statements\n* Space after keywords and between arguments and operators\n* JSHint valid (see rules in the project root)\n\nExample: (client side using requirejs)\n\n```js\ndefine(function(require) {\n    'use strict';\n\n    var a = require('a'),\n        b = require('b');\n\n    function Foo() {}\n\n    Foo.prototype = {\n        bar: function() {\n            return 'baz';\n        }\n    };\n\n    return Foo;\n});\n```\n\n### Markers\nWe mark problems and todos in the code comments via the marker `XXX` since using the well known marker `TODO` in a todo app seems not to be a good idea.\n\n\n\n\n## Tests ##\n\n### Overview\nAll following commands should run without errors: (all from the project root)\n\n    $ cd api \u0026\u0026 npm test\n    $ testem ci\n    $ casperjs test test/functional\n\n    # there is a command for all of them:\n    $ make all_tests\n\n### API\n\nAll server side unit \u0026 functional tests (bdd style) in: `/api/server/test`.\n\n    $ cd api\n    $ npm test  # mongod running? (possibly in another shell)\n\n### CLIENT\n\nTests in `/test`.\n\n[Quick View of the Testsuite](http://127.0.0.1/atonego/test)\n\nClientside UNIT Tests via `Mocha` and `testem`.\n\nCodeCoverage `/app/scripts` via `Blanket.js`, see Tests in the Browser via `testem`.\n\n    $ cd project_root\n    $ testem      # default mode - Browsers can run the testsuite at http://localhost:7357\n    $ testem ci   # ci mode      - run the suite in all available browsers\n\n_Execute the tests in a simulator or on a device:_\n\n    $ make test_build # copies `/app` und `/test` in mobile's `www` directories\n    # after that, the file config.xml (ios/android) has to be edited:\n\n    \u003ccontent src=\"test/index_browser.html\" /\u003e\n\n    Then just run:\n    $ make ios # build the phonegap app with the current content of `mobile/ios/www`\n    $ make android # same for `mobile/android/assets/www`...\n\n    # shortcuts (config.xml!)\n    $ make test_build \u0026\u0026 make ios\n    $ make test_build \u0026\u0026 make android\n\n\n### Functional tests\n\nTests in `/test/functional` via (casperjs.org)[http://casperjs.org].\n\n    # NOTE: Node and MongoDB must be running locally\n    $ casperjs test test/functional\n\n\n### Continuous Integration - Travis\n\n[![Build Status](https://travis-ci.org/mwager/atonego.png?branch=master)](https://travis-ci.org/mwager/atonego)\n\nSee `.travis.yml` and [the travis page](https://travis-ci.org/mwager/atonego).\n\n\n### Testing/Debugging via weinre\n\nCheckout [weinre](http://people.apache.org/~pmuellr/weinre/docs/latest/)\n\n    # Install \u0026 Run:\n    $ [sudo] npm install -g weinre\n    $ weinre --boundHost 192.168.1.233 --httpPort 8081 --verbose --debug --deathTimeout 60 --readTimeout 60\n    \u003e\u003e\u003e 2013-03-28T11:27:10.401Z weinre: starting server at ...\n\nThen include smt like this in `app/index.html` right after `\u003cbody\u003e`:\n\n    \u003cscript type=\"text/javascript\"\u003e\n    window.onerror = function(e) {\n        alert(e);\n    }\n    \u003c/script\u003e\n    \u003cscript src=\"http://192.168.1.233:8081/target/target-script.js#anonymous\"\u003e\u003c/script\u003e\n\n\nand open [this](http://192.168.1.233:8081/client/#anonymous) page with a browser.\n\n\n\n\n\n## The API, error handling \u0026 multilingualism ##\n\n### Authorization \u0026 Authentication\n\nWe use HTTP Basic auth over SSL everywhere. On login (or signup), a secret API TOKEN gets generated from the user's ID and a random string. This token will be encrypted via AES and sent over to the client. As RESTful APIs should be stateless, each following request must include this token in the `password` field of the `Authorization`-Header to authenticate against the service.\n\nExample:\n\n    Authorization: \"Basic base64encode('$username:$API_TOKEN')\"\n\nNOTE:\n\nWe cannot use custom certs and stuff on the openshift free plan so we cannot determine via node if the incoming request is secure (ssl) or not.\n\n* Helpful Link: [Best Practices for Designing a Pragmatic RESTful API](http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#hateoas)\n* [stackoverflow: Best Practices for securing a REST API](http://stackoverflow.com/questions/7551/best-practices-for-securing-a-rest-api-web-service)\n\n### Texts\n\nThe App __and__ the API/website were developed with support for multilingualism. The following directories include __all__ Texts:\n\n* /app/scripts/libs/locales  -\u003e Texts of the App\n* /api/server/locales        -\u003e Texts of the Website \u0026 API\n\n### Error Handling\n\nModels are always returning the Error as the __first__ parameter in the callback (Node.js-Style, `null` on success), the second parameter can be used as return value, e.g. `callback(null, user)`).\n\n#### Example\n\n    // in a model-method e.g. todolist.fetchList()\n    if (!list) {\n        utils.handleError('damnit some error message'); // optional logging\n        return callback({key: 'listNotFound'});\n    }\n    return callback(err);\n\n    // later: (e.g. in controllers)\n    if(err \u0026\u0026 err.key) {\n        // Error already logged (Log-files)\n        // Usage of key via `__(key)`\n        var text = __(err.key);\n        // `text` is now smt like \"List not found\" or\n        // \"Liste nicht gefunden\" (e.g. based on current request)\n        return displayErrToUserSomehow(text);\n    }\n\n\n\n\n\n## Deployment ##\n\nBe sure to check out the `Makefile` for more infos.\n\n### Deployment of the App via Phonegap\n\nVia PhoneGap for iOS [and Android]. There is a `Makefile` for automating tasks\nlike optimizing the sources or compiling the native Apps via Phonegap.\n\nWe generate __one__ optimized JavaScript file (`aog.js`) via the requirejs optimizer, which will look something [like this](https://atonego-mwager.rhcloud.com/app/scripts/aog.js).\n\n    $ make clean        # clean build directories\n    $ make ios_device   # optimize sources, copy to ios `www` and build\n    $ make ios          # build for ios via phonegap cli tools\n    $ make android      # build for android via phonegap cli tools\n    # NOTE: Shortcuts for running and logging: (phonegap catches \"console.log()\" calls)\n    # We want a clean log file: (running in simulator)\n    # 1. iOS\n    $ echo \"\" \u003e mobile/ios/cordova/console.log \u0026\u0026 make ios_build \u0026\u0026 clear \u0026\u0026 t mobile/ios/cordova/console.log\n    # 2- Android\n    # be sure to connect a real device before running the following one, else the android simulator could screw up your system (-;\n    $ make android_build \u0026\u0026 make android_run \u0026\u0026 clear \u0026\u0026 adb logcat | grep \"Cordova\"\n\n### App Store Submission (iOS)\n\n* [checkout this tutorial first](http://www.adobe.com/devnet/dreamweaver/articles/phonegap-mobile-app-pt7.html#addconfappdist)\n* [apple docs 1](http://developer.apple.com/library/ios/#documentation/ToolsLanguages/Conceptual/YourFirstAppStoreSubmission/AboutYourFirstAppStoreSubmission/AboutYourFirstAppStoreSubmission.html)\n* [creating app record in iTunes connect](http://developer.apple.com/library/ios/#documentation/ToolsLanguages/Conceptual/YourFirstAppStoreSubmission/CreateYourAppRecordiniTunesConnect/CreateYourAppRecordiniTunesConnect.html)\n\nThen just switch \"Run\" and \"Archive\" configs to \"Distribution\" under \"edit scheme...\" in xcode.\n\n### Google Play Store Submission ###\n\n* [see this tutorial](http://www.adobe.com/devnet/dreamweaver/articles/phonegap-mobile-app-pt4.html)\n\n### App Versioning ###\n\nWe use git tags for versioning. However, the file `mobile/www/config.xml` [and `api/package.json` and `AndroidManifest.xml`] should be manually updated on releases.\n\n### Deployment of the API\n\nThe API has its own repository at openshift. (URL: [atonego-mwager.rhcloud.com](https://atonego-mwager.rhcloud.com)) We are using a \"Node.js-Catridge\", default Node-Version is 0.6.x (May 2013), but of course we want a newer version of Node.js, so we also set up this:\n\n[https://github.com/ramr/nodejs-custom-version-openshift](https://github.com/ramr/nodejs-custom-version-openshift)\n\n##### Deploy the Node App to production\n\nNOTE: this requires additional files (see `/.gitignore`).\n\n    # 1. This command will optimize the sources using grunt and copy the generated stuff from `/dist/` to `/api/server/website/app/`:\n    $ make webapp\n\n    # 2. This command copies the sources from `api/*` over to `api_deployment/`\n    # and pushes the stuff from there up to the openshift server.\n    $ make api_deploy\n\n    # restart from cli:\n    $ make api_restart\n\n#### Openshift's CLI Tool \"rhc\"\n\n    # install: (needs ruby)\n    $ gem install rhc\n\n    \u003e rhc app start|stop|restart -a {appName}\n    \u003e rhc cartridge start|stop|restart -a {appName} -c mysql-5.1\n\n    When you do a git push, the app and cartridges do get restarted.  It is best if you can find any indication of why it stopped via your log files.  Feel free to post those if you need any further assistance.\n\n    You can access your logs via ssh:\n    \u003e ssh $UUID@$appURL (use \"rhc domain show\" to find your app's UUID/appURL\n    \u003e cd ~/mysql-5.1/log (log dir for mysql)\n    \u003e cd ~/$OPENSHIFT_APP_NAME/logs (log dir for your app)\n\n    # RESTART DATABASE ONLY:\n    $ rhc cartridge start -a atonego -c rockmongo-1.1\n\n    # RESTART APP ONLY:\n    $ rhc app start -a atonego\n\nFix quota errors at openshift: (https://www.openshift.com/kb/kb-e1089-disk-quota-exceeded-now-what)\n\n    $ ssh ...\n    $ du -h * | sort -rh | head -50\n    $ rm -rf mongodb-2.2/log/mongodb.log*\n    $ rm -rf rockmongo-1.1/logs/*\n    $ echo \"\" \u003e nodejs/logs/node.log\n\n    # and remove the mongodb journal files:\n    $ rm -rf  mongodb/data/journal/*\n\nLocally:\n\n    rhc app tidy atonego\n\n\nopenshift\n\n#### Cronjob:\n\nOn the Production-Server at openshift, there runs a minutely cronjob, checking all todos with notifications, so Email-, PUSH- and SocketIO-messages can be sent to notify users.\n\nSee `api/.openshift/cron/minutely/atonego.sh`\n\nThe cronjob has its own logfile:\n\n    $ ssh ...to openshift....\n    $ tail -f app-root/repo/server/logs/production_cronjob.log\n\n\n### PhoneGap Notes\n\n#### Reading\n* [workflow](http://www.tricedesigns.com/2013/01/18/my-workflow-for-developing-phonegap-applications/)\n* [why apple rejects apps](http://www.adobe.com/devnet/phonegap/articles/apple-application-rejections-and-phonegap-advice.html)\n* [performance1](http://floatlearning.com/2011/03/developing-better-phonegap-apps/)\n* [Youtube video creating IPA file](http://www.youtube.com/watch?v=wAdV16nRLp8)\n\n#### Getting Started\nThe mobile projects were created like this:\n\n* [Phonegap - getting started for iOS](http://docs.phonegap.com/en/2.4.0/guide_getting-started_ios_index.md.html#Getting%20Started%20with%20iOS)\n* [Phonegap - getting started for Android](http://docs.phonegap.com/en/2.4.0/guide_getting-started_android_index.md.html#Getting%20Started%20with%20Android)\n\n1. downloaded: PhoneGap2.x (current 2.9.x `cat mobile/ios/CordovaLib/VERSION`)\n2. created ios and android projects\n\n        $ mkdir mobile \u0026\u0026 cd mobile\n        $ alias create=\"/path/to/phonegap-2.7.0/lib/ios/bin/create\"\n        $ create ios     de.mwager.atonego AtOneGo\n        $ alias create=\"/path/to/phonegap-2.7.0/lib/android/bin/create\"\n        $ create android de.mwager.atonego AtOneGo\n\n\n#### Phonegap-Updates - Workflow: (#update, #upgrade, #phonegap)\n* download latest from phonegap.com\n* checkout guides per platform\n* copy all stuff manually\n* iOS: [check this](http://docs.phonegap.com/en/2.7.0/guide_upgrading_ios_index.md.html)\n\n#### Some links:\n* [Apple Docs - DistributionOnly](https://developer.apple.com/library/ios/#documentation/Xcode/Conceptual/ios_development_workflow/10-Configuring_Development_and_Distribution_Assets/identities_and_devices.html#//apple_ref/doc/uid/TP40007959-CH4-SW1)\n\n#### PUSH Notifications\n\nNOTE: see \"Cronjobs\" und also the demo script: `api_deployment/server/ssl/push_demo.js`\n\n    # run demo script via\n    ### DEBUG=apn node ./api_deployment/server/ssl/push_demo.js\n    DEBUG=apn node ./api/server/push_demo.js\n\nSome links:\n\n* [Phonegap PUSHPlugin at Github](https://github.com/phonegap-build/PushPlugin)\n* [PhonegapPlugins Docs](https://build.phonegap.com/docs/plugins)\n* [see this PUSH Tutorial](http://www.raywenderlich.com/3443/apple-push-notification-services-tutorial-part-12)\n\n\n##### Creating a development push certificate\n\nIn the Apple dev member center:\n\n1. create `development` provisioning profile for app id `de.mwager.atonego`, download and install\n2. create `development` push certificate within the app id `de.mwager.atonego`\n3. download this certificate, open with keychain access, export private key (`.p12` file)\n4. checkout [this PUSH Tutorial](http://www.raywenderlich.com/3443/apple-push-notification-services-tutorial-part-12) to create the certificates for the server\n\nTesting the certificate:\n\n__Note__: use `gateway.sandbox.push.apple.com` in development (same port)\n\n    $ openssl s_client -connect gateway.push.apple.com:2195 -cert api/server/ssl/ck.pem -key api/server/ssl/ck.pem\n    # Output should be smt like:\n    Enter pass phrase for api/server/ssl/ck_dev.pem:\n    ******\n    CONNECTED(00000003)\n    ...\n    Server certificate\n    -----BEGIN CERTIFICATE-----\n    ....\n\n\n##### Node.js and PUSH Notifications\n* [create ssl files](http://www.fasty.de/2011/04/how-to-apple-push-notification-inkl-php-skript/)\n* see `api/server/ssl/push_demo.js` -\u003e sends a push message to hardcoded device token\n\n##### The phonegap's PushPlugin #####\n\nSee the [GitHub Page](https://github.com/phonegap-build/PushPlugin).\n\nInstalled via `plugman`:\n\n    $ cd mobile\n    $ plugman --platform android --project ./platforms/android --plugin https://github.com/phonegap-build/PushPlugin.git\n    $ plugman --platform ios --project ./platforms/ios --plugin https://github.com/phonegap-build/PushPlugin.git\n\n\n## Problems, Solutions, Workarounds, Known Bugs ##\n\n### Performance\n\n1. [check this](http://developer.apple.com/library/ios/#documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/MemoryManagementforYouriOSApp/MemoryManagementforYouriOSApp.html)\n2. [and that](http://coding.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/)\n\n### Underscores in filenames\n\n_Avoid underscores in files and folders because Phonegap may fail to load the\ncontained files in Android. This is a known issue._\n\n\n### Edits\n\n#### Zepto, Backbone\nIn a mobile environment like phonegap, memory management will be much more important than in the web. Variables in the global namespace are not cleaned up by the js engine's garbage collector, so keeping our variables as local as possible is a must.\nTo avoid polluting the global namespace as much as possible, Zepto, Backbone and some other files in `/app/scripts/libs` were edited, see \"atonego\".\n\nLibs which are still global:\n\n* `window._`  -\u003e `/app/scripts/libs/lodash.js`\n* `window.io` -\u003e `/app/scripts/libs/socket.io.js` [not used anymore]\n\n##### Zepto errors\n\nZepto's touch module was edited to prevent lots of strange errors like:\n\n    TypeError: 'undefined' is not an object file:///var/mobile/Applications/XXXXXXXXXX/atonego.app/www/scripts/libs/zepto.js on line 1651\n\nSearch `/app/scripts/lib/zepto.js` for \"atonego\".\n\n\n#### iOS does not allow HTTP Requests against self-signed/invalid certs...\n\nOn iOS devices, there were problemes with the api endpoint at `https://atonego-mwager.rhcloud.com/api`. The following workaround __is necessary__!\n\nThe file `/mobile/ios/atonego/Classes/AppDelegate.m` was edited: (at the bottom)\n\n    @implementation NSURLRequest(DataController)\n    + (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host\n    {\n        return YES;\n    }\n    @end\n\n\n#### ratchet.css \u0026\u0026 junior.js\nThe files `/app/styles/ratchet.css` and `/app/scripts/libs/junior_fork.js` were edited to match our requirements.\n\nThanks to:\n\n* [ratchet project](http://maker.github.io/ratchet/)\n* Some inspiration for rendering Backbone views with nice animations: [junior.js project](http://justspamjustin.github.io/junior)\n\n\n### Disabled attributes \u0026 the `tap` event\n\nThe \"disabled state\" (\"\u0026lt;button ... disabled .../\u003e\") will not be captured. So on every \"tap\" we must check if the element has an disabled attribute or class.\n\n### Ghostclicks\n\nThis is one of the most annoying problems I have ever had. Checkout `main.js` and `router.js` for some workarounds.\n\n* [Google dev blog: Creating Fast Buttons for Mobile Web Applications](https://developers.google.com/mobile/articles/fast_buttons)\n\n### Socket IO\n\n__UPDATE:__ We do not use socket io anymore as its kind of senseless having an open connection in a todo-app. PUSH notifications should be enough. If you want to use websockets via phonegap on iOS, better do not use socketio version 0.9.\n\nThe app always crashed on resume after a (little) longer run. I was about to give up, then I found [this](https://issues.apache.org/jira/browse/CB-2301)\n\nSocketIO's \"auto reconnect\" somehow crashed the app on the iOS test devices (seg fault!). As a workaround I disconnect the websocket connection on Phonegap's `pause`-event, and manually re-connect (using same socket/connection again) on the `resume`-event.\n\nSee also:\n\n* https://github.com/LearnBoost/socket.io-client/pull/426\n\n### Testflight Notes:\n\n* Create the *.IPA file via XCode: check \"iOS device\", then: Product \u003e Archive\n\n### Install the app on a real iOS device via xCode\n\n* Create provisioning profile, download, copy profile via organizer to device , (dblclick installs in xcode first)\n* XCode: update codesigning identity according to the downloaded provisioning profile (project AND target)\n\n### The cronjob\n\nA minutely cronjob runs on the server, checking all todos which are due now, so we can notify users. However, I could not figure out a _good_ solution to re-use my existing (running) node app for this. The current workaround is to listen for a POST to a specific URL, and POSTing to that URL via `curl` from the cronjob with some pseudo credentials set to \"make sure\" that the request came from the shell script, not from outside )-:\n\nSearch `/api/worker.js` -\u003e \"cron\"\n\n\n## Console testing ##\nOpen the app in chrome or safari ([dev](http://127.0.0.1/atonego/app) or [live](https://atonego-mwager.rhcloud.com/app)), then open the dev console and put in some of the following commands to play with the app:\n\n    # as there is (almost) nothing global, we must require stuff first, use this as template:\n    \u003e var $ = require('zepto'), app = require('app'), common = require('common');\n\n    # then try some of these (-:\n    \u003e app.VERSION\n    \u003e app.isMobile\n    \u003e app.changeLang('de') // or app.changeLang('en') if currently in german\n    \u003e app.router.go('help')\n    \u003e window.history.back()\n    \u003e var list = app.todolists.get('object id of list from url or app.todolists');\n    \u003e list.toJSON()\n    // URL: #todolists\n    list.set('title', 'hello world')\n    \u003e app.fetchUser() // watch network tab\n\n    var list = app.todolists.get('get id hash from url');\n    list.set('title', '');\n\n\n\n\n## Todos ##\n\nSee `docs/TODOs.md`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmwager%2Fatonego","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmwager%2Fatonego","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmwager%2Fatonego/lists"}