diff --git a/.gitignore b/.gitignore index 45c1505..e43b0f9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1 @@ -_site -.sass-cache -.jekyll-metadata +.DS_Store diff --git a/404.html b/404.html deleted file mode 100644 index c472b4e..0000000 --- a/404.html +++ /dev/null @@ -1,24 +0,0 @@ ---- -layout: default ---- - - - -
-

404

- -

Page not found :(

-

The requested page could not be found.

-
diff --git a/_posts/2017-02-15-Alway-show-an-Intent-chooser.md b/Android/Alway-show-an-Intent-chooser.md similarity index 83% rename from _posts/2017-02-15-Alway-show-an-Intent-chooser.md rename to Android/Alway-show-an-Intent-chooser.md index a461ca5..1885731 100644 --- a/_posts/2017-02-15-Alway-show-an-Intent-chooser.md +++ b/Android/Alway-show-an-Intent-chooser.md @@ -1,11 +1,4 @@ ---- -layout: post -title: "Alway show an Intent chooser" -date: 2017-02-15 8:37:00 +1000 -categories: android -tags: android ---- - +# Alway show an `Intent` chooser If you want to alway show a chooser dialog, you can create `Intent` using `createChooser()` diff --git a/_posts/2017-9-25-Android-Activity-lifecycle.md b/Android/Android-Activity-lifecycle.md similarity index 100% rename from _posts/2017-9-25-Android-Activity-lifecycle.md rename to Android/Android-Activity-lifecycle.md diff --git a/_posts/2017-2-10-Android-simulator-HAXM-hypervisor-error.md b/Android/Android-simulator-HAXM-hypervisor-error.md similarity index 100% rename from _posts/2017-2-10-Android-simulator-HAXM-hypervisor-error.md rename to Android/Android-simulator-HAXM-hypervisor-error.md diff --git a/_posts/2017-9-28-Android-style-cheat-sheet.md b/Android/Android-style-cheat-sheet.md similarity index 100% rename from _posts/2017-9-28-Android-style-cheat-sheet.md rename to Android/Android-style-cheat-sheet.md diff --git a/_posts/2017-9-8-Use-Dagger2-for-DI.md b/Android/Use-Dagger2-for-DI.md similarity index 86% rename from _posts/2017-9-8-Use-Dagger2-for-DI.md rename to Android/Use-Dagger2-for-DI.md index 8c7bad5..1c72491 100644 --- a/_posts/2017-9-8-Use-Dagger2-for-DI.md +++ b/Android/Use-Dagger2-for-DI.md @@ -1,10 +1,4 @@ ---- -layout: post -title: "Use Dagger 2 for dependency injection" -date: 2017-09-8 8:37:00 +1000 -categories: android -tags: android ---- +# Use Dagger 2 for dependency injection This quote is from Google >Dependency injection frameworks can simplify the code you write and provide an adaptive environment that's useful for testing and other configuration changes. diff --git a/_posts/2017-10-16-android-ci.md b/Android/android-ci.md similarity index 100% rename from _posts/2017-10-16-android-ci.md rename to Android/android-ci.md diff --git a/_posts/2018-1-10-android-questions.md b/Android/android-questions.md similarity index 100% rename from _posts/2018-1-10-android-questions.md rename to Android/android-questions.md diff --git a/_posts/2017-11-15-distribute-views-evenly-linearlayout.md b/Android/distribute-views-evenly-linearlayout.md similarity index 100% rename from _posts/2017-11-15-distribute-views-evenly-linearlayout.md rename to Android/distribute-views-evenly-linearlayout.md diff --git a/Android/enable-emulator-keyboard.md b/Android/enable-emulator-keyboard.md new file mode 100644 index 0000000..f25cbf6 --- /dev/null +++ b/Android/enable-emulator-keyboard.md @@ -0,0 +1,3 @@ +# Enable Android emulator keyboard + +[https://stackoverflow.com/a/30327728](https://stackoverflow.com/a/30327728) \ No newline at end of file diff --git a/_posts/2017-9-7-gradle-daemon-error.md b/Android/gradle-daemon-error.md similarity index 82% rename from _posts/2017-9-7-gradle-daemon-error.md rename to Android/gradle-daemon-error.md index 752549e..44fc93b 100644 --- a/_posts/2017-9-7-gradle-daemon-error.md +++ b/Android/gradle-daemon-error.md @@ -1,10 +1,4 @@ ---- -layout: post -title: "Gradle damon error" -date: 2017-09-7 8:37:00 +1000 -categories: android -tags: android ---- +# Gradle damon error You can solve the below issue by adding `org.gradle.jvmargs=-Xmx1024m` in `gradle.properties` file. diff --git a/_posts/2017-9-19-gradle-project-sync-failed.md b/Android/gradle-project-sync-failed.md similarity index 100% rename from _posts/2017-9-19-gradle-project-sync-failed.md rename to Android/gradle-project-sync-failed.md diff --git a/_posts/2017-9-27-layout-cheat-sheet.md b/Android/layout-cheat-sheet.md similarity index 100% rename from _posts/2017-9-27-layout-cheat-sheet.md rename to Android/layout-cheat-sheet.md diff --git a/_posts/2017-10-26-vector-asset-support.md b/Android/vector-asset-support.md similarity index 100% rename from _posts/2017-10-26-vector-asset-support.md rename to Android/vector-asset-support.md diff --git a/Cloud/aws-ec2-disk-full.md b/Cloud/aws-ec2-disk-full.md new file mode 100644 index 0000000..1786cf6 --- /dev/null +++ b/Cloud/aws-ec2-disk-full.md @@ -0,0 +1,9 @@ +# Amazon EC2 - disk full + +When you run `df`, the output is `/dev/xvda1 100% /`. It means the disk space is full. You can use the following command to find big size files. + +``` + sudo find / -type f -size +100M -exec ls -lh {} \; +``` + +Reference:[http://stackoverflow.com/questions/20031604/amazon-ec2-disk-full](http://stackoverflow.com/questions/20031604/amazon-ec2-disk-full) diff --git a/Cloud/aws-lambda-read-config-file.md b/Cloud/aws-lambda-read-config-file.md new file mode 100644 index 0000000..d8d3ddb --- /dev/null +++ b/Cloud/aws-lambda-read-config-file.md @@ -0,0 +1,18 @@ +# AWS lambda Java read config file + +1. Put the config file under `src/main/resources` + +2. Read the config file using the code below + +```java +InputStream is = WobCredentials.class.getResourceAsStream(serviceAccountPrivateKeyPath); + String content = convertStreamToString(is); + JSONObject privateKeyJson = new JSONObject(content); + + String convertStreamToString(java.io.InputStream is) { + java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A"); + return s.hasNext() ? s.next() : ""; + } +``` + +Reference: [https://stackoverflow.com/questions/35356200/how-to-load-property-file-from-classpath-in-aws-lambda-java](https://stackoverflow.com/questions/35356200/how-to-load-property-file-from-classpath-in-aws-lambda-java) diff --git a/Cloud/aws-policy-generator.md b/Cloud/aws-policy-generator.md new file mode 100644 index 0000000..d9c5a50 --- /dev/null +++ b/Cloud/aws-policy-generator.md @@ -0,0 +1,7 @@ +# AWS Policy generator + +[AWS Policy generator](https://awspolicygen.s3.amazonaws.com/policygen.html) + + +[IAM policy simulator](https://policysim.aws.amazon.com) + diff --git a/Cloud/serverless-commands.md b/Cloud/serverless-commands.md new file mode 100644 index 0000000..147b498 --- /dev/null +++ b/Cloud/serverless-commands.md @@ -0,0 +1,12 @@ +# Some userful serverless commands + +* `sls invoke local -f funcName` + +* `sls deploy -f funcName` + +* `sls offline start` + +* `sls dynamodb install` + +* `sls deploy --aws-profile profileName` + diff --git a/Cloud/serverless-function-6-seconds-timeout.md b/Cloud/serverless-function-6-seconds-timeout.md new file mode 100644 index 0000000..b278b1a --- /dev/null +++ b/Cloud/serverless-function-6-seconds-timeout.md @@ -0,0 +1,28 @@ +# Serverless function 6 seconds timeout + +Serverless set a Lamdba function timeout to 6.00 seconds, If you didn't write timeout statement in serverless.yml. + + +```yml +# serverless.yml +service: myService + +provider: + name: aws + runtime: nodejs6.10 + memorySize: 512 # optional, in MB, default is 1024 + timeout: 10 # optional, in seconds, default is 6 + versionFunctions: false # optional, default is true + +functions: + hello: + handler: handler.hello # required, handler set in AWS Lambda + name: ${self:provider.stage}-lambdaName # optional, Deployed Lambda name + description: Description of what the lambda function does # optional, Description to publish to AWS + runtime: python2.7 # optional overwrite, default is provider runtime + memorySize: 512 # optional, in MB, default is 1024 + timeout: 10 # optional, in seconds, default is 6 +``` + +Reference: [https://github.com/serverless/serverless/issues/2640](https://github.com/serverless/serverless/issues/2640) + diff --git a/Cloud/serverless-s3-exits-error.md b/Cloud/serverless-s3-exits-error.md new file mode 100644 index 0000000..ce93fee --- /dev/null +++ b/Cloud/serverless-s3-exits-error.md @@ -0,0 +1,25 @@ +# Serverless S3 bucket exists error + +To solve this issue there are two steps: + +1. remove s3 reference from events +2. add CORS configruation as below: + + ```yaml + resources: + Resources: + S3BucketMyBucket: + Type: AWS::S3::Bucket + Properties: + BucketName: bucketname-${self:provider.stage} + CorsConfiguration: + CorsRules: + - AllowedHeaders: + - "*" + AllowedMethods: + - GET + - POST + - PUT + AllowedOrigins: + - "*" + ``` diff --git a/Docker/Docker-insecure-registry.md b/Docker/Docker-insecure-registry.md new file mode 100644 index 0000000..ea45056 --- /dev/null +++ b/Docker/Docker-insecure-registry.md @@ -0,0 +1,3 @@ +# Docker insecure registry + +[Test an insecure registry](https://docs.docker.com/registry/insecure/) diff --git a/Docker/Docker.qcow2-disk-space-issue-on-Mac.md b/Docker/Docker.qcow2-disk-space-issue-on-Mac.md new file mode 100644 index 0000000..7db1cde --- /dev/null +++ b/Docker/Docker.qcow2-disk-space-issue-on-Mac.md @@ -0,0 +1,12 @@ +# Docker.qcow2 disk space issue on Mac + +I found `Docker.qcow2` uses 28G on my mac. I solve this issue using the commands below. + +```script + docker rm $(docker ps -a -q) + docker rmi $(docker images -q) + docker volume rm $(docker volume ls |awk '{print $2}') + rm -rf ~/Library/Containers/com.docker.docker/Data/* +``` + +Reference: [https://github.com/docker/for-mac/issues/371](https://github.com/docker/for-mac/issues/371) diff --git a/Docker/Manage-different-docker-versions.md b/Docker/Manage-different-docker-versions.md new file mode 100644 index 0000000..b0683b8 --- /dev/null +++ b/Docker/Manage-different-docker-versions.md @@ -0,0 +1,11 @@ +# Manage different docker versions + +When you try to manage different docker container using docker-machine, it is impossible to manage them on one machine as those docker demons may have different docker versions. One solution is to use one docker container to manage one docker version containers. + +1. Get a docker container from docker hub + + `docker run --name mysites -it nootfly/ubuntu_docker` + +2. Install specific version docker:[Reference](https://docs.docker.com/engine/installation/linux/ubuntulinux/) + + `sudo apt-get install docker-engine=1.12.0-0~xenial` diff --git a/Docker/Move-docker-machine-config.md b/Docker/Move-docker-machine-config.md new file mode 100644 index 0000000..8c2ef10 --- /dev/null +++ b/Docker/Move-docker-machine-config.md @@ -0,0 +1,5 @@ +# Move docker-machine config to another machine + +1. Move `~/.docker/machine` directory to another machine's the same directory + +2. Update all machine's `config.json` files under `~/.docker/machine/machines/`, the purpose is to update ssh key and cert path. diff --git a/Docker/docker-commands.md b/Docker/docker-commands.md new file mode 100644 index 0000000..b9eab4d --- /dev/null +++ b/Docker/docker-commands.md @@ -0,0 +1,43 @@ +# docker commands + +* run a ubuntu image + + `docker run -i -t ubuntu /bin/bash` + +* go into a running container + + `docker exec -i -t containerName /bin/bash` + +* resolve "The default lines below are for a sh/bash shell, you can specify the shell you're using, with the --shell flag." error to use this command + + `eval $(docker-machine env docker-sandbox --shell bash)` + +* create a volume + + `docker run --name mysites -v /Users/noot/docker/data:/data -it nootfly/docker1.1.2` + +* commit a container + + `docker commit 1ff9c95fdc30 nootfly/docker1.1.2` + +* docker-machine configures at the start of each shell session + + `eval $(docker-machine env docker-sandbox)` + +* docker saves an image to a tar + + `docker save -o ~/container1.tar container1` + +* docker recovery an image from a tar + + `docker load -i /root/container1.tar` + +* rename docker container + + `docker rename CONTAINER NEW_NAME` + +* copy files from the container to the host + + `docker cp :/file/path/within/container /host/path/target` + +* [Removing Docker containers and images](https://zaiste.net/posts/removing_docker_containers/) diff --git a/Docker/docker-compose-node-link-mongo.md b/Docker/docker-compose-node-link-mongo.md new file mode 100644 index 0000000..8d89937 --- /dev/null +++ b/Docker/docker-compose-node-link-mongo.md @@ -0,0 +1,38 @@ +# docker-compose node link mongo + +1. Create a `Dockerfile` + + ``` + FROM node:6.9.4-alpine + ADD . /usr/src/app + WORKDIR /usr/src/app + RUN npm install + CMD ["npm", "start"] + ``` +2. Create `docker-compose.yaml`, and pay attention to the service names which should not include `_`. + + ``` + version: '2.1' + services: + mongodbservice: + container_name: mongo + image: mongo + ports: + - "27017:27017" + volumes: + - ./db:/data/db + web: + container_name: web + build: . + depends_on: + - mongodbservice + volumes: + - ./:/usr/src/app + links: + - mongodbservice + ports: + - "3000:3000" + ``` +3. In code, use the correct mongodb URL + + `let mongodb = mongojs('mongodb://mongodbservice:27017/Test', ['test']);` diff --git a/Docker/nginx-log-conf.md b/Docker/nginx-log-conf.md new file mode 100644 index 0000000..8be05f6 --- /dev/null +++ b/Docker/nginx-log-conf.md @@ -0,0 +1,10 @@ +# Docker nginx log configuration + +If you use ```nginx``` docker offical image, the nginx logs point to ```stderr``` and ```stdout```. You need to keep logs into different files, otherwise the logs won't be saved. For example: + +``` +http { + access_log /var/log/nginx/access1.log; + error_log /var/log/nginx/error1.log; +} +``` diff --git a/Docker/sudo-docker.md b/Docker/sudo-docker.md new file mode 100644 index 0000000..a0657b9 --- /dev/null +++ b/Docker/sudo-docker.md @@ -0,0 +1,5 @@ +# sudo docker + +how to remove sudo + +http://askubuntu.com/questions/477551/how-can-i-use-docker-without-sudo diff --git a/Gemfile b/Gemfile deleted file mode 100644 index 99324d5..0000000 --- a/Gemfile +++ /dev/null @@ -1,32 +0,0 @@ -source "https://rubygems.org" - -# Hello! This is where you manage which Jekyll version is used to run. -# When you want to use a different version, change it below, save the -# file and run `bundle install`. Run Jekyll with `bundle exec`, like so: -# -# bundle exec jekyll serve -# -# This will help ensure the proper Jekyll version is running. -# Happy Jekylling! -gem "jekyll", "~> 3.7.3" - -# This is the default theme for new Jekyll sites. You may change this to anything you like. -gem "minima", "~> 2.0" - -# If you want to use GitHub Pages, remove the "gem "jekyll"" above and -# uncomment the line below. To upgrade, run `bundle update github-pages`. -# gem "github-pages", group: :jekyll_plugins - -# If you have any plugins, put them here! -group :jekyll_plugins do - gem "jekyll-feed", "~> 0.6" -end - -# Windows does not include zoneinfo files, so bundle the tzinfo-data gem -gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby] - -# Performance-booster for watching directories on Windows -gem "wdm", "~> 0.1.0" if Gem.win_platform? - -gem 'jekyll-tagging' - diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 387a4ae..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,78 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - addressable (2.5.2) - public_suffix (>= 2.0.2, < 4.0) - colorator (1.1.0) - concurrent-ruby (1.0.5) - em-websocket (0.5.1) - eventmachine (>= 0.12.9) - http_parser.rb (~> 0.6.0) - eventmachine (1.2.5) - ffi (1.9.23) - forwardable-extended (2.6.0) - http_parser.rb (0.6.0) - i18n (0.9.5) - concurrent-ruby (~> 1.0) - jekyll (3.7.3) - addressable (~> 2.4) - colorator (~> 1.0) - em-websocket (~> 0.5) - i18n (~> 0.7) - jekyll-sass-converter (~> 1.0) - jekyll-watch (~> 2.0) - kramdown (~> 1.14) - liquid (~> 4.0) - mercenary (~> 0.3.3) - pathutil (~> 0.9) - rouge (>= 1.7, < 4) - safe_yaml (~> 1.0) - jekyll-feed (0.9.3) - jekyll (~> 3.3) - jekyll-sass-converter (1.5.2) - sass (~> 3.4) - jekyll-seo-tag (2.4.0) - jekyll (~> 3.3) - jekyll-tagging (1.1.0) - nuggets - jekyll-watch (2.0.0) - listen (~> 3.0) - kramdown (1.16.2) - liquid (4.0.0) - listen (3.1.5) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - ruby_dep (~> 1.2) - mercenary (0.3.6) - minima (2.4.1) - jekyll (~> 3.5) - jekyll-feed (~> 0.9) - jekyll-seo-tag (~> 2.1) - nuggets (1.5.0) - pathutil (0.16.1) - forwardable-extended (~> 2.6) - public_suffix (3.0.2) - rb-fsevent (0.10.3) - rb-inotify (0.9.10) - ffi (>= 0.5.0, < 2) - rouge (3.1.1) - ruby_dep (1.5.0) - safe_yaml (1.0.4) - sass (3.5.6) - sass-listen (~> 4.0.0) - sass-listen (4.0.0) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - -PLATFORMS - ruby - -DEPENDENCIES - jekyll (~> 3.7.3) - jekyll-feed (~> 0.6) - jekyll-tagging - minima (~> 2.0) - tzinfo-data - -BUNDLED WITH - 1.16.1 diff --git a/Go/Upgrade-go-to-1.6.md b/Go/Upgrade-go-to-1.6.md new file mode 100644 index 0000000..6b5fa6f --- /dev/null +++ b/Go/Upgrade-go-to-1.6.md @@ -0,0 +1,6 @@ +# Upgrade go to 1.6 + +If Go was installed by `brew`, you want to upgrade to go 1.6. The first thing is to uninstall go by `brew` and run the command. +``` +brew uninstall go +``` \ No newline at end of file diff --git a/Javascript/Atom-run-javascript.md b/Javascript/Atom-run-javascript.md new file mode 100644 index 0000000..ff5838b --- /dev/null +++ b/Javascript/Atom-run-javascript.md @@ -0,0 +1,5 @@ +# Run JavaScript in Atom + +1. intall `script` package +`apm install script` +2. `cmd + i` run script on Mac diff --git a/Javascript/JSFiddle-console.md b/Javascript/JSFiddle-console.md new file mode 100644 index 0000000..c2053dd --- /dev/null +++ b/Javascript/JSFiddle-console.md @@ -0,0 +1,3 @@ +# JSFiddle console.log + +http://stackoverflow.com/a/22989862/1146834 diff --git a/Javascript/Webpack-errors.md b/Javascript/Webpack-errors.md new file mode 100644 index 0000000..cc4b783 --- /dev/null +++ b/Javascript/Webpack-errors.md @@ -0,0 +1,18 @@ +# Webpack errors + +1. Error: Cannot find module 'webpack' + + ``` + npm install --save-dev webpack + ``` + +2. configuration.output.path: The provided value "dist/assets" is not an absolute path! + To solve this issue, you can add `__dirname` to a ouput path. + + ``` + output: { + path: __dirname + "dist/assets", + filename: "bundle.js", + sourceMapFilename: 'bundle.map' + } + ``` diff --git a/Javascript/es6-cheat-sheet.md b/Javascript/es6-cheat-sheet.md new file mode 100644 index 0000000..bbb7947 --- /dev/null +++ b/Javascript/es6-cheat-sheet.md @@ -0,0 +1,99 @@ +# ES6 cheat sheet + +1. Unlike variables declared with var that are function-scoped, variables declared with let are block-scoped: they only exist in the block they are defined in. + +2. In the Chrome Development Tool > Network > Disable Cache + +3. Modules have been available in JavaScript through third-party libraries. ECMAScript 6 adds native support for modules to JavaScript. When you compile a modular ECMAScript 6 application to ECMASCript 5, the compiler relies on a third party library to implement modules in ECMAScript 5. Webpack and Browserify are two popular options, and Babel supports both (and others). + +4. The ECMAScript 6 arrow function syntax is a shorthand for the ECMAScript 5 function syntax. It supports both block and expression bodies. The value of this inside the function is not altered: it is the same as the value of this outside the function. No more var self = this to keep track of the current scope. + +5. Current browsers don’t support all the new ECMAScript 6 (aka ECMAScript 2015) features yet (see comptability table). You need to use a compiler (transpiler) to transform your ECMAScript 6 code to ECMAScript 5 compatible code. Although there are other options, Babel has become the de-facto standard to compile ECMAScript 6 applications to a version of ECMAScript that can run in current browsers. Babel can also compile other versions of ECMAScript as well as React’s JSX. + +6. Promises have replaced callback functions as the preferred programming style for handling asynchronous calls. A promise is a holder for a result (or an error) that will become available in the future (when the async call returns). Promises have been available in JavaScript through third-party libraries (for example, jQuery and q). ECMAScript 6 adds built-in support for promises to JavaScript. + +7. What you know as JavaScript in browsers and in Node.js is actually a superset of ECMAScript + +8. Bindings declared using const are considered constants, meaning their values cannot be changed once set. + +9. Constants, like let declarations, are block-level declarations. That means constants are no longer accessible once execution flows out of the block in which they were declared, and declarations are not hoisted. + +10. The value a constant holds can be modified if it is an object. `const` prevents modification of the binding, not modification of the bound value. + +11. Use const by default, and only use let when you know a variable’s value needs to change. + +12. ECMAScript 6 supports Unicode normalization forms by giving strings a `normalize()` method. + +13. ECMAScript 6 adds `includes()`, `startsWith()`, `endsWith()` and `repeat()` method to strings. + +14. A template tag performs a transformation on the template literal and returns the final string value. This tag is specified at the start of the template. + +15. Rest parameters have two restrictions. The first restriction is that there can be only one rest parameter, and the rest parameter must be last. The second restriction is that rest parameters cannot be used in an object literal setter. + +16. All functions in an ECMAScript 6 program will have an appropriate value for their name property. + +17. JavaScript has two different internal-only methods for functions: [[Call]] and [[Construct]]. When a function is called without new, the [[Call]] method is executed, which executes the body of the function as it appears in the code. When a function is called with new, that’s when the [[Construct]] method is called. + +18. ECMAScript 6 introduces the new.target metaproperty. A metaproperty is a property of a nonobject that provides additional information related to its target (such as new). + +19. Block-level functions are hoisted to the top of the block in which they are defined. + +20. But arrow functions behave differently than traditional JavaScript functions in a number of important ways: 1. No this, super, arguments, and new.target bindings 2. Cannot be called with new 3. No prototype 4. Can’t change this 5. No arguments object 6. No duplicate named parameters. + +21. Even though there is no explicit return statement, this arrow function will return the first argument that is passed in. + +22. Think about tail call optimization whenever you’re writing a recursive function, because it can provide a significant performance improvement, especially when applied in a computationally expensive function. + +23. When an object property name is the same as the local variable name, you can simply include the name without a colon and value. + +24. ECMAScript 6 introduces the `Object.is()` method to remedy the remaining inaccuracies of the identically equals operator. + +25. It’s now possible to modify an object’s prototype after it’s been created thanks to ECMAScript 6’s Object.setPrototypeOf() method. + +26. When you’re using destructuring to declare variables using var, let, or const, you must supply an initializer (the value after the equal sign). + +27. In ECMAScript 6, you can use rest items to clone an array. + +28. ECMAScript 6 introduces symbols as a primitive type. (The language already had five primitive types: strings, numbers, Booleans, null, and undefined. + +29. ECMAScript 6 introduces symbols as a primitive type. (The language already had five primitive types: strings, numbers, Booleans, null, and undefined. + +30. ECMAScript 6 added sets and maps to JavaScript. + +31. Keep in mind that although sets are great for tracking values and forEach() lets you work on each item sequentially, you can’t directly access an item by index like you can with an array. If you need to do so, the best option is to convert the set to an array. + +32. Converting an array to a set is easy because you can pass the array to the Set constructor; converting a set back to an array is also easy if you use the spread operator (...). + +33. ECMAScript 6 also includes weak sets, which only store weak object references and cannot store primitive values. A weak reference to an object doesn’t prevent garbage collection if it’s the only remaining reference. + +34. Keep in mind that an error will be thrown if the array contains any nonobject values, because WeakSet can’t accept primitive values. + +35. You can initialize a map with data by passing an array to the Map constructor. Each item in the array must itself be an array where the first item is the key and the second is that key’s corresponding value. Therefore, the entire map is an array of these two-item arrays. + +36. It’s best to use weak sets only for tracking objects that need to be grouped together. + +37. Generator functions are indicated by an asterisk character (*) after the function keyword and use the new yield keyword. + +38. The for-of statement will throw an error when you use it on a non-iterable object, null, or undefined. + +39. The spread operator and `for-of` ignore any value specified by a return statement. As soon as they see done is true, they stop without reading the value. However, iterator return values are helpful when delegating generators. + +40. Class declarations and class expressions are not hoisted. + +41. Classes that inherit from other classes are referred to as derived classes. Derived classes require you to use `super()` if you specify a constructor; if you don’t, an error will occur. You must call `super()` before accessing this in the constructor. Because `super()` is responsible for initializing this, attempting to access this before calling `super()` results in an error. The only way to avoid calling `super()` is to return an object from the class constructor. + +42. An internal [[PromiseState]] property is set to "pending", "fulfilled", or "rejected" to reflect the promise’s state. This property isn’t exposed on promise objects, so you can’t determine which state the promise is in programmatically. But you can take a specific action when a promise changes state by using the then() method. + +43. Prototype proxy traps have some restrictions. First, the getPrototypeOf trap must return an object or null, and any other return value results in a runtime error. The return value check ensures that Object.getPrototypeOf() will always return an expected value. Second, the return value of the setPrototypeOf trap must be false if the operation doesn’t succeed. When setPrototypeOf returns false, Object.setPrototypeOf() throws an error. If setPrototypeOf returns any value other than false, Object.setPrototypeOf() assumes the operation succeeded. + +44. You can use the ownKeys trap to, for example, filter out certain property keys that you don’t want used when the Object.keys() method, the Object.getOwnPropertyNames() method, the Object.getOwnPropertySymbols() method, or the Object.assign() method is used. + +45. Using a combination of proxy traps and reflection API methods, it’s possible to filter some operations to behave differently only in certain conditions while defaulting to the built-in behavior. + +46. A module is JavaScript code that automatically runs in strict mode with no way to opt out. Keep in mind that no matter how many times you use a module in import statements, the module will execute only once. Keep in mind that the default must come before the non-defaults in the import statement. Imports without bindings are most likely to be used to create polyfills and shims. + + +Reference: + +* [ECMAScript 6 Tutorial](http://ccoenraets.github.io/es6-tutorial/) +* Understanding ECMAScript 6 diff --git a/Javascript/mongojs-aggregate.md b/Javascript/mongojs-aggregate.md new file mode 100644 index 0000000..84a33da --- /dev/null +++ b/Javascript/mongojs-aggregate.md @@ -0,0 +1,17 @@ +# mongojs aggregate + +This example is to aggregate records with the same `memberId` and date. The return json group filed name must `_id`. + + ```javascript + var findQuery = {memberId:req.params.id}; + mongodb.tierPoints.aggregate([ + { $match: findQuery }, + {$group: { _id: { $substr: ["$updateDate",0, 10] } + , total: { $sum: "$changeAmount" } + }} ],function(err, points){ + if(err){ + res.send(err); + } + res.json(points); + }); + ``` diff --git a/Javascript/nodejs-authentication.md b/Javascript/nodejs-authentication.md new file mode 100644 index 0000000..1a3a0ce --- /dev/null +++ b/Javascript/nodejs-authentication.md @@ -0,0 +1,14 @@ +# Nodejs server api authentication + +1. Basic authentication + + `npm install basic-auth` + +2. [Passport](http://www.passportjs.org/) is a piece of authentication middleware for Node.js + + ``` + npm install passport + npm install passport-http + ``` + + \ No newline at end of file diff --git a/Javascript/nodejs-debug-object.md b/Javascript/nodejs-debug-object.md new file mode 100644 index 0000000..a056524 --- /dev/null +++ b/Javascript/nodejs-debug-object.md @@ -0,0 +1,3 @@ +# nodejs debug object + +`console.dir(req.body, { depth: null });` diff --git a/Javascript/npm-semver.md b/Javascript/npm-semver.md new file mode 100644 index 0000000..fe79166 --- /dev/null +++ b/Javascript/npm-semver.md @@ -0,0 +1,11 @@ +# Semver for consumers + +As a consumer, you can specify which kinds of updates your app can accept in the package.json file. + +If you were starting with a package 1.0.4, this is how you would specify the ranges: + +Patch releases: 1.0 or 1.0.x or ~1.0.4 +Minor releases: 1 or 1.x or ^1.0.4 +Major releases: * or x + +Reference: [https://docs.npmjs.com/getting-started/semantic-versioning](https://docs.npmjs.com/getting-started/semantic-versioning) \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4875fef --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Noot + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Linux/Bash-commands.md b/Linux/Bash-commands.md new file mode 100644 index 0000000..1c68768 --- /dev/null +++ b/Linux/Bash-commands.md @@ -0,0 +1,20 @@ +# Bash commands + +* `ctrl-r` - reverse search history + +* `ctrl-a` - move the cursor to the beginning + +* `ctrl-e` - move the cursor to the Extending + +* `pbcopy` / `pbpaste` - copy to your system clipboard or paste from your system clipboard + +* `ctrl-b` - move the cursor back one character + +* `ctrl-f` - move the cursor forward one character + +* `ctrl-l` - clear the screen + + +[reference 1](http://teohm.com/blog/shortcuts-to-move-faster-in-bash-command-line/) + +[reference 2](https://www.blockloop.io/mastering-bash-and-terminal) diff --git a/Linux/Ubuntu-commands.md b/Linux/Ubuntu-commands.md new file mode 100644 index 0000000..028a879 --- /dev/null +++ b/Linux/Ubuntu-commands.md @@ -0,0 +1,28 @@ +# Ubuntu commands + +* Check ubuntu version + If `lsb_release -a` does not work, you can use `cat /etc/*-release`. + +* Create ssh keys + + `ssh-keygen -t rsa` + +* Copy public key to a remote server + + `ssh-copy-id dockeradmin@remote-server` + +* Upgrade git version (http://askubuntu.com/questions/568591/how-do-i-install-the-latest-version-of-git-with-apt) + + ``` + sudo apt-add-repository ppa:git-core/ppa + sudo apt-get update + sudo apt-get install git + ``` + +* Install ping + + `apt-get install iputils-ping` + +* Copy SSH key to clipboard + + `pbcopy < ~/.ssh/id_rsa.pub` diff --git a/Linux/run-cd-in-a-shell-script.md b/Linux/run-cd-in-a-shell-script.md new file mode 100644 index 0000000..cf67710 --- /dev/null +++ b/Linux/run-cd-in-a-shell-script.md @@ -0,0 +1,6 @@ +# Run cd in a shell script + +The `cd` is done within the script's shell. When the script ends, that shell exits, and then you are left in the directory you were. So you run script `. yourscript.sh` by adding `.`. + + +Reference: [http://stackoverflow.com/a/2236614/1146834](http://stackoverflow.com/a/2236614/1146834) diff --git a/Linux/sudo-cd.md b/Linux/sudo-cd.md new file mode 100644 index 0000000..9dcec7d --- /dev/null +++ b/Linux/sudo-cd.md @@ -0,0 +1,5 @@ +# sudo cd + +`sudo cd` does not work because the `cd` command is built into the shell. You can use `sudo -i` to open root console and then `cd`. + +Reference: [http://askubuntu.com/questions/57789/how-to-enter-to-the-directory-with-cd-command-if-it-has-700-permission](http://askubuntu.com/questions/57789/how-to-enter-to-the-directory-with-cd-command-if-it-has-700-permission) diff --git a/ML/install-tensorflow-error.md b/ML/install-tensorflow-error.md new file mode 100644 index 0000000..b7dc6a0 --- /dev/null +++ b/ML/install-tensorflow-error.md @@ -0,0 +1,4 @@ +# install tensorflow error + +When you install tensorflow using `pip install tensorflow` and see `Invalid requirement: 'tensorflow'`error, +you can run `sudo easy_install --upgrade six` to resolve this issue. diff --git a/Mac/Resize-off-screen-window.md b/Mac/Resize-off-screen-window.md new file mode 100644 index 0000000..cfa498c --- /dev/null +++ b/Mac/Resize-off-screen-window.md @@ -0,0 +1,4 @@ +#Resize off screen window + +The tip is from https://www.tekrevue.com/tip/resize-off-screen-window-in-mac-os-x/ +> Simply select your desired application to make it active by click on its icon in the Dock (you should see the application's name in the top-left corner of your OS X Menu Bar, next to the Apple logo). Then, also in the Menu Bar, click the word Window and then Zoom. diff --git a/Mac/nscurl.md b/Mac/nscurl.md new file mode 100644 index 0000000..d9b7824 --- /dev/null +++ b/Mac/nscurl.md @@ -0,0 +1,9 @@ +# nscurl + +The nscurl tool on OS X El Capitan supports diagnosing ATS secure connections. The below shows that it will display ATS connection information for www.example.com. Reference: https://forums.developer.apple.com/thread/14816 + + + +``` +/usr/bin/nscurl --ats-diagnostics https://www.example.com +``` diff --git a/Others/Gmail-alias.md b/Others/Gmail-alias.md new file mode 100644 index 0000000..d242a72 --- /dev/null +++ b/Others/Gmail-alias.md @@ -0,0 +1,8 @@ +# Gmail alias + +You can use many alias for your gmail account, for example, emails sent to the following alias will go to okok@gmail.com: +* okok+work@gmail.com +* okok+notes@gmail.com +* okok+shopping@gmail.com + +You do not do any setting for this alias function. diff --git a/Others/letsencrypt-certificate.md b/Others/letsencrypt-certificate.md new file mode 100644 index 0000000..c8c8ce8 --- /dev/null +++ b/Others/letsencrypt-certificate.md @@ -0,0 +1,48 @@ +# letsencrypt certificate + +1. Use this docker command generate a SSL certificate, you can choose option 2 after you run this command. + + ```shell + docker run -it --rm -p 443:443 -p 80:80 --name certbot \ + -v "/etc/letsencrypt:/etc/letsencrypt" \ + -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \ + quay.io/letsencrypt/letsencrypt:latest auth --server https://acme-v01.api.letsencrypt.org/directory \ + --debug --renew-by-default --standalone-supported-challenges http-01 \ + --verbose -d yourdomain --text --agree-tos --email youremail@gmail.com + ``` + +2. Config nginx + + + ``` + server { + listen 80; + server_name yourdomain; + + return 301 https://$host$request_uri; + } + + server { + listen 443 ssl; + server_name yourdomain; + + ssl_certificate /etc/letsencrypt/live/yourdomain/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/yourdomain/privkey.pem; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; + ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES"; + + + location / { + proxy_pass http://site2/; + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $server_name; + } + } + upstream site2 { + server site2:8081; + } + ``` diff --git a/Others/technique-interview-websites.md b/Others/technique-interview-websites.md new file mode 100644 index 0000000..60bb6ba --- /dev/null +++ b/Others/technique-interview-websites.md @@ -0,0 +1,9 @@ +#Preparing technical coding interviews websites + +* LeetCode(https://leetcode.com/) + +* HackerRank(https://www.hackerrank.com/) + +* Grassdoor(https://www.glassdoor.com.au) + +* Careercup(https://www.careercup.com/) diff --git a/Python/Python-resources.md b/Python/Python-resources.md new file mode 100644 index 0000000..4d1e079 --- /dev/null +++ b/Python/Python-resources.md @@ -0,0 +1,4 @@ +#Python resources + +1. Python IDE - LiClipse http://www.liclipse.com/ +2. "Python for Data Analysis" - sample code https://github.com/wesm/pydata-book diff --git a/Python/docker-jupyter-notebook.md b/Python/docker-jupyter-notebook.md new file mode 100644 index 0000000..fd07630 --- /dev/null +++ b/Python/docker-jupyter-notebook.md @@ -0,0 +1,15 @@ +# run Jupyter in a docker container + +1. `sudo chown 1000 hostdir` + +2. `docker run -d -p 8888:8888 -v hostdir:/home/jovyan/work jupyter/scipy-notebook` + +3. `docker exec -it container_id /bin/bash` + +4. Run `jupyter notebook list` to get a url with a token + +5. Change the port of the url to the running container's open port and open the url in a browser + + +Reference: +[https://hub.docker.com/r/jupyter/scipy-notebook/](https://hub.docker.com/r/jupyter/scipy-notebook/) diff --git a/Python/python-tutorial.md b/Python/python-tutorial.md new file mode 100644 index 0000000..76eaf64 --- /dev/null +++ b/Python/python-tutorial.md @@ -0,0 +1,3 @@ +# Python tutorial + +* [http://cs231n.github.io/python-numpy-tutorial/](http://cs231n.github.io/python-numpy-tutorial/) diff --git a/README.md b/README.md new file mode 100644 index 0000000..c8d0569 --- /dev/null +++ b/README.md @@ -0,0 +1,220 @@ +# TIL +> Today I learned + +This is inspired by https://github.com/jbranchaud/til. + +[My blog](http://blog.youapp.co) + +--- + +### Categories + +* [Android](#android) +* [Cloud](#cloud) +* [Design](#design) +* [Docker](#docker) +* [Git](#git) +* [Go](#go) +* [iOS](#ios) +* [JavaScript](#javascript) +* [Linux](#linux) +* [Mac](#mac) +* [Machine Learning](#ml) +* [Others](#others) +* [PostgreSQL](#postgresql) +* [Python](#python) +* [Rails](#rails) +* [Raspberry PI](#raspberry) +* [ReactNative](#reactnative) +* [Resources](#resources) +* [Ruby](#ruby) +* [Swift](#swift) +* [tmux](#tmux) +* [Tools](#tools) +* [Unix](#unix) +* [Vim](#vim) +* [WatchOS](#watchos) + + +--- +### Android +- [Android simulator HAXM hypervisor error](Android/Android-simulator-HAXM-hypervisor-error.md) +- [Always show an intent chooser](Android/Alway-show-an-Intent-chooser.md) +- [Gradle daemon error](Android/gradle-daemon-error.md) +- [Use Dagger 2 for dependency injection](Android/Use-Dagger2-for-DI.md) +- [Enable Android emulator keyboard](Android/enable-emulator-keyboard.md) +- [Android Studio gradle project sync failed](Android/gradle-project-sync-failed.md) +- [Android activity lifecycle](Android/Android-Activity-lifecycle.md) +- [Android layout cheat sheet](Android/layout-cheat-sheet.md) +- [Android style cheat sheet](Android/Android-style-cheat-sheet.md) +- [Android CI](Android/android-ci.md) +- [Vector Support Library](Android/vector-asset-support.md) +- [Distribute views evenly across a linearlayout](Android/distribute-views-evenly-linearlayout.md) +- [Save to Android Pay](https://nootfly.github.io/android/2017/12/12/Save-to-Android-Pay/) + +### Cloud +- [AWS EC2 disk full](Cloud/aws-ec2-disk-full.md) +- [Serverless S3 bucket exists error](Cloud/serverless-s3-exits-error.md) +- [AWS lambda Java read config file](Cloud/aws-lambda-read-config-file.md) +- [Serverless function 6 seconds timeout](Cloud/serverless-function-6-seconds-timeout.md) +- [Serverless commands](Cloud/serverless-commands.md) +- [AWS Policy generator](Cloud/aws-policy-generator.md) + +### Design +- [Color-hex](http://www.color-hex.com/) +- [Convert Icon Fonts To PNG](http://fa2png.io/) +- [Gradient colors](https://uigradients.com) +- [Flat colors](https://www.materialui.co/flatuicolors) +- [Free pictures](http://www.freegreatpicture.com/) +- [Free high-resolution photos from Unsplash](https://unsplash.com/collections/curated/143) + +### Docker + +- [docker nginx log configuration](Docker/nginx-log-conf.md) +- [sudo docker](Docker/sudo-docker.md) +- [docker commands](Docker/docker-commands.md) +- [Move docker-machine config](Docker/Move-docker-machine-config.md) +- [Move different docker versions](Docker/Manage-different-docker-versions.md) +- [docker-compose node link mongo](Docker/docker-compose-node-link-mongo.md) +- [Docker insecure registry](Docker/Docker-insecure-registry.md) +- [Docker.qcow2 disk space issue on Mac](Docker/Docker.qcow2-disk-space-issue-on-Mac.md) + +### Git +- [git auto push](git/git-auto-push.md) +- [git cheat sheet](git/git-cheat-sheet.md) +- [remove big files from git repository](git/remove-big-files-from-git-repository.md) +- [Automatically use correct SSH key for remote Git repo](git/use-correct-ssh-key.md) + +### Go + +- [Upgrade go to 1.6](Go/Upgrade-go-to-1.6.md) + +### iOS + +- [Print system font names](iOS/print-system-font-names.md) +- [How to use Low Power Mode in code](iOS/How-to-use-Low-Power-Mode-in-code.md) +- [Share code between iOS and TVOS](iOS/Share-code-between-iOS-and-TVOS.md) +- [UIScrollView not scrolling when using autolayout](iOS/UIScrollView-not-scrolling-when-using-autolayout.md) +- [iOS 9 PopOver points to top-left corner of anchor](iOS/ios9-popover-always-points-to-top-left-corner-of-anchor.md) +- [CALayer shadow performance issue](iOS/CALayer-shadow-performance-issue.md) +- [Slow animations in a simulator](iOS/Slow-animations-in-a-simulator.md) +- [UITapGestureRecognizer or touchesBegan](iOS/UITapGestureRecognizer-or-touchesBegan.md) +- [CoreData in Swift framework](iOS/CoreData-in-Swift-framework.md) +- [iOS keyboard background issue](iOS/iOS-keyboard-background-issue.md) +- [iOS delete downloaded simulators](iOS/iOS-delete-downloaded-simulators.md) +- [SDWebImagePrefetcher memory issue](iOS/SDWebImage-memory-issue.md) +- [Get current thread](iOS/Get-current-thread.md) +- [iOS concurrency cheat sheet](iOS/iOS-concurrency-cheat-sheet.md) +- [No such module](iOS/No-such-module.md) +- [iOS Keychain cheat sheet](iOS/iOS-keychain-cheat-sheet.md) +- [iOS Extensions access CoreData, shared folder and CloudKit](iOS/iOS-Extensions-access-CoreData-shared-folder-and-CloudKit.md) +- [Xcode uses too much disk space](iOS/Xcode-uses-too-much-disk-space.md) +- [CoreData get records count](iOS/coredata-get-records-count.md) +- [UIApplicationDelegate handles push notification](iOS/UIApplicationDelegate-handles-push-notification.md) +- [Silent push notification](iOS/Silent-push-notification.md) +- [Prepare push notification certificate](iOS/Prepare-push-notification-certificate.md) +- [I used iOS Cocoapods libraries](iOS/I-used-iOS-Cocoapods-libraries.md) +- [UIViewController loadView](iOS/UIViewController-loadView.md) +- [Autolayout cheat sheet](iOS/Autolayout-rules-of-thumb.md) +- [NSLayoutAnchor](iOS/NSLayoutAnchor.md) +- [UILayoutGuide](iOS/UILayoutGuide.md) +- [Customize iOS share extension UI](http://blog.youapp.co/ios/2017/03/01/Customize-iOS-Share-extension-UI/) +- [UIStackView](iOS/UIStackView.md) +- [Fix iTunesConnect must have an arm64-only executable error](iOS/itunesconnect-arm64-only-error.md) +- [iOS share extension icon not seen on simulators](iOS/iOS-share-extension-icon-not-seen-on-simulators.md) +- [iOS common code library](iOS/iOS-common-code-library.md) +- [Quartz 2D cheat sheet](iOS/quartz2d.md) +- [iOS Drawing cheat sheet](iOS/iOS-Drawing-Concepts.md) +- [iOS graphics SDK guides](iOS/iOS-graph-SDK-guides.md) +- [no known instance method for selector](iOS/no-known-instance-method-error.md) +- [OpenGL cheat sheet](iOS/OpenGL-cheat-sheet.md) +- [Set static UITableViewCell delegate](iOS/Set-static-UITableViewCell-delegate.md) +- [UIWebView transparent background color](iOS/UIWebView-transparent-background-color.md) +- [Increase iOS build number in Fastlane](iOS/increase-ios-build-number-in-fastlane.md) +- [iOS theme code](iOS/ios-theme.md) +- [iOS debugging tips](iOS/xcode-debugging-tips.md) +- [Strange AQDefaultDevice logs](iOS/strange-AQDefaultDevice-logging.md) +- [Xcode 9 tips](iOS/xcode-9-tips.md) +- [iPad Drag and Drop steps](iOS/drag-drop-implement-steps.md) +- [SceneKit torus example](iOS/scenekit-torus-example.md) +- [Save to Apple Wallet](http://nootfly.github.io/ios/2017/12/13/Save-to-Apple-Wallet/) +- [Command /bin/sh failed with exit code 1](iOS/command-failed-with-exit-code-1.md) +- [ALWAYS #import other classes in your .m file](iOS/Always-import-other-classes-in-m-file.md) + +### JavaScript +- [Show console.log in JSFiddle](Javascript/JSFiddle-console.md) +- [Run script in Atom](Javascript/Atom-run-javascript.md) +- [mongojs aggregate](Javascript/mongojs-aggregate.md) +- [nodejs debug objects](Javascript/nodejs-debug-object.md) +- [ES6 cheat sheet](Javascript/es6-cheat-sheet.md) +- [Webpack errors](Javascript/Webpack-errors.md) +- [Nodejs Authentication](Javascript/nodejs-authentication.md) +- [Semantic versioning and npm](Javascript/npm-semver.md) + +### Linux +- [Ubuntu commands](Linux/Ubuntu-commands.md) +- [Bash commands](Linux/Bash-commands.md) +- [Run cd in a shell script](Linux/run-cd-in-a-shell-script.md) +- [sudo cd](Linux/sudo-cd.md) + +### Mac +- [nscurl](Mac/nscurl.md) +- [Resize off screen window](Mac/Resize-off-screen-window.md) + +### ML +- [install tensorflow error](ML/install-tensorflow-error.md) + +### Others +- [Technical coding interviews websites](Others/technique-interview-websites.md) +- [Gmail alias](Others/Gmail-alias.md) +- [letsencrypt certificate](Others/letsencrypt-certificate.md) + +### Python +- [Python resources](Python/Python-resources.md) +- [Docker Jupter notebook](Python/docker-jupyter-notebook.md) + +### Raspberry +- [Some interesting Raspberry PI projects](raspberrypi/interesting-pi-projects.md) + +### ReactNative + +- [Add custom fonts](https://medium.com/@danielskripnik/how-to-add-and-remove-custom-fonts-in-react-native-b2830084b0e4) +- [RawText must be wrapped issue](ReactNative/RawText-must-be-wrapped.md) + +### Resources + +- [Free high-resolution photos](https://unsplash.com/) +- [Matrial Design icons](https://material.io/icons/) +- [Mathematical symbols](http://www.rapidtables.com/math/symbols/Basic_Math_Symbols.htm) + +### Swift +- [Swift lazy](Swift/Lazy-Swift.md) +- [Swift generated interface](Swift/Show-swift-generated-interface.md) +- [Creating Set Types](Swift/Creating-your-own-set-types.md) +- [Conditionally Extending a Type](Swift/Conditionally-Extending-a-Type.md) +- [Data set in asset catalogue](Swift/Data-set-in-asset-catalogue.md) +- [ReadableContentGuide](Swift/ReadableContentGuide.md) +- [Swift 2 to Swift 3](Swift/Swift2-to-Swift3.md) +- [Escaping closures](Swift/Escaping-Closures.md) +- [Open keyword](Swift/Open-keyword-swift-3.md) +- [Swift 3 cheat sheet](Swift/Swift-3-cheat-sheet.md) +- [Swift Playground tips](Swift/playground-tips.md) +- [Swift playground unit test](Swift/swift-playground-unit-test.md) + +### Tools +- [Developers cheat sheets](Tools/Developers-cheat-sheets.md) +- [Dictionary](https://cdn.rawgit.com/nootfly/TIL/10cc9914/dict.html) +- [Where has my disk space gone](Tools/Where-has-my-disk-space-gone.md) +- [ES 6 playground](https://babeljs.io/repl/) +- [atom mac live server plugin not working](Tools/atom-mac-live-server-plugin-not-working.md) +- [jenkins docker permission denied issue.md](Tools/jenkins-docker-permission-denied-issue.md) +- [Atom packages](Tools/atom-packages.md) +- [visual studio code column selection](Tools/visual-studio-code-column-selection.md) + + +### WatchOS +- [Watch OS app archive other items issue](WatchOS/Watch-OS-app-archive-other-items-issue.md) +- [Watch OS app connection lost issue issue](WatchOS/Watch-app-the-connection-lost.md) +- [watchOS 3 cheat sheet](WatchOS/watchOS-3-cheat-sheet.md) diff --git a/ReactNative/RawText-must-be-wrapped.md b/ReactNative/RawText-must-be-wrapped.md new file mode 100644 index 0000000..33c666c --- /dev/null +++ b/ReactNative/RawText-must-be-wrapped.md @@ -0,0 +1,17 @@ +# RawText must be wrapped issue + +RawText " " must be wrapped in an explicit component. + +This error happens when I put some codes in one line. + +``` + +``` + +And this issue is resolved by put this code in three lines. + +``` + + + +``` diff --git a/Swift/Conditionally-Extending-a-Type.md b/Swift/Conditionally-Extending-a-Type.md new file mode 100644 index 0000000..66f3a33 --- /dev/null +++ b/Swift/Conditionally-Extending-a-Type.md @@ -0,0 +1,33 @@ +# Conditionally Extending a Type + +Conform to the OptionSetType protocol + +```swift +extension SequenceType where + Generator.Element : IntegerArithmeticType{ + public func canFind(value: Generator.Element) -> Bool{ + for (_, v) in self.enumerate(){ + if v == value{ + return true + } + } + return false + } +} +``` + +You can use it like so: + +```swift +func example1(){ + + if [1, 3, 5, 7].canFind(5){ + print("Found it") + } else { + print("Could not find it") + } + + } + ``` + + The above examples are from "iOS 9 Swift Programming Cookbook". diff --git a/Swift/Creating-your-own-set-types.md b/Swift/Creating-your-own-set-types.md new file mode 100644 index 0000000..18b4d7b --- /dev/null +++ b/Swift/Creating-your-own-set-types.md @@ -0,0 +1,53 @@ +# Creating your own set types + +Conform to the OptionSetType protocol + +```swift +struct IphoneModels : OptionSetType, CustomDebugStringConvertible{ + + let rawValue: Int + init(rawValue: Int){ + self.rawValue = rawValue + } + + static let Six = IphoneModels(rawValue: 0) + static let SixPlus = IphoneModels(rawValue: 1) + static let Five = IphoneModels(rawValue: 2) + static let FiveS = IphoneModels(rawValue: 3) + + var debugDescription: String{ + switch self{ + case IphoneModels.Six: + return "iPhone 6" + case IphoneModels.SixPlus: + return "iPhone 6+" + case IphoneModels.Five: + return "iPhone 5" + case IphoneModels.FiveS: + return "iPhone 5s" + default: + return "Unknown iPhone" + } + } + } +``` + +You can use it like so: + +```swift +func example1(){ + + let myIphones: [IphoneModels] = [.Six, .SixPlus] + + if myIphones.contains(.FiveS){ + print("You own an iPhone 5s") + } else { + print("You don't seem to have an iPhone 5s but you have these:") + for i in myIphones{ + print(i) + } + } + } + ``` + + The above examples are from "iOS 9 Swift Programming Cookbook". diff --git a/Swift/Data-set-in-asset-catalogue.md b/Swift/Data-set-in-asset-catalogue.md new file mode 100644 index 0000000..96e5bd5 --- /dev/null +++ b/Swift/Data-set-in-asset-catalogue.md @@ -0,0 +1,5 @@ +# Data Set in asset catalogue + +```swift +let asset = NSDataAsset(name: "rtf") +``` diff --git a/Swift/Escaping-Closures.md b/Swift/Escaping-Closures.md new file mode 100644 index 0000000..1811f84 --- /dev/null +++ b/Swift/Escaping-Closures.md @@ -0,0 +1,7 @@ +# Escaping Closures in Swift 3.0.1 + +A closure is said to escape a function when the closure is passed as an argument to the function, but is called after the function returns. When you declare a function that takes a closure as one of its parameters, you can write `@escaping` before the parameter’s type to indicate that the closure is allowed to escape. + +Marking a closure with `@escaping` means you have to refer to self explicitly within the closure. Marking a closure with `@escaping` means you have to refer to self explicitly within the closure. + +The content is from [The Swift Programming Language (Swift 3.0.1)](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html) diff --git a/Swift/Lazy-Swift.md b/Swift/Lazy-Swift.md new file mode 100644 index 0000000..91de1fb --- /dev/null +++ b/Swift/Lazy-Swift.md @@ -0,0 +1,30 @@ +#Lazy Swift + + +```lazy var``` and ```LazySequence``` examples are as the blow. The code is from http://alisoftware.github.io/swift/2016/02/28/being-lazy/?utm_campaign=iOS%2BDev%2BWeekly&utm_medium=web&utm_source=iOS_Dev_Weekly_Issue_240 + +```swift +class Avatar { + static let defaultSmallSize = CGSize(width: 64, height: 64) + + lazy var smallImage: UIImage = { + let size = CGSize( + width: min(Avatar.defaultSmallSize.width, self.largeImage.size.width), + height: min(Avatar.defaultSmallSize.height, self.largeImage.size.height) + ) + return self.largeImage.resizedTo(size) + }() + var largeImage: UIImage + + init(largeImage: UIImage) { + self.largeImage = largeImage + } +} +``` + +```swift +let array = Array(0..<1000) +let incArray = array.lazy.map(increment) +print("Result:") +print(incArray[0], incArray[4]) +``` diff --git a/Swift/Open-keyword-swift-3.md b/Swift/Open-keyword-swift-3.md new file mode 100644 index 0000000..909a55f --- /dev/null +++ b/Swift/Open-keyword-swift-3.md @@ -0,0 +1,5 @@ +# open keyword in Swift 3 + +* [`open` keyword](http://stackoverflow.com/a/38950955/1146834) + +* [Swift 3 access control](https://medium.com/@ryuichi/swift-3-access-control-e8035ce8569e#.22y3sgv7j) diff --git a/Swift/ReadableContentGuide.md b/Swift/ReadableContentGuide.md new file mode 100644 index 0000000..caf1ed0 --- /dev/null +++ b/Swift/ReadableContentGuide.md @@ -0,0 +1,25 @@ +# ReadableContentGuide + +```swift + + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.backgroundColor = UIColor.greenColor() + label.text = "Hello, World" + label.sizeToFit() + view.addSubview(label) + + label.leadingAnchor.constraintEqualToAnchor( + view.readableContentGuide.leadingAnchor).active = true + + label.topAnchor.constraintEqualToAnchor( + view.readableContentGuide.topAnchor).active = true + + label.trailingAnchor.constraintEqualToAnchor( + view.readableContentGuide.trailingAnchor).active = true + + label.bottomAnchor.constraintEqualToAnchor( + view.readableContentGuide.bottomAnchor).active = true + ``` + + The above examples is from "iOS 9 Swift Programming Cookbook". diff --git a/Swift/Show-swift-generated-interface.md b/Swift/Show-swift-generated-interface.md new file mode 100644 index 0000000..72773ec --- /dev/null +++ b/Swift/Show-swift-generated-interface.md @@ -0,0 +1,3 @@ +# Show swift generated interface + +Use `Command-Alt-Enter` to it and use ` Command-Enter` to close it diff --git a/Swift/Swift-3-cheat-sheet.md b/Swift/Swift-3-cheat-sheet.md new file mode 100644 index 0000000..98e85fa --- /dev/null +++ b/Swift/Swift-3-cheat-sheet.md @@ -0,0 +1,44 @@ +#Swift 3 cheat sheet + +1. Empty Strings +```swift +var anEmptyString = "" +var anotherEmptyString = String() +if anEmptyString.isEmpty { +print("String is empty") + } +``` + +2. stride functions +``` +let fourToTwo = Array(stride(from: 4, to: 1, by: -1)) // [4, 3, 2] +let fourToOne = Array(stride(from:4, through: 1, by: -1)) // [4, 3, 2, 1] +``` +3. Mutable parameters are not favorable in Swift functional programming and are removed from Swift 3.0. Functions can have inout parameters. +``` +func swapTwoInts( a: inout Int, b: inout Int) { + let temporaryA = a + a = b + b = temporaryA +} +``` +4. nested functions +``` +func returnTwenty() -> Int { + var y = 10 + func add() { + y += 10 + } + add() + return y +} + + returnTwenty() +``` +5. AnyObject can represent an instance of any class type. Any can represent an instance of any type, including structs, enumerations, and function types. + +6. Swift enables us to declare nested types whereby we nest supporting enumerations, classes, and structures within the definition of the type that they support. + +7. The static methods cannot be overridden by the subclasses of the object that they reside in. Class methods are like the static methods but they can be overridden by subclasses. + +8. diff --git a/Swift/Swift2-to-Swift3.md b/Swift/Swift2-to-Swift3.md new file mode 100644 index 0000000..25ddaae --- /dev/null +++ b/Swift/Swift2-to-Swift3.md @@ -0,0 +1,3 @@ +# Swift 2 to Swift 3 + +[Swift 2 to Swift 3](https://saffipeng17.gitbooks.io/swift-2-to-swift-3/content/) diff --git a/Swift/playground-tips.md b/Swift/playground-tips.md new file mode 100644 index 0000000..ced5eaf --- /dev/null +++ b/Swift/playground-tips.md @@ -0,0 +1,56 @@ +# Swift Playground tips + +* Attaching live view to playgrounds + +```swift +import PlaygroundSupport +import UIKit + +let view = UIView(frame: 300.toSize.toRectWithZeroOrigin) +view.backgroundColor = .blue +PlaygroundPage.current.liveView = view +``` + +* Running Playgrounds as continuous apps + +```swift +import UIKit +import PlaygroundSupport + +PlaygroundPage.current.needsIndefiniteExecution = true + +class TappableView : UIView{ + + @objc func handleTaps(_ sender: UITapGestureRecognizer){ + PlaygroundPage.current.finishExecution() + } + + override init(frame: CGRect) { + super.init(frame: frame) + let recognizer = UITapGestureRecognizer(target: self, action: + #selector(TappableView.handleTaps(_:))) + addGestureRecognizer(recognizer) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} + +extension Double{ + var toSize: CGSize{ + return .init(width: self, height: self) + } +} + +extension CGSize{ + var toRectWithZeroOrigin: CGRect{ + return CGRect(origin: .zero, size: self) + } +} + +let view = TappableView(frame: 300.toSize.toRectWithZeroOrigin) +view.backgroundColor = .blue +PlaygroundPage.current.liveView = view +``` diff --git a/Swift/swift-playground-unit-test.md b/Swift/swift-playground-unit-test.md new file mode 100644 index 0000000..58b44d3 --- /dev/null +++ b/Swift/swift-playground-unit-test.md @@ -0,0 +1,18 @@ +# Swift playground unit test + +1. Create a unit test + +```swift +import Foundation +import XCTest + + +public class UnitTests: XCTestCase { + + func testFindIndex() { + XCTAssertEqual(Test.printFindIndexResult(" ", ""), "Position: N/A") + } +} +``` + +2. In swift playground run `UnitTests.defaultTestSuite.run()` \ No newline at end of file diff --git a/Tools/Developers-cheat-sheets.md b/Tools/Developers-cheat-sheets.md new file mode 100644 index 0000000..4bbe07a --- /dev/null +++ b/Tools/Developers-cheat-sheets.md @@ -0,0 +1,17 @@ +# Developers cheat sheets + +* [Vim cheat sheet](https://vim.rtorr.com/) + +* [Markdown cheat sheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) + +* [Xcode keyboard shortcuts and gestures](https://developer.apple.com/library/content/documentation/IDEs/Conceptual/xcode_help-command_shortcuts/MenuCommands/MenuCommands014.html) + +* [Xcode keyboard shortcuts 2](http://five.agency/xcode-keyboard-shortcuts-which-will-boost-your-productivity/) + +* [Android Studio keyboard shortcuts](https://developer.android.com/studio/intro/keyboard-shortcuts.html) + +* [Eclipse shortcuts](https://shortcutworld.com/en/Eclipse/win/all) + +* [Mac keyboard shortcuts](https://support.apple.com/en-au/HT201236) + +* [All shortcuts](https://shortcutworld.com/) diff --git a/Tools/Where-has-my-disk-space-gone.md b/Tools/Where-has-my-disk-space-gone.md new file mode 100644 index 0000000..f286ffb --- /dev/null +++ b/Tools/Where-has-my-disk-space-gone.md @@ -0,0 +1,5 @@ +# Where has my disk space gone? + +[Where has my disk space gone?](http://www.brendangregg.com/blog/2017-02-05/file-system-flame-graph.html) + +[FlameGraph](https://github.com/brendangregg/FlameGraph) diff --git a/Tools/atom-mac-live-server-plugin-not-working.md b/Tools/atom-mac-live-server-plugin-not-working.md new file mode 100644 index 0000000..afd9c70 --- /dev/null +++ b/Tools/atom-mac-live-server-plugin-not-working.md @@ -0,0 +1,8 @@ +# atom mac live server plugin not working + +1. Restart Atom +2. Bring up the command palette (cmd + shift + p) and type "incompatible packages: view" +3. That screen will list all the packages that need to be rebuilt, just click on the "Rebuild" button +4. Atom will ask you to restart it, do so, and that's it, Atom Live Server is now working + +Reference: [https://github.com/jas-chen/atom-live-server/issues/57](https://github.com/jas-chen/atom-live-server/issues/57) diff --git a/Tools/atom-packages.md b/Tools/atom-packages.md new file mode 100644 index 0000000..5550a40 --- /dev/null +++ b/Tools/atom-packages.md @@ -0,0 +1,13 @@ +# Atom editor packages + +I'm using some good packages below: + +1. emmet +2. linter +3. file-icons +4. sublime-style-column-selection +5. atom-live-server +6. minimap +7. atom-beautify +8. Ask Stack +9. Pigments (display colors) diff --git a/Tools/jenkins-docker-permission-denied-issue.md b/Tools/jenkins-docker-permission-denied-issue.md new file mode 100644 index 0000000..0f77d2c --- /dev/null +++ b/Tools/jenkins-docker-permission-denied-issue.md @@ -0,0 +1,11 @@ +# Jenkins docker run permission errors + +To solve `Permission denied - /var/jenkins_home/copy_reference_file.log` issue, + +If the directory is empty: +`sudo chown 1000 volume_dir` + +If the directory already contains files: +`sudo chown -R 1000 volume_dir` + +Reference:[https://github.com/jenkinsci/docker/issues/177](https://github.com/jenkinsci/docker/issues/177) diff --git a/Tools/visual-studio-code-column-selection.md b/Tools/visual-studio-code-column-selection.md new file mode 100644 index 0000000..1e69ea4 --- /dev/null +++ b/Tools/visual-studio-code-column-selection.md @@ -0,0 +1,5 @@ +#Selecting Columns in VS Code + +In Visual Studio Code version 1.0, you can now select columns by holding down `Shift+Alt`, then click and drag with the mouse. This can also be done using just the keyboard by holding down `Ctrl+Shift+Alt` and then using the arrow keys. + +Reference: [https://superuser.com/a/1087720](https://superuser.com/a/1087720) \ No newline at end of file diff --git a/WatchOS/Watch-OS-app-archive-other-items-issue.md b/WatchOS/Watch-OS-app-archive-other-items-issue.md new file mode 100644 index 0000000..868da0f --- /dev/null +++ b/WatchOS/Watch-OS-app-archive-other-items-issue.md @@ -0,0 +1,4 @@ +#Watch OS app archive other items issue + +When you archive an app which has a watch app, the archived item goes to "Other items". +This issue can be resolved by setting `Skip Install` to `Yes` in the watch app Build Settings. You should archive the app watch from the watch app scheme. Also you can reference [the Apple technique archiving note](https://developer.apple.com/library/content/technotes/tn2215/_index.html#//apple_ref/doc/uid/DTS40011221-CH1-PROJ) diff --git a/WatchOS/Watch-app-the-connection-lost.md b/WatchOS/Watch-app-the-connection-lost.md new file mode 100644 index 0000000..3e802c3 --- /dev/null +++ b/WatchOS/Watch-app-the-connection-lost.md @@ -0,0 +1,3 @@ +# Watch app "the network connection was lost" issue in a simulator + +To solve this issue, you can reset iPhone and Watch simulator, then clean the app project and run again. diff --git a/WatchOS/watchOS-3-cheat-sheet.md b/WatchOS/watchOS-3-cheat-sheet.md new file mode 100644 index 0000000..84aaab8 --- /dev/null +++ b/WatchOS/watchOS-3-cheat-sheet.md @@ -0,0 +1,15 @@ +# watchOS 3 cheat sheet + +* The delivery of extension delegate life cycle events may be intermixed with the delivery of activation and deactivation events to the app’s interface controllers, and the order of delivery is not guaranteed. In other words, the `willActivate` method of an interface controller may be called before or after the `applicationDidBecomeActive` method of the extension delegate. + +* Use your interface controller’s `init` and `awakeWithContext:` methods to load any required data, set the values for any interface objects, and prepare your interface to be displayed. Do not use the `willActivate` to initialize your interface controller, instead use the `willActivate` method to make last-minute updates before your interface appears onscreen. + +* When the user reboots the paired iPhone, Watch apps are still able to run, but they cannot communicate with the iPhone until after the user unlocks it. + +* Receiving a background task object from the system is your signal to perform specific types of operations. The task object defines the type of task to perform and contains any data needed to complete the task. The system delivers background task objects to your app by calling the handleBackgroundTasks: method of your app’s extension delegate. + +* Background snapshot tasks are budgeted. In general, the system performs approximately one task per hour for each app in the dock (including the most recently used app). This budget is shared among all complications on the watch face. + +* iOS automatically forwards a read-only copy of your iOS app’s preferences to Apple Watch. Your WatchKit extension can read those preferences using an NSUserDefaults object, but it cannot make changes directly to the defaults database. + +* Apps can initiate telephone calls or SMS messages using the openSystemURL: method of the shared WKExtension object. diff --git a/_config.yml b/_config.yml deleted file mode 100644 index 46b95fe..0000000 --- a/_config.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Welcome to Jekyll! -# -# This config file is meant for settings that affect your whole blog, values -# which you are expected to set up once and rarely edit after that. If you find -# yourself editing this file very often, consider using Jekyll's data files -# feature for the data you need to update frequently. -# -# For technical reasons, this file is *NOT* reloaded automatically when you use -# 'bundle exec jekyll serve'. If you change this file, please restart the server process. - -# Site settings -# These are used to personalize your new site. If you look in the HTML files, -# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on. -# You can create any custom variable you would like, and they will be accessible -# in the templates via {{ site.myvariable }}. -title: Noot's TIL -#email: your-email@example.com -description: >- # this means to ignore newlines until "baseurl:" - This website includes my work and study programming notes. -baseurl: "" # the subpath of your site, e.g. /blog -url: "" # the base hostname & protocol for your site, e.g. http://example.com -twitter_username: jekyllrb -github_username: jekyll - -# Build settings -markdown: kramdown -theme: minima -plugins: - - jekyll-feed - -tag_page_layout: tag_page -tag_page_dir: tag -tag_permalink_style: pretty - -# Exclude from processing. -# The following items will not be processed, by default. Create a custom list -# to override the default setting. -# exclude: -# - Gemfile -# - Gemfile.lock -# - node_modules -# - vendor/bundle/ -# - vendor/cache/ -# - vendor/gems/ -# - vendor/ruby/ diff --git a/_includes/collecttags.html b/_includes/collecttags.html deleted file mode 100644 index 22e38c6..0000000 --- a/_includes/collecttags.html +++ /dev/null @@ -1,18 +0,0 @@ -{% assign rawtags = "" %} -{% for post in site.posts %} - {% assign ttags = post.tags | join:'|' | append:'|' %} - {% assign rawtags = rawtags | append:ttags %} -{% endfor %} -{% assign rawtags = rawtags | split:'|' | sort %} - -{% assign site.tags = "" %} -{% for tag in rawtags %} - {% if tag != "" %} - {% if tags == "" %} - {% assign tags = tag | split:'|' %} - {% endif %} - {% unless tags contains tag %} - {% assign tags = tags | join:'|' | append:'|' | append:tag | split:'|' %} - {% endunless %} - {% endif %} -{% endfor %} \ No newline at end of file diff --git a/_includes/disqus_comments.html b/_includes/disqus_comments.html deleted file mode 100644 index d9400f2..0000000 --- a/_includes/disqus_comments.html +++ /dev/null @@ -1,20 +0,0 @@ -{%- if page.comments != false and jekyll.environment == "production" -%} - -
- - -{%- endif -%} diff --git a/_includes/footer.html b/_includes/footer.html deleted file mode 100644 index db72885..0000000 --- a/_includes/footer.html +++ /dev/null @@ -1,35 +0,0 @@ -
- - -
- - - - - -
- -
diff --git a/_includes/google-analytics.html b/_includes/google-analytics.html deleted file mode 100644 index e9afb20..0000000 --- a/_includes/google-analytics.html +++ /dev/null @@ -1,12 +0,0 @@ - - diff --git a/_includes/head.html b/_includes/head.html deleted file mode 100644 index bd74f05..0000000 --- a/_includes/head.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - {%- seo -%} - - {%- feed_meta -%} - {%- if jekyll.environment == 'production' and site.google_analytics -%} - {%- include google-analytics.html -%} - {%- endif -%} - - {% if site.tags != "" %} - {% include collecttags.html %} - {%- endif -%} - - diff --git a/_includes/header.html b/_includes/header.html deleted file mode 100644 index 89ba581..0000000 --- a/_includes/header.html +++ /dev/null @@ -1,33 +0,0 @@ - diff --git a/_includes/icon-github.html b/_includes/icon-github.html deleted file mode 100644 index e501a16..0000000 --- a/_includes/icon-github.html +++ /dev/null @@ -1 +0,0 @@ -{% include icon-github.svg %}{{ include.username }} diff --git a/_includes/icon-github.svg b/_includes/icon-github.svg deleted file mode 100644 index e6c5f6d..0000000 --- a/_includes/icon-github.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/_includes/icon-twitter.html b/_includes/icon-twitter.html deleted file mode 100644 index e623dbd..0000000 --- a/_includes/icon-twitter.html +++ /dev/null @@ -1 +0,0 @@ -{{ include.username }} diff --git a/_includes/icon-twitter.svg b/_includes/icon-twitter.svg deleted file mode 100644 index efc0ecf..0000000 --- a/_includes/icon-twitter.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/_includes/social.html b/_includes/social.html deleted file mode 100644 index 44046b8..0000000 --- a/_includes/social.html +++ /dev/null @@ -1,14 +0,0 @@ - diff --git a/_layouts/default.html b/_layouts/default.html deleted file mode 100644 index 58e141b..0000000 --- a/_layouts/default.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - {%- include head.html -%} - - - - {%- include header.html -%} - -
-
- {{ content }} -
-
- - {%- include footer.html -%} - - - - diff --git a/_layouts/home.html b/_layouts/home.html deleted file mode 100644 index b9fa3d1..0000000 --- a/_layouts/home.html +++ /dev/null @@ -1,47 +0,0 @@ ---- -layout: default ---- - -
- {%- if page.title -%} -

{{ page.title }}

- {%- endif -%} - - {{ content }} - - {%- if site.posts.size > 0 -%} -

{{ page.list_title | default: "Posts" }}

-
    - {%- for post in site.posts -%} -
  • - {%- assign date_format = site.minima.date_format | default: "%b %-d, %Y" -%} - -

    - - {{ post.title | escape }} - -

    - {%- if site.show_excerpts -%} - {{ post.excerpt }} - {%- endif -%} -
  • - {%- endfor -%} -
- - {%- endif -%} - -

Tags

- {% assign tags = site.tags | sort %} - {% for tag in tags %} - - - {{ tag[0] | replace:'-', ' ' }} ({{ tag | last | size }}) - - - {% endfor %} -
-
-

subscribe via RSS

- -
diff --git a/_layouts/page.html b/_layouts/page.html deleted file mode 100644 index 01e4b2a..0000000 --- a/_layouts/page.html +++ /dev/null @@ -1,14 +0,0 @@ ---- -layout: default ---- -
- -
-

{{ page.title | escape }}

-
- -
- {{ content }} -
- -
diff --git a/_layouts/post.html b/_layouts/post.html deleted file mode 100644 index d0024a7..0000000 --- a/_layouts/post.html +++ /dev/null @@ -1,34 +0,0 @@ ---- -layout: default ---- -
- -
-

{{ page.title | escape }}

- -
- -
- {{ content }} -
- - {%- if site.disqus.shortname -%} - {%- include disqus_comments.html -%} - {%- endif -%} - - -
- -[ - {% for tag in page.tags %} - {% capture tag_name %}{{ tag }}{% endcapture %} - {{ tag_name }}  - {% endfor %} - ] diff --git a/_layouts/tag_feed.xml b/_layouts/tag_feed.xml deleted file mode 100644 index 3b5cd75..0000000 --- a/_layouts/tag_feed.xml +++ /dev/null @@ -1,23 +0,0 @@ ---- -layout: nil ---- - - - Your Title - {{ page.tag }} - - - {{ site.time | date_to_xmlschema }} - http://example.com/tag/{{ page.tag }}.html - - Author Here - - {% for post in page.posts %} - - {{ post.title }} - - {{ post.date | date_to_xmlschema }} - http://example.com{{ post.id }} - {{ post.content | xml_escape }} - - {% endfor %} - \ No newline at end of file diff --git a/_layouts/tag_page.html b/_layouts/tag_page.html deleted file mode 100644 index 30be4c6..0000000 --- a/_layouts/tag_page.html +++ /dev/null @@ -1,13 +0,0 @@ ---- -layout: default ---- -

{{ page.tag }}

- - -
- {{ site | tag_cloud }} -
\ No newline at end of file diff --git a/_plugins/ext.rb b/_plugins/ext.rb deleted file mode 100644 index 8c6e2a1..0000000 --- a/_plugins/ext.rb +++ /dev/null @@ -1 +0,0 @@ -require 'jekyll/tagging' \ No newline at end of file diff --git a/_posts/2017-9-11-enable-emulator-keyboard.md b/_posts/2017-9-11-enable-emulator-keyboard.md deleted file mode 100644 index 230ba06..0000000 --- a/_posts/2017-9-11-enable-emulator-keyboard.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: post -title: "Enable Android emulator keyboard" -date: 2017-09-11 8:37:00 +1000 -categories: android -tags: android ---- - -[https://stackoverflow.com/a/30327728](https://stackoverflow.com/a/30327728) \ No newline at end of file diff --git a/_posts/2018-04-05-welcome-to-jekyll.markdown b/_posts/2018-04-05-welcome-to-jekyll.markdown deleted file mode 100644 index e13e6bf..0000000 --- a/_posts/2018-04-05-welcome-to-jekyll.markdown +++ /dev/null @@ -1,26 +0,0 @@ ---- -layout: post -title: "Welcome" -date: 2018-04-05 10:14:17 +1000 -categories: jekyll update -tags: java test ---- -You’ll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated. - -To add new posts, simply add a file in the `_posts` directory that follows the convention `YYYY-MM-DD-name-of-post.ext` and includes the necessary front matter. Take a look at the source for this post to get an idea about how it works. - -Jekyll also offers powerful support for code snippets: - -{% highlight ruby %} -def print_hi(name) - puts "Hi, #{name}" -end -print_hi('Tom') -#=> prints 'Hi, Tom' to STDOUT. -{% endhighlight %} - -Check out the [Jekyll docs][jekyll-docs] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll’s GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll Talk][jekyll-talk]. - -[jekyll-docs]: https://jekyllrb.com/docs/home -[jekyll-gh]: https://github.com/jekyll/jekyll -[jekyll-talk]: https://talk.jekyllrb.com/ diff --git a/_sass/minima.scss b/_sass/minima.scss deleted file mode 100644 index cb0865b..0000000 --- a/_sass/minima.scss +++ /dev/null @@ -1,51 +0,0 @@ -@charset "utf-8"; - -// Define defaults for each variable. - -$base-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !default; -$base-font-size: 16px !default; -$base-font-weight: 400 !default; -$small-font-size: $base-font-size * 0.875 !default; -$base-line-height: 1.5 !default; - -$spacing-unit: 30px !default; - -$text-color: #111 !default; -$background-color: #fdfdfd !default; -$brand-color: #2a7ae2 !default; - -$grey-color: #828282 !default; -$grey-color-light: lighten($grey-color, 40%) !default; -$grey-color-dark: darken($grey-color, 25%) !default; - -$table-text-align: left !default; - -// Width of the content area -$content-width: 800px !default; - -$on-palm: 600px !default; -$on-laptop: 800px !default; - -// Use media queries like this: -// @include media-query($on-palm) { -// .wrapper { -// padding-right: $spacing-unit / 2; -// padding-left: $spacing-unit / 2; -// } -// } -@mixin media-query($device) { - @media screen and (max-width: $device) { - @content; - } -} - -@mixin relative-font-size($ratio) { - font-size: $base-font-size * $ratio; -} - -// Import partials. -@import - "minima/base", - "minima/layout", - "minima/syntax-highlighting" -; diff --git a/_sass/minima/_base.scss b/_sass/minima/_base.scss deleted file mode 100644 index 248fad0..0000000 --- a/_sass/minima/_base.scss +++ /dev/null @@ -1,251 +0,0 @@ -/** - * Reset some basic elements - */ -body, h1, h2, h3, h4, h5, h6, -p, blockquote, pre, hr, -dl, dd, ol, ul, figure { - margin: 0; - padding: 0; -} - - - -/** - * Basic styling - */ -body { - font: $base-font-weight #{$base-font-size}/#{$base-line-height} $base-font-family; - color: $text-color; - background-color: $background-color; - -webkit-text-size-adjust: 100%; - -webkit-font-feature-settings: "kern" 1; - -moz-font-feature-settings: "kern" 1; - -o-font-feature-settings: "kern" 1; - font-feature-settings: "kern" 1; - font-kerning: normal; -} - - - -/** - * Set `margin-bottom` to maintain vertical rhythm - */ -h1, h2, h3, h4, h5, h6, -p, blockquote, pre, -ul, ol, dl, figure, -%vertical-rhythm { - margin-bottom: $spacing-unit / 2; -} - - - -/** - * `main` element - */ -main { - display: block; /* Default value of `display` of `main` element is 'inline' in IE 11. */ -} - - - -/** - * Images - */ -img { - max-width: 100%; - vertical-align: middle; -} - - - -/** - * Figures - */ -figure > img { - display: block; -} - -figcaption { - font-size: $small-font-size; -} - - - -/** - * Lists - */ -ul, ol { - margin-left: $spacing-unit; -} - -li { - > ul, - > ol { - margin-bottom: 0; - } -} - - - -/** - * Headings - */ -h1, h2, h3, h4, h5, h6 { - font-weight: $base-font-weight; -} - - - -/** - * Links - */ -a { - color: $brand-color; - text-decoration: none; - - &:visited { - color: darken($brand-color, 15%); - } - - &:hover { - color: $text-color; - text-decoration: underline; - } - - .social-media-list &:hover { - text-decoration: none; - - .username { - text-decoration: underline; - } - } -} - - -/** - * Blockquotes - */ -blockquote { - color: $grey-color; - border-left: 4px solid $grey-color-light; - padding-left: $spacing-unit / 2; - @include relative-font-size(1.125); - letter-spacing: -1px; - font-style: italic; - - > :last-child { - margin-bottom: 0; - } -} - - - -/** - * Code formatting - */ -pre, -code { - @include relative-font-size(0.9375); - border: 1px solid $grey-color-light; - border-radius: 3px; - background-color: #eef; -} - -code { - padding: 1px 5px; -} - -pre { - padding: 8px 12px; - overflow-x: auto; - - > code { - border: 0; - padding-right: 0; - padding-left: 0; - } -} - - - -/** - * Wrapper - */ -.wrapper { - max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit} * 2)); - max-width: calc(#{$content-width} - (#{$spacing-unit} * 2)); - margin-right: auto; - margin-left: auto; - padding-right: $spacing-unit; - padding-left: $spacing-unit; - @extend %clearfix; - - @include media-query($on-laptop) { - max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit})); - max-width: calc(#{$content-width} - (#{$spacing-unit})); - padding-right: $spacing-unit / 2; - padding-left: $spacing-unit / 2; - } -} - - - -/** - * Clearfix - */ -%clearfix:after { - content: ""; - display: table; - clear: both; -} - - - -/** - * Icons - */ - -.svg-icon { - width: 16px; - height: 16px; - display: inline-block; - fill: #{$grey-color}; - padding-right: 5px; - vertical-align: text-top; -} - -.social-media-list { - li + li { - padding-top: 5px; - } -} - - - -/** - * Tables - */ -table { - margin-bottom: $spacing-unit; - width: 100%; - text-align: $table-text-align; - color: lighten($text-color, 18%); - border-collapse: collapse; - border: 1px solid $grey-color-light; - tr { - &:nth-child(even) { - background-color: lighten($grey-color-light, 6%); - } - } - th, td { - padding: ($spacing-unit / 3) ($spacing-unit / 2); - } - th { - background-color: lighten($grey-color-light, 3%); - border: 1px solid darken($grey-color-light, 4%); - border-bottom-color: darken($grey-color-light, 12%); - } - td { - border: 1px solid $grey-color-light; - } -} diff --git a/_sass/minima/_layout.scss b/_sass/minima/_layout.scss deleted file mode 100644 index c20e202..0000000 --- a/_sass/minima/_layout.scss +++ /dev/null @@ -1,254 +0,0 @@ -/** - * Site header - */ -.site-header { - border-top: 5px solid $grey-color-dark; - border-bottom: 1px solid $grey-color-light; - min-height: $spacing-unit * 1.865; - - // Positioning context for the mobile navigation icon - position: relative; -} - -.site-title { - @include relative-font-size(1.625); - font-weight: 300; - line-height: $base-line-height * $base-font-size * 2.25; - letter-spacing: -1px; - margin-bottom: 0; - float: left; - - &, - &:visited { - color: $grey-color-dark; - } -} - -.site-nav { - float: right; - line-height: $base-line-height * $base-font-size * 2.25; - - .nav-trigger { - display: none; - } - - .menu-icon { - display: none; - } - - .page-link { - color: $text-color; - line-height: $base-line-height; - - // Gaps between nav items, but not on the last one - &:not(:last-child) { - margin-right: 20px; - } - } - - @include media-query($on-palm) { - position: absolute; - top: 9px; - right: $spacing-unit / 2; - background-color: $background-color; - border: 1px solid $grey-color-light; - border-radius: 5px; - text-align: right; - - label[for="nav-trigger"] { - display: block; - float: right; - width: 36px; - height: 36px; - z-index: 2; - cursor: pointer; - } - - .menu-icon { - display: block; - float: right; - width: 36px; - height: 26px; - line-height: 0; - padding-top: 10px; - text-align: center; - - > svg path { - fill: $grey-color-dark; - } - } - - input ~ .trigger { - clear: both; - display: none; - } - - input:checked ~ .trigger { - display: block; - padding-bottom: 5px; - } - - .page-link { - display: block; - padding: 5px 10px; - - &:not(:last-child) { - margin-right: 0; - } - margin-left: 20px; - } - } -} - - - -/** - * Site footer - */ -.site-footer { - border-top: 1px solid $grey-color-light; - padding: $spacing-unit 0; -} - -.footer-heading { - @include relative-font-size(1.125); - margin-bottom: $spacing-unit / 2; -} - -.contact-list, -.social-media-list { - list-style: none; - margin-left: 0; -} - -.footer-col-wrapper { - @include relative-font-size(0.9375); - color: $grey-color; - margin-left: -$spacing-unit / 2; - @extend %clearfix; -} - -.footer-col { - float: left; - margin-bottom: $spacing-unit / 2; - padding-left: $spacing-unit / 2; -} - -.footer-col-1 { - width: -webkit-calc(35% - (#{$spacing-unit} / 2)); - width: calc(35% - (#{$spacing-unit} / 2)); -} - -.footer-col-2 { - width: -webkit-calc(20% - (#{$spacing-unit} / 2)); - width: calc(20% - (#{$spacing-unit} / 2)); -} - -.footer-col-3 { - width: -webkit-calc(45% - (#{$spacing-unit} / 2)); - width: calc(45% - (#{$spacing-unit} / 2)); -} - -@include media-query($on-laptop) { - .footer-col-1, - .footer-col-2 { - width: -webkit-calc(50% - (#{$spacing-unit} / 2)); - width: calc(50% - (#{$spacing-unit} / 2)); - } - - .footer-col-3 { - width: -webkit-calc(100% - (#{$spacing-unit} / 2)); - width: calc(100% - (#{$spacing-unit} / 2)); - } -} - -@include media-query($on-palm) { - .footer-col { - float: none; - width: -webkit-calc(100% - (#{$spacing-unit} / 2)); - width: calc(100% - (#{$spacing-unit} / 2)); - } -} - - - -/** - * Page content - */ -.page-content { - padding: $spacing-unit 0; -} - -.page-heading { - @include relative-font-size(2); -} - -.post-list-heading { - @include relative-font-size(1.75); -} - -.post-list { - margin-left: 0; - list-style: none; - - > li { - margin-bottom: $spacing-unit; - } -} - -.post-meta { - font-size: $small-font-size; - color: $grey-color; -} - -.post-link { - display: block; - @include relative-font-size(1.5); -} - - - -/** - * Posts - */ -.post-header { - margin-bottom: $spacing-unit; -} - -.post-title { - @include relative-font-size(2.625); - letter-spacing: -1px; - line-height: 1; - - @include media-query($on-laptop) { - @include relative-font-size(2.25); - } -} - -.post-content { - margin-bottom: $spacing-unit; - - h2 { - @include relative-font-size(2); - - @include media-query($on-laptop) { - @include relative-font-size(1.75); - } - } - - h3 { - @include relative-font-size(1.625); - - @include media-query($on-laptop) { - @include relative-font-size(1.375); - } - } - - h4 { - @include relative-font-size(1.25); - - @include media-query($on-laptop) { - @include relative-font-size(1.125); - } - } -} diff --git a/_sass/minima/_syntax-highlighting.scss b/_sass/minima/_syntax-highlighting.scss deleted file mode 100644 index bccdb89..0000000 --- a/_sass/minima/_syntax-highlighting.scss +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Syntax highlighting styles - */ -.highlight { - background: #fff; - @extend %vertical-rhythm; - - .highlighter-rouge & { - background: #eef; - } - - .c { color: #998; font-style: italic } // Comment - .err { color: #a61717; background-color: #e3d2d2 } // Error - .k { font-weight: bold } // Keyword - .o { font-weight: bold } // Operator - .cm { color: #998; font-style: italic } // Comment.Multiline - .cp { color: #999; font-weight: bold } // Comment.Preproc - .c1 { color: #998; font-style: italic } // Comment.Single - .cs { color: #999; font-weight: bold; font-style: italic } // Comment.Special - .gd { color: #000; background-color: #fdd } // Generic.Deleted - .gd .x { color: #000; background-color: #faa } // Generic.Deleted.Specific - .ge { font-style: italic } // Generic.Emph - .gr { color: #a00 } // Generic.Error - .gh { color: #999 } // Generic.Heading - .gi { color: #000; background-color: #dfd } // Generic.Inserted - .gi .x { color: #000; background-color: #afa } // Generic.Inserted.Specific - .go { color: #888 } // Generic.Output - .gp { color: #555 } // Generic.Prompt - .gs { font-weight: bold } // Generic.Strong - .gu { color: #aaa } // Generic.Subheading - .gt { color: #a00 } // Generic.Traceback - .kc { font-weight: bold } // Keyword.Constant - .kd { font-weight: bold } // Keyword.Declaration - .kp { font-weight: bold } // Keyword.Pseudo - .kr { font-weight: bold } // Keyword.Reserved - .kt { color: #458; font-weight: bold } // Keyword.Type - .m { color: #099 } // Literal.Number - .s { color: #d14 } // Literal.String - .na { color: #008080 } // Name.Attribute - .nb { color: #0086B3 } // Name.Builtin - .nc { color: #458; font-weight: bold } // Name.Class - .no { color: #008080 } // Name.Constant - .ni { color: #800080 } // Name.Entity - .ne { color: #900; font-weight: bold } // Name.Exception - .nf { color: #900; font-weight: bold } // Name.Function - .nn { color: #555 } // Name.Namespace - .nt { color: #000080 } // Name.Tag - .nv { color: #008080 } // Name.Variable - .ow { font-weight: bold } // Operator.Word - .w { color: #bbb } // Text.Whitespace - .mf { color: #099 } // Literal.Number.Float - .mh { color: #099 } // Literal.Number.Hex - .mi { color: #099 } // Literal.Number.Integer - .mo { color: #099 } // Literal.Number.Oct - .sb { color: #d14 } // Literal.String.Backtick - .sc { color: #d14 } // Literal.String.Char - .sd { color: #d14 } // Literal.String.Doc - .s2 { color: #d14 } // Literal.String.Double - .se { color: #d14 } // Literal.String.Escape - .sh { color: #d14 } // Literal.String.Heredoc - .si { color: #d14 } // Literal.String.Interpol - .sx { color: #d14 } // Literal.String.Other - .sr { color: #009926 } // Literal.String.Regex - .s1 { color: #d14 } // Literal.String.Single - .ss { color: #990073 } // Literal.String.Symbol - .bp { color: #999 } // Name.Builtin.Pseudo - .vc { color: #008080 } // Name.Variable.Class - .vg { color: #008080 } // Name.Variable.Global - .vi { color: #008080 } // Name.Variable.Instance - .il { color: #099 } // Literal.Number.Integer.Long -} diff --git a/about.md b/about.md deleted file mode 100644 index 5c3ee38..0000000 --- a/about.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: page -title: About -permalink: /about/ ---- - -Today I learned - -This is inspired by [https://github.com/jbranchaud/til](https://github.com/jbranchaud/til) - -[My blog](http://blog.youapp.co) diff --git a/assets/main.scss b/assets/main.scss deleted file mode 100644 index c60ebe4..0000000 --- a/assets/main.scss +++ /dev/null @@ -1,5 +0,0 @@ ---- -# Only the main Sass file needs front matter (the dashes are enough) ---- - -@import "minima"; diff --git a/assets/minima-social-icons.svg b/assets/minima-social-icons.svg deleted file mode 100644 index fa7399f..0000000 --- a/assets/minima-social-icons.svg +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dict.html b/dict.html new file mode 100644 index 0000000..e8bbbbb --- /dev/null +++ b/dict.html @@ -0,0 +1,71 @@ + + + + + + + + + + + + + Dictionary + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ + + +

+ +
+ +
+
+
+ + + +

+ +
+ +
+ +
+ + + + diff --git a/git/git-auto-push.md b/git/git-auto-push.md new file mode 100644 index 0000000..9006862 --- /dev/null +++ b/git/git-auto-push.md @@ -0,0 +1,24 @@ +# github auto push script + +1. Create ssh key and add the public key to your github repository + + ``` + ssh-keygen -t rsa + ``` + +2. Create a script to commit changes and push it to the remote github server. You can add a commit message as this script's parameter or you can use the default message. + + + ```shell + #!/bin/bash + + MESSAGE="Update" + if [ $# -eq 0 ] + then + echo "No arguments supplied" + else + MESSAGE=$1 + fi + cd /data/myFiles/github/TIL/ + git add . && git commit -m $MESSAGE && git push origin master + ``` diff --git a/git/git-cheat-sheet.md b/git/git-cheat-sheet.md new file mode 100644 index 0000000..d29cfc0 --- /dev/null +++ b/git/git-cheat-sheet.md @@ -0,0 +1,5 @@ +# git cheat sheet + +* git amend commit with another author + + `git commit --amend -m "new comment" --author "New Author "` diff --git a/git/remove-big-files-from-git-repository.md b/git/remove-big-files-from-git-repository.md new file mode 100644 index 0000000..af62837 --- /dev/null +++ b/git/remove-big-files-from-git-repository.md @@ -0,0 +1,3 @@ +# remove big files from git repository + +[https://rtyley.github.io/bfg-repo-cleaner/](https://rtyley.github.io/bfg-repo-cleaner/) diff --git a/git/use-correct-ssh-key.md b/git/use-correct-ssh-key.md new file mode 100644 index 0000000..4ae8ecb --- /dev/null +++ b/git/use-correct-ssh-key.md @@ -0,0 +1,20 @@ +# Automatically use correct SSH key for remote Git repo + +1. In ~/.ssh/ create a file called config with contents based on this: +``` +#user1 account +Host github.aaakk.us.kg-user1 + HostName github.com + User git + IdentityFile ~/.ssh/github-user1 + +#user2 account +Host github.aaakk.us.kg-user2 + HostName github.com + User git + IdentityFile ~/.ssh/github-user2 +``` + +2. `git remote set-url origin git@github.aaakk.us.kg-user1:user1/your-repo-name.git` + +[Automatically use correct SSH key for remote Git repo](https://www.keybits.net/post/automatically-use-correct-ssh-key-for-remote-git-repo/) \ No newline at end of file diff --git a/iOS/Add-swift-to-Objective-c-project.md b/iOS/Add-swift-to-Objective-c-project.md new file mode 100644 index 0000000..e69de29 diff --git a/iOS/Always-import-other-classes-in-m-file.md b/iOS/Always-import-other-classes-in-m-file.md new file mode 100644 index 0000000..8bf9501 --- /dev/null +++ b/iOS/Always-import-other-classes-in-m-file.md @@ -0,0 +1,10 @@ +>You should ALWAYS #import other classes in your .m file. + +>If they happen to also be members of your class, you can forward declare them (by using the @class directive) in your .h file. + +>The reason for doing this is because when you #import a .h file, you only want to import declarations, not definitions. By using @class and only #importing in .m files, you are a) reducing overhead and b) makes for cleaner code. + +>The reasoning behind forward declarations in header files is that it avoids unnecessary dependencies. i.e. Imagine B.h forward declares A and B.m imports A.h. Then imagine C.m, D.m, E.m and F.m import B.h. After all this is done, A.h changes. Since A is only forward declared in B.h, only B.m needs to rebuild. Without forward declarations, C.m, D.m, E.m and F.m would all need to be rebuild if A changes + + +Reference: [https://stackoverflow.com/a/2770246](https://stackoverflow.com/a/2770246) \ No newline at end of file diff --git a/iOS/Autolayout-rules-of-thumb.md b/iOS/Autolayout-rules-of-thumb.md new file mode 100644 index 0000000..c25035b --- /dev/null +++ b/iOS/Autolayout-rules-of-thumb.md @@ -0,0 +1,27 @@ +# Autolayout cheat sheet + +> 1. Whole number multipliers are favored over fractional multipliers. +> 2. Positive constants are favored over negative constants. +> 3. Wherever possible, views should appear in layout order: leading to trailing, top to bottom. +> 4. You should avoid assigning constant sizes to views +> 5. You can always replace a single equality relationship with two inequalities. +> 6. Constraints with a priority of 1000 are required. All other constraints are optional. +> 7. An empty image view does not have an intrinsic content size. As soon as you add an image, though, its intrinsic content size is set to the image’s size. +> 8. With scrolling enabled, a text view does not have an intrinsic content size. With scrolling disabled, by default the view’s intrinsic content size is calculated based on the size of the text without any line wrapping. +> 9. By default, views use a 250 priority for their content hugging, and a 750 priority for their compression resistance. Therefore, it’s easier to stretch a view than it is to shrink it. +> 10. Whenever possible, use the view’s intrinsic content size in your layout. It lets your layout dynamically adapt as the view’s content changes. +> 11. A common example is a label and text field pair. Typically, you want the text field to stretch to fill the extra space while the label remains at its intrinsic content size. To ensure this, make sure the text field’s horizontal content-hugging priority is lower than the label’s. +> 12. To prevent unwanted stretching, increase the content-hugging priority. +> 13. Baseline constraints work only with views that are at their intrinsic content height. If a view is vertically stretched or compressed, the baseline constraints no longer align properly. +> 14. Setting the stack view’s CHCR priorities has no effect, because the stack view does not have an intrinsic content size. +> 15. The system sets and manages the margins of a view controller’s root view. The top and bottom margins are set to zero points, making it easy to extend content under the bars (if any). The side margins vary depending on how and where the controller is presented, but can be either 16 or 20 points. You cannot change these margins. +> 16. Use stack views wherever possible +> 17. Avoid giving views a fixed height or width. +> 18. Always use leading and trailing constraints instead of right and left. +> 19. For text objects that fill the root view from margin to margin, use the readable content guides instead of the layout margins. +For items that need to fill the root view from edge to edge (for example, background images), use the view’s leading and trailing edges. +> 20. If the view extends under the bars, use the top and bottom margins.If the view does not extend under the bars, constrain the view to the top and bottom layout guides instead. +> 21. When programmatically instantiating views, be sure to set their translatesAutoresizingMaskIntoConstraints property to NO. + + +Reference:https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/AnatomyofaConstraint.html#//apple_ref/doc/uid/TP40010853-CH9-SW1 diff --git a/iOS/CALayer-shadow-performance-issue.md b/iOS/CALayer-shadow-performance-issue.md new file mode 100644 index 0000000..f5cb885 --- /dev/null +++ b/iOS/CALayer-shadow-performance-issue.md @@ -0,0 +1,16 @@ +# CALayer shadow performance issue + +Using ```shadowPath``` property can greatly improve performance. +http://stackoverflow.com/questions/7746921/iphone-animations-performance-is-very-poor-when-views-shadow-is-on + + + +```objective-c +theView.layer.shadowPath = [UIBezierPath bezierPathWithRect:theView.bounds].CGPath; +``` + +Or + +```objective-c +theView.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:theView.bounds cornerRadius:theView.layer.cornerRadius].CGPath; +``` diff --git a/iOS/CoreData-in-Swift-framework.md b/iOS/CoreData-in-Swift-framework.md new file mode 100644 index 0000000..3040f3e --- /dev/null +++ b/iOS/CoreData-in-Swift-framework.md @@ -0,0 +1,21 @@ +#CoreData in Swift framework + +Three things are required when CoreData is put in a Swift framework and this framework is shared between the main project and extension projects. Reference: https://www.andrewcbancroft.com/2015/08/25/sharing-a-core-data-model-with-a-swift-framework/ + +- Need to create a data model file in this Swift framework. You cannot move one from other projects. + +- Create an app group for sqlite database +```swift +lazy var applicationDocumentsDirectory: NSURL = { + let url = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.xxx.xxxxxx"); + return url! + }() +``` +- Use the framework bundle to get the data model file +```swift +lazy var managedObjectModel: NSManagedObjectModel = { + let shareKitBundle = NSBundle(identifier: "com.xxx.xxxxxx") + let modelURL = shareKitBundle!.URLForResource("DataModel", withExtension: "momd")! + return NSManagedObjectModel(contentsOfURL: modelURL)! + }() +``` diff --git a/iOS/Customize-iOS-Share-extension-UI.md b/iOS/Customize-iOS-Share-extension-UI.md new file mode 100644 index 0000000..7dc927d --- /dev/null +++ b/iOS/Customize-iOS-Share-extension-UI.md @@ -0,0 +1,19 @@ +# Customize iOS share extension UI + + +1. Create a new UIViewController rather than extending `SLComposeServiceViewController`, and you need to add `@objc (CustomShareViewController)` + + ```swift + @objc (CustomShareViewController) + class CustomShareViewController: UIViewController + ``` + +2. Create a UI, and remember that you cannot present or show another view controller. If you want to show different UI, you can use `alpha` to show or hide UI elements. + +3. Remember to use `extensionContext!.cancelRequest(withError: NSError())` or `extensionContext!.completeRequest(returningItems: [], completionHandler: nil)` to close UI + + +Reference + +http://catthoughts.ghost.io/extensions-in-ios8-custom-views/ +http://blog.hellocode.co/post/share-extension/ diff --git a/iOS/Get-current-thread.md b/iOS/Get-current-thread.md new file mode 100644 index 0000000..2475ceb --- /dev/null +++ b/iOS/Get-current-thread.md @@ -0,0 +1,7 @@ +#Get current thread + +Use the below code to check whether the current thread is main thread. + +```objective-c +NSLog​ (​NSThread​.isMainThread() ? ​"On main thread"​ : ​"Not on main thread"​) +``` diff --git a/iOS/How-to-use-Low-Power-Mode-in-code.md b/iOS/How-to-use-Low-Power-Mode-in-code.md new file mode 100644 index 0000000..86d6540 --- /dev/null +++ b/iOS/How-to-use-Low-Power-Mode-in-code.md @@ -0,0 +1,24 @@ +# How to use Low Power Mode in code + +In iOS9. We can get Low Power Mode through NSProcessInfo. There are two ways to use it. The code is from +https://littlebitesofcocoa.com/192-being-a-good-low-power-mode-citizen?utm_campaign=iOS%2BDev%2BWeekly&utm_medium=web&utm_source=iOS_Dev_Weekly_Issue_238 + +- Read Low Power Mode property + +```swift +func userStoppedScrolling() { + guard NSProcessInfo.processInfo().lowPowerModeEnabled == false else { return } + gifView.beginPlaying() +} +``` + +- Register the notification + +```swift +NSNotificationCenter.defaultCenter() + .addObserver(self, + selector: "lowPowerModeChanged:", + name: NSProcessInfoPowerStateDidChangeNotification, + object: nil + ) +``` diff --git a/iOS/I-used-iOS-Cocoapods-libraries.md b/iOS/I-used-iOS-Cocoapods-libraries.md new file mode 100644 index 0000000..e84fb99 --- /dev/null +++ b/iOS/I-used-iOS-Cocoapods-libraries.md @@ -0,0 +1,11 @@ +# I used iOS Cocoapods libraries + +* [SSFadingScrollView](https://github.com/stephsharp/SSFadingScrollView) + +* [SVProgressHUD](https://github.com/SVProgressHUD/SVProgressHUD) + +* [JVFloatLabeledTextField](https://github.com/jverdi/JVFloatLabeledTextField) + +* [Mantle](https://github.com/Mantle/Mantle) + +* [IQKeyboardManager](https://github.com/hackiftekhar/IQKeyboardManager) diff --git a/iOS/NSLayoutAnchor.md b/iOS/NSLayoutAnchor.md new file mode 100644 index 0000000..2e6c06f --- /dev/null +++ b/iOS/NSLayoutAnchor.md @@ -0,0 +1,58 @@ +# NSLayoutAnchor + +> UIView does not provide anchor properties for the layout margin attributes. Instead, the layoutMarginsGuide property provides a UILayoutGuide object that represents these margins. Use the guide’s anchor properties to create your constraints. + +These are the available layout anchors for UIView: + +* widthAnchor +* heightAnchor +* topAnchor +* bottomAnchor +* leadingAnchor +* trailingAnchor +* leftAnchor +* rightAnchor +* centerXAnchor +* centerYAnchor +* firstBaselineAnchor +* lastBaselineAnchor + + + ``` + // Creating constraints using NSLayoutConstraint +NSLayoutConstraint(item: subview, + attribute: .Leading, + relatedBy: .Equal, + toItem: view, + attribute: .LeadingMargin, + multiplier: 1.0, + constant: 0.0).active = true + +NSLayoutConstraint(item: subview, + attribute: .Trailing, + relatedBy: .Equal, + toItem: view, + attribute: .TrailingMargin, + multiplier: 1.0, + constant: 0.0).active = true + + +// Creating the same constraints using Layout Anchors +let margins = view.layoutMarginsGuide + +subview.leadingAnchor.constraintEqualToAnchor(margins.leadingAnchor).active = true +subview.trailingAnchor.constraintEqualToAnchor(margins.trailingAnchor).active = true + +// Create & Add Layout Constraint +let leadingConstraint = subview.leadingAnchor.constraintEqualToAnchor(superview.leadingAnchor, constant: 8.0) + +// Activate Layout Constraint +leadingConstraint.active = true + +centerXAnchor.constraint(equalTo: (superview?.centerXAnchor)!, constant: 0).isActive = true + +centerYAnchor.constraint(equalTo: (superview?.centerYAnchor)!, constant: 0).isActive = true +``` + + +Reference: https://developer.apple.com/reference/uikit/nslayoutanchor diff --git a/iOS/No-such-module.md b/iOS/No-such-module.md new file mode 100644 index 0000000..55a13ad --- /dev/null +++ b/iOS/No-such-module.md @@ -0,0 +1,3 @@ +# No such module + +I found that this issue was resolved by setting `Build Active Architecture Only` to `Yes` in `Build Settings`. diff --git a/iOS/OpenGL-cheat-sheet.md b/iOS/OpenGL-cheat-sheet.md new file mode 100644 index 0000000..e22edcc --- /dev/null +++ b/iOS/OpenGL-cheat-sheet.md @@ -0,0 +1,14 @@ +# OpenGL cheat sheet + + +* OpenGL ES is a C-based API. The OpenGL ES specification does not define a windowing layer + +* Apps that are running in the background may not call OpenGL ES functions. If your app accesses the graphics processor while it is in the background, it is automatically terminated by iOS. + +* Although the context holds the OpenGL ES state, it does not directly manage OpenGL ES objects. Instead, OpenGL ES objects are created and maintained by an EAGLSharegroup object. Every context contains an EAGLSharegroup object that it delegates object creation to. + +* All contexts associated with the same sharegroup must use the same version of the OpenGL ES API as the initial context. + +* The GLKView class manages OpenGL ES infrastructure to provide a place for your drawing code, and the GLKViewController class provides a rendering loop for smooth animation of OpenGL ES content in a GLKit view. + +* The three steps for drawing OpenGL ES content: preparing OpenGL ES infrastructure, issuing drawing commands, and presenting the rendered content to Core Animation for display. diff --git a/iOS/PODS_ROOT-issue.md b/iOS/PODS_ROOT-issue.md new file mode 100644 index 0000000..56aeb74 --- /dev/null +++ b/iOS/PODS_ROOT-issue.md @@ -0,0 +1,10 @@ +#PODS_ROOT issue + +I run into the issue below. It did not work even I run `Pod install`. The solution to this issue was that I +installed a new version CocoaPods. + +``` +diff: /../Podfile.lock: No such file or directory +diff: /Manifest.lock: No such file or directory +error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation. +``` diff --git a/iOS/Prepare-push-notification-certificate.md b/iOS/Prepare-push-notification-certificate.md new file mode 100644 index 0000000..ab2a2f4 --- /dev/null +++ b/iOS/Prepare-push-notification-certificate.md @@ -0,0 +1,28 @@ +# Prepare push notification certificate + +1. On the Apple Developer web site, click Member Center, click Certificates, Identifiers and Profiles, and then click Certificates + +2. Create development and production SSL push certificate on Apple Development certificate portal, then download the certificates and import them into Keychain Access. + +3. Export two private keys as .p12 files from Keychain Access. + +4. Generate `.pem` files + + ``` + $ openssl x509 -in cert.cer -inform DER -outform PEM -out cert.pem + $ openssl pkcs12 -in key.p12 -out key.pem -nodes -clcerts + ``` + + +5. Test certificates: + + ``` + $ openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert myapnsappcert.pem -key myapnsappprivatekey.pem # sandbox + $ openssl s_client -connect gateway.push.apple.com:2195 -cert cert.pem -key key.pem # production + ``` + + +Reference: + +https://github.com/node-apn/node-apn/wiki/Preparing-Certificates +http://docs.aws.amazon.com/sns/latest/dg/mobile-push-apns.html diff --git a/iOS/SDWebImage-memory-issue.md b/iOS/SDWebImage-memory-issue.md new file mode 100644 index 0000000..37ce886 --- /dev/null +++ b/iOS/SDWebImage-memory-issue.md @@ -0,0 +1,8 @@ +#SDWebImagePrefetcher memory issue + +```SDImageCache``` saves images cache in memory by default. If you downloaded lots of images, the app will crash because of low memory. +To solve this issue, we can set ```shouldCacheImagesInMemory``` to ```No``` + +```objective-c +[SDImageCache sharedImageCache].shouldCacheImagesInMemory = NO; +``` diff --git a/iOS/Set-static-UITableViewCell-delegate.md b/iOS/Set-static-UITableViewCell-delegate.md new file mode 100644 index 0000000..e2d7e46 --- /dev/null +++ b/iOS/Set-static-UITableViewCell-delegate.md @@ -0,0 +1,12 @@ +# Set static UITableViewCell delegate + + +```objective-c +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]; + if (indexPath.row == 0) { + ((MyTableViewViewCell *)cell).delegate = self; + } + return cell; +} +``` diff --git a/iOS/Share-code-between-iOS-and-TVOS.md b/iOS/Share-code-between-iOS-and-TVOS.md new file mode 100644 index 0000000..c0bf50c --- /dev/null +++ b/iOS/Share-code-between-iOS-and-TVOS.md @@ -0,0 +1,26 @@ +# Share code between iOS and TVOS + +Using CocoaPods different targets is a way to share code between iOS and TVOS. +The code is from https://labs.ribot.co.uk/sharing-functionality-across-tvos-and-ios-228c76b03a06#.4pa6trgb7. + +```ruby +# Podfile +source 'https://github.com/CocoaPods/Specs.git' + +def shared_pods + pod 'Alamofire', '~> 3.0' + pod 'AlamofireImage', '~> 2.0' +end + +target 'ribotTeam' do + platform :ios, '9.0' + use_frameworks! + shared_pods +end + +target 'ribotTeamtvOS' do + platform :tvos, '9.0' + use_frameworks! + shared_pods +end +``` diff --git a/iOS/Silent-push-notification.md b/iOS/Silent-push-notification.md new file mode 100644 index 0000000..bd1d088 --- /dev/null +++ b/iOS/Silent-push-notification.md @@ -0,0 +1,37 @@ +* Silent push notification + +You need to push `content-available` in a payload. + + ```json + { + "content-available" : 1 + } + ``` +And you can check this in application delegate: + + ```swift + func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) { + let aps = userInfo["aps"] as! [String: AnyObject] + + // 1 + if (aps["content-available"] as? NSString)?.integerValue == 1 { + // Refresh data + // 2 + let podcastStore = PodcastStore.sharedStore + podcastStore.refreshItems { didLoadNewItems in + // 3 + completionHandler(didLoadNewItems ? .NewData : .NoData) + } + } else { + // News + // 4 + createNewNewsItem(aps) + completionHandler(.NewData) + } + } + ``` + + + +Reference http://stackoverflow.com/a/36327058/1146834 + https://www.raywenderlich.com/123862/push-notifications-tutorial diff --git a/iOS/Slow-animations-in-a-simulator.md b/iOS/Slow-animations-in-a-simulator.md new file mode 100644 index 0000000..9038834 --- /dev/null +++ b/iOS/Slow-animations-in-a-simulator.md @@ -0,0 +1,3 @@ +#Slow animations in a simulator + +[⌘]+[t] to toggle slow animations diff --git a/iOS/UIApplicationDelegate-handles-push-notification.md b/iOS/UIApplicationDelegate-handles-push-notification.md new file mode 100644 index 0000000..2b3c827 --- /dev/null +++ b/iOS/UIApplicationDelegate-handles-push-notification.md @@ -0,0 +1,10 @@ +# UIApplicationDelegate handles push notification + +* If your app wasn’t running and the user launches it by tapping the push notification, the push notification is passed to your app in the launchOptions of `application(_:didFinishLaunchingWithOptions:)`. + +* If your app was running and in the foreground, the push notification will not be shown, but `application(_:didReceiveRemoteNotification:)` will be called immediately. + +* If your app was running or suspended in the background and the user brings it to the foreground by tapping the push notification, `application(_:didReceiveRemoteNotification:)` will be called. + + +Reference: https://www.raywenderlich.com/123862/push-notifications-tutorial diff --git a/iOS/UILayoutGuide.md b/iOS/UILayoutGuide.md new file mode 100644 index 0000000..df353f3 --- /dev/null +++ b/iOS/UILayoutGuide.md @@ -0,0 +1,31 @@ +# UILayoutGuide + +>The UILayoutGuide class is designed to perform all the tasks previously performed by dummy views, but to do it in a safer, more efficient manner. Layout guides do not define a new view. They do not participate in the view hierarchy. Instead, they simply define a rectangular region in their owning view’s coordinate system that can interact with Auto Layout. + + +## Creating Layout Guides + +>To create a layout guide, you must perform the following steps: +1. Instantiate a new layout guide. +2. Add the layout guide to a view by calling the view’s `addLayoutGuide(_:)` method. +3. Define the position and size of the layout guide using Auto Layout. + +>You can use these guides to define the space between elements in your layout. The following example shows layout guides used to define an equal spacing between a series of views. + + ```swift + let space1 = UILayoutGuide() + view.addLayoutGuide(space1) + + let space2 = UILayoutGuide() + view.addLayoutGuide(space2) + + space1.widthAnchor.constraint(equalTo: space2.widthAnchor).isActive = true + saveButton.trailingAnchor.constraint(equalTo: space1.leadingAnchor).isActive = true + cancelButton.leadingAnchor.constraint(equalTo: space1.trailingAnchor).isActive = true + cancelButton.trailingAnchor.constraint(equalTo: space2.leadingAnchor).isActive = true + clearButton.leadingAnchor.constraint(equalTo: space2.trailingAnchor).isActive = true + ``` + + + +Reference: https://developer.apple.com/reference/uikit/uilayoutguide diff --git a/iOS/UIScrollView-not-scrolling-when-using-autolayout.md b/iOS/UIScrollView-not-scrolling-when-using-autolayout.md new file mode 100644 index 0000000..ac645bc --- /dev/null +++ b/iOS/UIScrollView-not-scrolling-when-using-autolayout.md @@ -0,0 +1,3 @@ +# UIScrollView not scrolling when using autolayout +If you're using autolayout, you need to set contentSize in viewDidLayoutSubviews in order for it to be applied after the autolayout completes. +http://stackoverflow.com/questions/2824435/uiscrollview-not-scrolling diff --git a/iOS/UIStackView.md b/iOS/UIStackView.md new file mode 100644 index 0000000..167a481 --- /dev/null +++ b/iOS/UIStackView.md @@ -0,0 +1,22 @@ +# UIStackView + + * The UIStackView is a nonrendering subclass of UIView; that is, it does not provide any user interface of its own. Instead, it just manages the position and size of its arranged views. As a result, some properties (like `backgroundColor`) have no effect on the stack view. Similarly, you cannot override layerClass, `draw(_:)`, or `draw(_:in:)`. + +* You can also fine tune an arranged view’s appearance by adding additional constraints to the arranged view. For example, you can use constraints to set a minimum or maximum height or width for the view. Or you can define an aspect ratio for the view. + +* Be careful to avoid introducing conflicts when adding constraints to views inside a stack view. As a general rule of thumb, if a view’s size defaults back to its intrinsic content size for a given dimension, you can safely add a constraint for that dimension. + +* Removing a view from the arrangedSubviews array does not remove it as a subview. The stack view no longer manages the view’s size and position, but the view is still part of the view hierarchy, and is rendered on screen if it is visible. + +* Dynamically Changing the Stack View’s Content + + ```swift + // Animates removing the first item in the stack. +UIView.animateWithDuration(0.25) { () -> Void in + let firstView = stackView.arrangedSubviews[0] + firstView.isHidden = true +} + ``` + + +Reference: https://developer.apple.com/reference/uikit/uistackview diff --git a/iOS/UITapGestureRecognizer-or-touchesBegan.md b/iOS/UITapGestureRecognizer-or-touchesBegan.md new file mode 100644 index 0000000..442eba3 --- /dev/null +++ b/iOS/UITapGestureRecognizer-or-touchesBegan.md @@ -0,0 +1,15 @@ +# UITapGestureRecognizer or touchesBegan + +`UITapGestureRecognizer` is a discrete gesture recognizer, and therefore never transitions to the began or changed states. +To animate a touch on a view, the good way is to use `touchesBegan` and `touchesEnded` + +```objective-c +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + UITouch *touch= [touches anyObject]; + if ([touch view].superview == self.giftView){ + [UIView animateWithDuration:0.2 animations:^{ + self.giftView.transform = CGAffineTransformMakeScale(1.05, 1.05); + } completion:nil]; + } + } +``` diff --git a/iOS/UIViewController-loadView.md b/iOS/UIViewController-loadView.md new file mode 100644 index 0000000..64735c0 --- /dev/null +++ b/iOS/UIViewController-loadView.md @@ -0,0 +1,7 @@ +# UIViewController loadView + +> If you use Interface Builder to create your views and initialize the view controller, you must not override this method. + +>You can override this method in order to create your views manually. If you choose to do so, assign the root view of your view hierarchy to the view property. The views you create should be unique instances and should not be shared with any other view controller object. Your custom implementation of this method should not call super. + +Reference:https://developer.apple.com/reference/uikit/uiviewcontroller/1621454-loadview diff --git a/iOS/UIWebView-transparent-background-color.md b/iOS/UIWebView-transparent-background-color.md new file mode 100644 index 0000000..8513b72 --- /dev/null +++ b/iOS/UIWebView-transparent-background-color.md @@ -0,0 +1,8 @@ +# UIWebView transparent background color + +You can use these two lines code to make a UIWebView transparent. + +```objective-c +self.webView.backgroundColor = UIColor.clearColor; +self.webView.opaque = NO; +``` diff --git a/iOS/Xcode-uses-too-much-disk-space.md b/iOS/Xcode-uses-too-much-disk-space.md new file mode 100644 index 0000000..b942a11 --- /dev/null +++ b/iOS/Xcode-uses-too-much-disk-space.md @@ -0,0 +1,3 @@ +# Xcode uses too much disk space + +Remove useless device support from `~/Library/Developer/Xcode/iOS DeviceSupport` and save lots of disk space diff --git a/iOS/command-failed-with-exit-code-1.md b/iOS/command-failed-with-exit-code-1.md new file mode 100644 index 0000000..c90eef2 --- /dev/null +++ b/iOS/command-failed-with-exit-code-1.md @@ -0,0 +1,11 @@ +# Command /bin/sh failed with exit code 1 + +I run into some issues about compilation. + +1. `Command /bin/sh failed with exit code 1` + + After I upgraded xCode, and I could run my app on a simulator, but I cannot run it on a device. This issue was resolved after I restarted my Mac. + +2. `ld: framework not found` + + I got this issue when I added some frameworks to `project -> targets -> general -> Embedded Binaries` and I added them to `project -> targets -> Build Phases -> Link Binary With Libraries`. I solved this issue by removing them from `Link Binary With Libraries`. diff --git a/iOS/core-data-background-context.md b/iOS/core-data-background-context.md new file mode 100644 index 0000000..ad5bc22 --- /dev/null +++ b/iOS/core-data-background-context.md @@ -0,0 +1,22 @@ +# core data background context + +```swift +let context = persistentContainer.newBackgroundContext() +context.automaticallyMergesChangesFromParent = true + +context.perform { + let howMany = 999 + for index in 1...howMany{ + let person = Person(context: context) + person.firstName = "First name \(index)" + person.lastName = "First name \(index)" + } + do{ + try context.save() + DispatchQueue.main.async{completion()} + } catch { + // catch the errors here + } + +} +``` \ No newline at end of file diff --git a/iOS/coredata-get-records-count.md b/iOS/coredata-get-records-count.md new file mode 100644 index 0000000..a3ea55f --- /dev/null +++ b/iOS/coredata-get-records-count.md @@ -0,0 +1,12 @@ +# CoreData get records count + + ```swift + let fetchRequest = NSFetchRequest(entityName: "entityName") + fetchRequest.includesSubentities = false + do { + return try managedObjectContext.count(for: fetchRequest) + } catch { + print("fetch error") + } + return 0 + ``` diff --git a/iOS/drag-drop-implement-steps.md b/iOS/drag-drop-implement-steps.md new file mode 100644 index 0000000..8ee3945 --- /dev/null +++ b/iOS/drag-drop-implement-steps.md @@ -0,0 +1,235 @@ +# Drag and drop steps + +On the iPhone, drag and drop works only inside the same app, not across applications. On the iPad, however, drag and drop works across applications. + +1. Conform your view controller to the `UIDropInteractionDelegate` and `UIDragInteractionDelegate` protocols. These are responsible for controlling drag and drop, whether inside your app or between apps. +```swift +import UIKit + +class ViewController: UIViewController, +UIDropInteractionDelegate, UIDragInteractionDelegate{ + + var dropPoint = CGPoint.zero + + var imageViews = [UIImageView]() + + var images: [UIImage]{ + return imageViews.flatMap{$0.image} + } +``` + +2. Set your view controller’s view’s `pasteConfiguration` to a valid instance of `UIPasteConfiguration`. +```swift + override func viewDidLoad() { + super.viewDidLoad() + + view.pasteConfiguration = UIPasteConfiguration(forAccepting: UIImage.self) +} +``` + +3. Instantiate `UIDropInteraction` and add the drop interaction to your view controller’s view using its `addInteraction(_:)` function. + +```swift + view.addInteraction(UIDropInteraction(delegate: self)) +``` + +4. Similar to the previous step, instantiate `UIDragInteraction` and add the drag interaction to your view controller’s view using its `addInteraction(_:)` function. +```swift + view.addInteraction(UIDragInteraction(delegate: self)) +``` + +5. Implement the `UIDropInteractionDelegate` functions. +```swift +func dropInteraction(_ interaction: UIDropInteraction, + canHandle session: UIDropSession) -> Bool { + return session.canLoadObjects(ofClass: UIImage.self) +} + +func dropInteraction( + _ interaction: UIDropInteraction, + sessionDidUpdate session: UIDropSession) -> UIDropProposal { + + let operation: UIDropOperation + if session.localDragSession == nil{ + operation = .copy + } else { + operation = .move + } + + return UIDropProposal(operation: operation) + +} + + func dropInteraction(_ interaction: UIDropInteraction, + performDrop session: UIDropSession) { + + if let view = interaction.view { + + dropPoint = session.location(in: view) + + if session.localDragSession == nil{ + for item in session.items{ + extractImage(from: item.itemProvider, center: dropPoint) + } + } + } +} + +func dropInteraction( + _ interaction: UIDropInteraction, + previewForDropping item: UIDragItem, + withDefault defaultPreview: UITargetedDragPreview) + -> UITargetedDragPreview? { + + guard item.localObject != nil else {return nil} + + let target = UIDragPreviewTarget(container: view, center: dropPoint) + return defaultPreview.retargetedPreview(with: target) + +} + + func dropInteraction( + _ interaction: UIDropInteraction, + item: UIDragItem, + willAnimateDropWith animator: UIDragAnimating) { + + animator.addAnimations { + self.fade(items: [item], alpha: 0.5) + } + + let center = dropPoint + animator.addCompletion {_ in + guard let index = item.localObject as? Int else {return} + self.imageViews[index].center = center + self.imageViews[index].alpha = 1.0 + } +} + +func extractImage(from itemProvider: NSItemProvider, center: CGPoint) { + + itemProvider.loadObject(ofClass: UIImage.self) {[weak self] object, _ in + guard let self = self else {return} + DispatchQueue.main.async {[weak self] in + guard let self = self, let image = object as? UIImage else {return} + let imageView = image.imageView + imageView.center = center + self.imageViews.append(imageView) + self.view.addSubview(imageView) + } + } + +} + +extension CGSize{ + var rounded: CGSize{ + return CGSize(width: round(width), height: round(height)) + } +} + +fileprivate extension UIImage{ + var imageView: UIImageView{ + let result = UIImageView(image: self) + result.isUserInteractionEnabled = true + result.contentMode = .scaleAspectFit + + let longestSide = max(size.width, size.height) + let maxSize = CGFloat(300) + + //if the image's largest size is larger than 'maxSize', then we + //shrink it down with a transformation + if longestSide > maxSize { + let scale = maxSize / longestSide + let transform = CGAffineTransform(scaleX: scale, y: scale) + result.frame.size = size.applying(transform).rounded + } + + return result + } +} + + func fade(items: [UIDragItem], alpha: CGFloat) { + for item in items where item.localObject is Int { + imageViews[item.localObject as! Int].alpha = alpha + } +} +``` + +6. Similarly, implement the `UIDragInteractionDelegate` functions. + +```swift +func dragInteraction( + _ interaction: UIDragInteraction, + itemsForBeginning session: UIDragSession) -> [UIDragItem] { + + guard let interactionView = interaction.view else {return []} + + let point = session.location(in: interactionView) + + guard let hitTestView = view?.hitTest(point, with: nil) as? UIImageView, + let index = imageViews.index(of: hitTestView) else { + return [] + } + + let image = images[index] + let itemProvider = NSItemProvider(object: image) + let dragItem = UIDragItem(itemProvider: itemProvider) + dragItem.localObject = index + + return [dragItem] + +} + +func dragInteraction( + _ interaction: UIDragInteraction, + previewForLifting item: UIDragItem, session: UIDragSession) + -> UITargetedDragPreview? { + + guard let index = item.localObject as? Int else {return nil} + + return UITargetedDragPreview(view: imageViews[index]) + +} + + func dragInteraction( + _ interaction: UIDragInteraction, + willAnimateLiftWith animator: UIDragAnimating, + session: UIDragSession) { + + animator.addCompletion { position in + if position == .end { + self.fade(items: session.items, alpha: 0.5) + } + } +} + +func dragInteraction( + _ interaction: UIDragInteraction, + item: UIDragItem, + willAnimateCancelWith animator: UIDragAnimating) { + + animator.addAnimations { + self.fade(items: [item], alpha: 1) + } + +} + + func dragInteraction( + _ interaction: UIDragInteraction, + session: UIDragSession, + willEndWith operation: UIDropOperation) { + + if operation == .copy { + fade(items: session.items, alpha: 1) + } + + } + + override func paste(itemProviders: [NSItemProvider]) { + for item in itemProviders { + extractImage(from: item, center: dropPoint) + } +} +``` + + +Reference: iOS 11 Swift Programming Cookbook \ No newline at end of file diff --git a/iOS/iOS-Drawing-Concepts.md b/iOS/iOS-Drawing-Concepts.md new file mode 100644 index 0000000..fbd8d3b --- /dev/null +++ b/iOS/iOS-Drawing-Concepts.md @@ -0,0 +1,33 @@ +# iOS Drawing cheat sheet + +* The iOS native graphics system combines three major technologies: UIKit, Core Graphics, and Core Animation. UIKit provides views and some high-level drawing functionality within those views, Core Graphics provides additional (lower-level) drawing support within UIKit views, and Core Animation provides the ability to apply transformations and animation to UIKit views. Core Animation is also responsible for view compositing. + +* iOS provides two primary paths for creating high-quality graphics in your system: OpenGL or native rendering using Quartz, Core Animation, and UIKit. + +* Quartz is the main drawing interface, providing support for path-based drawing, anti-aliased rendering, gradient fill patterns, images, colors, coordinate-space transformations, and PDF document creation, display, and parsing. UIKit provides Objective-C wrappers for line art, Quartz images, and color manipulations. Core Animation provides the underlying support for animating changes in many UIKit view properties and can also be used to implement custom animations. + +* The default coordinate system used by the UIKit and Core Animation frameworks is ULO-based. The default coordinate system used by Core Graphics framework is LLO-based. The default coordinate system in OS X is LLO-based. + +* One point does not necessarily correspond to one physical pixel. + +* Native drawing technologies, such as Core Graphics, take the current scale factor into account for you. For example, if one of your views implements a drawRect: method, UIKit automatically sets the scale factor for that view to the screen’s scale factor. In addition, UIKit automatically modifies the current transformation matrix of any graphics contexts used during drawing to take into account the view’s scale factor. Thus, any content you draw in your drawRect: method is scaled appropriately for the underlying device’s screen. + +* As a rule, lines that are an odd number of physical pixels wide appear softer than lines with widths measured in even numbers of physical pixels unless you adjust their position to make them cover pixels fully. + +* In iOS, it is recommended that you use the UIKit functions for drawing to bitmap contexts and PDF contexts. However, if you do use the Core Graphics alternatives and intend to display the rendered results, you will have to adjust your code to compensate for the difference in default coordinate systems. + +* Quartz is the general name for the native drawing technology in iOS. The Core Graphics framework is at the heart of Quartz, and is the primary interface you use for drawing content. + +* If you only use UIKit methods and function for drawing, you shouldn’t need to flip the CTM. However, if you mix Core Graphics or Image I/O function calls with UIKit calls, flipping the CTM might be necessary. + +* The key technology in Core Animation is the layer object. Layers are lightweight objects that are similar in nature to views, but that are actually model objects that encapsulate geometry, timing, and visual properties for the content you want to display. + +* The UIBezierPath class is really just a wrapper for a CGPathRef data type and the drawing attributes associated with that path. + +* Because a UIBezierPath object owns its underlying CGPathRef data type, you cannot simply retrieve that type and modify it directly. Instead, you must make a mutable copy, modify the copy, and then assign the copy back to the CGPath property. + +* The containsPoint: method and the Core Graphics hit-testing functions operate only on closed paths. These methods always return NO for hits on open subpaths. If you want to do hit detection on an open subpath, you must create a copy of your path object and close the open subpaths before testing points. + + + +Reference: [Drawing and Printing Guide for iOS](https://developer.apple.com/library/content/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/Introduction/Introduction.html#//apple_ref/doc/uid/TP40010156-CH1-SW1) diff --git a/iOS/iOS-Drawing-cheat-sheet-2.md b/iOS/iOS-Drawing-cheat-sheet-2.md new file mode 100644 index 0000000..8f1e698 --- /dev/null +++ b/iOS/iOS-Drawing-cheat-sheet-2.md @@ -0,0 +1 @@ +# iOS Drawing cheat sheet 2 diff --git a/iOS/iOS-Extensions-access-CoreData-shared-folder-and-CloudKit.md b/iOS/iOS-Extensions-access-CoreData-shared-folder-and-CloudKit.md new file mode 100644 index 0000000..7013f37 --- /dev/null +++ b/iOS/iOS-Extensions-access-CoreData-shared-folder-and-CloudKit.md @@ -0,0 +1,22 @@ +# iOS Extensions access CoreData, shared folder and CloudKit + +1. `applicationDocumentsDirectory` needs to point to a group directory. + + ```swift + public lazy var applicationDocumentsDirectory: URL? = { + return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.xxx.xxxxxx"); + }() + ``` + +2. `sqlite` file is required to put in a group folder + + ```swift + let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) + let url = self.applicationDocumentsDirectory?.appendingPathComponent("xxxxx.sqlite") + ``` + +3. `CKContainer` is created with a identifier and extensions must share this identifier in targets capabilities settings. + + ```swift + container = CKContainer(identifier: "iCloud.com.xxx.xxxxxx") + ``` diff --git a/iOS/iOS-common-code-library.md b/iOS/iOS-common-code-library.md new file mode 100644 index 0000000..23032a4 --- /dev/null +++ b/iOS/iOS-common-code-library.md @@ -0,0 +1,22 @@ +#iOS common code library + +1. add tint color to a button + + + ```swift + let button = UIButton(frame: aRectHere) + let buttonImage = UIImage(named: "imageName") + button.setImage(buttonImage?.withRenderingMode(.alwaysTemplate), for: .normal) + button.tintColor = .white + ``` + +2. Add `Mark` to Swift code + + ```swift + //MARK: viewDidLoad + //TODO: - viewDidLoad + //FIXME - viewDidLoad + + ``` +3. `UIView` `func addConstraint(_ constraint: NSLayoutConstraint)` method + >When developing for iOS 8.0 or later, set the constraint’s isActive property totrue instead of calling the addConstraint(_:) method directly. The isActive property automatically adds and removes the constraint from the correct view. diff --git a/iOS/iOS-concurrency-cheat-sheet.md b/iOS/iOS-concurrency-cheat-sheet.md new file mode 100644 index 0000000..d0c0cd1 --- /dev/null +++ b/iOS/iOS-concurrency-cheat-sheet.md @@ -0,0 +1,64 @@ +# iOS concurrency fact sheet + +* NSInvocationOperation is a class you use as-is to create an operation object based on an object and selector from your application. + +* When you create a block operation, you typically add at least one block at initialization time; you can add more blocks as needed later. When it comes time to execute an NSBlockOperation object, the object submits all of its blocks to the default-priority, concurrent dispatch queue. The object then waits until all of the blocks finish executing. + +* `start`, `isExecuting`, `isFinished`, and `isConcurrent` are required to override for concurrent operations. + +* A canceled operation is still considered to be "finished". + +* The system provides each application with four concurrent dispatch queues. These queues are global to the application and are differentiated only by their priority level. + +* Use the dispatch_get_current_queue function for debugging purposes or to test the identity of the current queue. + +* All dispatch objects (including dispatch queues) allow you to associate custom context data with the object. To set and get this data on a given object, you use the dispatch_set_context and dispatch_get_context functions. + +* Executing a completion callback after a task + + ```objective-c + void average_async(int *data, size_t len, + dispatch_queue_t queue, void (^block)(int)) + { + // Retain the queue provided by the user to make + // sure it does not disappear before the completion + // block can be called. + dispatch_retain(queue); + + // Do the work on the default concurrent queue and then + // call the user-provided block with the results. + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + int avg = average(data, len); + dispatch_async(queue, ^{ block(avg);}); + + // Release the user-provided queue when done + dispatch_release(queue); + }); + } + ``` + +* Using Dispatch Semaphores to Regulate the Use of Finite Resources + + ```objective-c + // Create the semaphore, specifying the initial pool size + dispatch_semaphore_t fd_sema = dispatch_semaphore_create(getdtablesize() / 2); + + // Wait for a free file descriptor + dispatch_semaphore_wait(fd_sema, DISPATCH_TIME_FOREVER); + fd = open("/etc/services", O_RDONLY); + + // Release the file descriptor when done + close(fd); + dispatch_semaphore_signal(fd_sema); + ``` + +* Dispatch groups are a way to block a thread until one or more tasks finish executing. + +* Do not call the dispatch_sync function from a task that is executing on the same queue that you pass to your function call. Doing so will deadlock the queue. If you need to dispatch to the current queue, do so asynchronously using the dispatch_async function. + +* All dispatch queues are first-in, first-out data structures. + +* You can create as many serial queues as you need, and each queue operates concurrently with respect to all other queues. In other words, if you create four serial queues, each queue executes only one task at a time but up to four tasks could still execute concurrently, one from each queue. + + +All contents are from [Apple concurrency programming guide](https://developer.apple.com/library/content/documentation/General/Conceptual/ConcurrencyProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008091-CH1-SW1) diff --git a/iOS/iOS-delete-downloaded-simulators.md b/iOS/iOS-delete-downloaded-simulators.md new file mode 100644 index 0000000..5f494f7 --- /dev/null +++ b/iOS/iOS-delete-downloaded-simulators.md @@ -0,0 +1,3 @@ +# iOS delete downloaded simulators + +Remove them from ```/Library/Developer/CoreSimulator/Profiles/Runtimes``` diff --git a/iOS/iOS-graph-SDK-guides.md b/iOS/iOS-graph-SDK-guides.md new file mode 100644 index 0000000..32f64c0 --- /dev/null +++ b/iOS/iOS-graph-SDK-guides.md @@ -0,0 +1,13 @@ +# iOS graphics SDK guides + +* [Drawing and Printing Guide for iOS](https://developer.apple.com/library/content/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/Introduction/Introduction.html#//apple_ref/doc/uid/TP40010156-CH1-SW1) + +* [Core Animation Programming Guide](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreAnimation_guide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40004514-CH1-SW1) + +* [Animation Types and Timing Programming Guide](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Animation_Types_Timing/Introduction/Introduction.html#//apple_ref/doc/uid/TP40006668-SW1) + +* [OpenGL ES Programming Guide](https://developer.apple.com/library/content/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008793-CH1-SW1) + +* [Quartz 2D Programming Guide](https://developer.apple.com/library/content/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/Introduction/Introduction.html) + +* [Core Image Programming Guide](https://developer.apple.com/library/content/documentation/GraphicsImaging/Conceptual/CoreImaging/ci_intro/ci_intro.html#//apple_ref/doc/uid/TP30001185-CH1-TPXREF101) diff --git a/iOS/iOS-keyboard-background-issue.md b/iOS/iOS-keyboard-background-issue.md new file mode 100644 index 0000000..7db241e --- /dev/null +++ b/iOS/iOS-keyboard-background-issue.md @@ -0,0 +1,5 @@ +# iOS keyboard background issue + +This issue happens on iOS 9 when presenting a new view controller. The solution is to dismiss the keyboard before presenting the view controller. + +![The background was changed from grey to white](white_bg_keyboard.png) diff --git a/iOS/iOS-keychain-cheat-sheet.md b/iOS/iOS-keychain-cheat-sheet.md new file mode 100644 index 0000000..e8abe33 --- /dev/null +++ b/iOS/iOS-keychain-cheat-sheet.md @@ -0,0 +1,15 @@ +# iOS Keychain check sheet + +* A keychain is simply a database stored in the file system, and an iOS device has a single keychain that is available to all apps. + +* In iOS, the keychain is automatically unlocked when the devices is unlocked. + +* In macOS, if you make this call from the same app that created the keychain item, Keychain Services automatically grants access because the app is in the item’s ACL. + +* In iOS, and in macOS when using the iCloud keychain (for items with the kSecAttrSynchronizable attribute set to kCFBooleanTrue), you share keychain items using Access Groups. This kind of sharing does not require interaction with, or permission from the user, but limits sharing to apps that are delivered by a single development team. + +* Access Control Lists are not available in iOS or to macOS apps that use the iCloud keychain. For keychain item sharing in those environments, use Access Groups instead. + +* Before iOS 10.3, as an effect of the implementation, Keychain does store values after we uninstall the app. + +The content is from [Apple Keychain Services Programming Guide.](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/01introduction/introduction.html#//apple_ref/doc/uid/TP30000897-CH203-TP1) diff --git a/iOS/iOS-share-extension-icon-not-seen-on-simulators.md b/iOS/iOS-share-extension-icon-not-seen-on-simulators.md new file mode 100644 index 0000000..c179100 --- /dev/null +++ b/iOS/iOS-share-extension-icon-not-seen-on-simulators.md @@ -0,0 +1,7 @@ +# iOS share extension icon not seen on simulators + +To solve this issue, two settings are needed to be done. + +1. Set `Asset Catalog App Icon Set Name` to `AppIcon` in `Assets.xcassets` in `Build Settings`. `AppIcon` is the app's icon name + +2. Select the extension in `AppIcon`'s `File inspector Target Membership` diff --git a/iOS/increase-ios-build-number-in-fastlane.md b/iOS/increase-ios-build-number-in-fastlane.md new file mode 100644 index 0000000..678cdb1 --- /dev/null +++ b/iOS/increase-ios-build-number-in-fastlane.md @@ -0,0 +1,7 @@ +# increase iOS build number in Fastlane + +There are two steps to do this. + +1. Enable agvtool in Xcode according to [https://developer.apple.com/library/content/qa/qa1827/_index.html](https://developer.apple.com/library/content/qa/qa1827/_index.html) + +2. Call `increment_build_number` function in `Fastfile`. diff --git a/iOS/ios-questions.md b/iOS/ios-questions.md new file mode 100644 index 0000000..a560ccf --- /dev/null +++ b/iOS/ios-questions.md @@ -0,0 +1,7 @@ +# iOS questions + +1. MVP vs MVVM vs MVC + +2. What's ARC and MRC? + +3. swift \ No newline at end of file diff --git a/iOS/ios-theme.md b/iOS/ios-theme.md new file mode 100644 index 0000000..e6d921e --- /dev/null +++ b/iOS/ios-theme.md @@ -0,0 +1,131 @@ +# iOS theme code + +``` +enum Theme: Int { + //1 + case `default`, dark, graphical + + //2 + private enum Keys { + static let selectedTheme = "SelectedTheme" + } + + //3 + static var current: Theme { + let storedTheme = UserDefaults.standard.integer(forKey: Keys.selectedTheme) + return Theme(rawValue: storedTheme) ?? .default + } + + + var mainColor: UIColor { + switch self { + case .default: + return UIColor(red: 87.0/255.0, green: 188.0/255.0, blue: 95.0/255.0, alpha: 1.0) + case .dark: + return UIColor(red: 255.0/255.0, green: 115.0/255.0, blue: 50.0/255.0, alpha: 1.0) + case .graphical: + return UIColor(red: 10.0/255.0, green: 10.0/255.0, blue: 10.0/255.0, alpha: 1.0) + } + } + + func apply() { + //1 + UserDefaults.standard.set(rawValue, forKey: Keys.selectedTheme) + UserDefaults.standard.synchronize() + + //2 + UIApplication.shared.delegate?.window??.tintColor = mainColor + + UINavigationBar.appearance().barStyle = barStyle + UINavigationBar.appearance().setBackgroundImage(navigationBackgroundImage, for: .default) + + UINavigationBar.appearance().backIndicatorImage = UIImage(named: "backArrow") + UINavigationBar.appearance().backIndicatorTransitionMaskImage = UIImage(named: "backArrowMaskFixed") + + UITabBar.appearance().barStyle = barStyle + UITabBar.appearance().backgroundImage = tabBarBackgroundImage + + let tabIndicator = UIImage(named: "tabBarSelectionIndicator")?.withRenderingMode(.alwaysTemplate) + let tabResizableIndicator = tabIndicator?.resizableImage( + withCapInsets: UIEdgeInsets(top: 0, left: 2.0, bottom: 0, right: 2.0)) + UITabBar.appearance().selectionIndicatorImage = tabResizableIndicator + + let controlBackground = UIImage(named: "controlBackground")? + .withRenderingMode(.alwaysTemplate) + .resizableImage(withCapInsets: UIEdgeInsets(top: 3, left: 3, bottom: 3, right: 3)) + + let controlSelectedBackground = UIImage(named: "controlSelectedBackground")? + .withRenderingMode(.alwaysTemplate) + .resizableImage(withCapInsets: UIEdgeInsets(top: 3, left: 3, bottom: 3, right: 3)) + + UISegmentedControl.appearance().setBackgroundImage(controlBackground, + for: .normal, + barMetrics: .default) + UISegmentedControl.appearance().setBackgroundImage(controlSelectedBackground, + for: .selected, + barMetrics: .default) + + UIStepper.appearance().setBackgroundImage(controlBackground, for: .normal) + UIStepper.appearance().setBackgroundImage(controlBackground, for: .disabled) + UIStepper.appearance().setBackgroundImage(controlBackground, for: .highlighted) + UIStepper.appearance().setDecrementImage(UIImage(named: "fewerPaws"), for: .normal) + UIStepper.appearance().setIncrementImage(UIImage(named: "morePaws"), for: .normal) + + UISlider.appearance().setThumbImage(UIImage(named: "sliderThumb"), for: .normal) + UISlider.appearance().setMaximumTrackImage(UIImage(named: "maximumTrack")? + .resizableImage(withCapInsets:UIEdgeInsets(top: 0, left: 0.0, bottom: 0, right: 6.0)), for: .normal) + + UISlider.appearance().setMinimumTrackImage(UIImage(named: "minimumTrack")? + .withRenderingMode(.alwaysTemplate) + .resizableImage(withCapInsets:UIEdgeInsets(top: 0, left: 6.0, bottom: 0, right: 0)), for: .normal) + + UISwitch.appearance().onTintColor = mainColor.withAlphaComponent(0.3) + UISwitch.appearance().thumbTintColor = mainColor + + UITableViewCell.appearance().backgroundColor = backgroundColor + UILabel.appearance(whenContainedInInstancesOf: [UITableViewCell.self]).textColor = textColor + + } + + var barStyle: UIBarStyle { + switch self { + case .default, .graphical: + return .default + case .dark: + return .black + } + } + + var navigationBackgroundImage: UIImage? { + return self == .graphical ? UIImage(named: "navBackground") : nil + } + + var tabBarBackgroundImage: UIImage? { + return self == .graphical ? UIImage(named: "tabBarBackground") : nil + } + + var backgroundColor: UIColor { + switch self { + case .default, .graphical: + return UIColor.white + case .dark: + return UIColor(white: 0.4, alpha: 1.0) + } + } + + var textColor: UIColor { + switch self { + case .default, .graphical: + return UIColor.black + case .dark: + return UIColor.white + } + } + + +} + +``` + +Reference: +[https://www.raywenderlich.com/156036/uiappearance-tutorial-getting-started](https://www.raywenderlich.com/156036/uiappearance-tutorial-getting-started) diff --git a/iOS/ios9-popover-always-points-to-top-left-corner-of-anchor.md b/iOS/ios9-popover-always-points-to-top-left-corner-of-anchor.md new file mode 100644 index 0000000..167c647 --- /dev/null +++ b/iOS/ios9-popover-always-points-to-top-left-corner-of-anchor.md @@ -0,0 +1,14 @@ +#iOS 9 PopOver points to top-left corner of anchor + +The fix is from stackoverflow: http://stackoverflow.com/questions/32666214/ios9-popover-always-points-to-top-left-corner-of-anchor + +```objective-c +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + if ([segue.identifier isEqualToString:@"BalanceInfo"]) { + UIViewController *infoVC = segue.destinationViewController; + infoVC.preferredContentSize = CGSizeMake(351, 286); + infoVC.popoverPresentationController.sourceRect = self.balanceInfoButton.bounds; + + } +} +``` diff --git a/iOS/itunesconnect-arm64-only-error.md b/iOS/itunesconnect-arm64-only-error.md new file mode 100644 index 0000000..5141c04 --- /dev/null +++ b/iOS/itunesconnect-arm64-only-error.md @@ -0,0 +1,3 @@ +# Fix iTunesConnect must have an arm64-only executable error + +When you upload your app to iTunesConnect, you may meet "must have an arm64-only executable" error. To solve this issue, you need to update your `Valid Architectures` to `arm64` in Xcode target `Build Settings`. diff --git a/iOS/no-known-instance-method-error.md b/iOS/no-known-instance-method-error.md new file mode 100644 index 0000000..d9ffc14 --- /dev/null +++ b/iOS/no-known-instance-method-error.md @@ -0,0 +1,4 @@ +# no known instance method for selector respondstoselector + + +When you see this error, you may fix it by adding adding `` to a protocol diff --git a/iOS/print-system-font-names.md b/iOS/print-system-font-names.md new file mode 100644 index 0000000..f0d3fa0 --- /dev/null +++ b/iOS/print-system-font-names.md @@ -0,0 +1,29 @@ +# Print system font names + +It's a quick way to get system font names. The code is from http://codewithchris.com/common-mistakes-with-adding-custom-fonts-to-your-ios-app/ + +Swift: +```swift + for family: String in UIFont.familyNames + { + print("\(family)") + for names: String in UIFont.fontNames(forFamilyName: family) + { + print("== \(names)") + } + } + +``` + +Objective C +```objective-c +for (NSString* family in [UIFont familyNames]) +{ + NSLog(@"%@", family); + + for (NSString* name in [UIFont fontNamesForFamilyName: family]) + { + NSLog(@" %@", name); + } +} +``` diff --git a/iOS/quartz2d.md b/iOS/quartz2d.md new file mode 100644 index 0000000..03a084a --- /dev/null +++ b/iOS/quartz2d.md @@ -0,0 +1,35 @@ +# Quartz 2D cheat sheet + +* You can think of a graphics context as a drawing destination, as shown in Figure 1-2. When you draw with Quartz, all device-specific characteristics are contained within the specific type of graphics context you use. In other words, you can draw the same image to a different device simply by providing a different graphics context to the same sequence of Quartz drawing routines. You do not need to perform any device-specific calculations; Quartz does it for you. + +* A layer context (CGLayerRef) is an offscreen drawing destination associated with another graphics context. It is designed for optimal performance when drawing the layer to the graphics context that created it. A layer context can be a much better choice for offscreen drawing than a bitmap graphics context. + +* The graphics context contains a stack of graphics states. When Quartz creates a graphics context, the stack is empty. When you save the graphics state, Quartz pushes a copy of the current graphics state onto the stack. When you restore the graphics state, Quartz pops the graphics state off the top of the stack. The popped state becomes the current graphics state. + +* Quartz accomplishes device independence with a separate coordinate system—user space—mapping it to the coordinate system of the output device—device space—using the current transformation matrix, or CTM. + +* In iOS, if you use a UIImage object to wrap a CGImage object you create, you do not need to modify the CTM. The UIImage object automatically compensates for the modified coordinate system applied by UIKit. + +* f you create or copy an object, you own it, and therefore you must release it. That is, in general, if you obtain an object from a function with the words “Create” or “Copy” in its name, you must release the object when you’re done with it. Otherwise, a memory leak results. + +* A PDF graphics context in iOS uses the default coordinate system provided by Quartz, without applying a transform to match the UIKit coordinate system. If your application plans on sharing drawing code between your PDF graphics context and the graphics context provided by UIView object, your application should modify the CTM of the PDF graphics context to modify the coordinate system + +* iOS applications should use the function UIGraphicsBeginImageContextWithOptions instead of using the low-level Quartz functions to create a bitmap graphics context. + +* Path creation and path painting are separate tasks. Subpaths are built from lines, arcs, and curves. + +* Points are x and y coordinates that specify a location in user space. You can call the function CGContextMoveToPoint to specify a starting position for a new subpath. Quartz keeps track of the current point, which is the last location used for path construction. + +* An empty path has no current point; you must call CGContextMoveToPoint to set the starting point for the first subpath or call a convenience function that implicitly does this for you. + +* When you want to close the current subpath within a path, call the function CGContextClosePath to connect a segment to the starting point of the subpath. Subsequent path calls begin a new subpath, even if you do not explicitly set a new starting point. + +* You must call a painting function to fill or stroke the path because creating a path does not draw the path. + +* Quartz provides two data types for creating reusable paths—CGPathRef and CGMutablePathRef. + +* iOS does not support device-independent or generic color spaces. iOS applications must use device color spaces instead. + + + +Reference: [Quartz 2D Programming Guide](https://developer.apple.com/library/content/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/Introduction/Introduction.html) diff --git a/iOS/scenekit-torus-example.md b/iOS/scenekit-torus-example.md new file mode 100644 index 0000000..c1f998d --- /dev/null +++ b/iOS/scenekit-torus-example.md @@ -0,0 +1,51 @@ +# SceneKit torus example + +```swift +import UIKit +import SceneKit +import PlaygroundSupport + +var sceneView = SCNView(frame:CGRect(x: 0, y: 0,width: 400, height: 400)) +var scene = SCNScene() +sceneView.scene = scene +PlaygroundPage.current.liveView = sceneView + + +var cameraNode = SCNNode() +cameraNode.camera = SCNCamera() +cameraNode.position = SCNVector3(x: 0, y: 0, z: 4) +scene.rootNode.addChildNode(cameraNode) + +var torus = SCNTorus(ringRadius: 1, pipeRadius: 0.35) +var torusNode = SCNNode(geometry: torus) +torusNode.position = SCNVector3(x: 0.0, y: 0.0, z: 0.0) +scene.rootNode.addChildNode(torusNode) + +torus.firstMaterial?.diffuse.contents = UIColor.green +torus.firstMaterial?.specular.contents = UIColor.white + +torusNode.rotation = SCNVector4(x: 1.0, y: 0.0, z: 0.0, w: Float(Double.pi/4.0)) + +var light = SCNLight() +light.type = SCNLight.LightType.spot +var lightNode = SCNNode() +lightNode.light = light +lightNode.position = SCNVector3(x: 0, y: 0, z: 6) +scene.rootNode.addChildNode(lightNode) + +let moveAction = SCNAction.sequence([ + SCNAction.moveBy(x: -2, y: 0, z: 0, duration: 1), + SCNAction.moveBy(x: 2, y: 0, z: 0, duration: 1), + SCNAction.moveBy(x: 2, y: 0, z: 0, duration: 1), + SCNAction.moveBy(x: -2, y: 0, z: 0, duration: 1) + ]) +lightNode.runAction(SCNAction.repeatForever(moveAction)) + +let rotateAction = SCNAction.rotate(by: CGFloat(Double.pi), + around: SCNVector3(x: 1.0, y: 0.0, z: 0.0), + duration: 4.0) + +torusNode.runAction(SCNAction.repeatForever(rotateAction)) +``` + +Reference: Swift: Developing iOS Applications \ No newline at end of file diff --git a/iOS/strange-AQDefaultDevice-logging.md b/iOS/strange-AQDefaultDevice-logging.md new file mode 100644 index 0000000..f5f1afe --- /dev/null +++ b/iOS/strange-AQDefaultDevice-logging.md @@ -0,0 +1,3 @@ +# Strange AQDefaultDevice logging + +Whne you see this log `AQDefaultDevice (173): skipping input stream 0 0 0x0` in your simulator console, you can disable it by following [this link](https://stackoverflow.com/a/40698526) \ No newline at end of file diff --git a/iOS/white_bg_keyboard.png b/iOS/white_bg_keyboard.png new file mode 100644 index 0000000..c41359c Binary files /dev/null and b/iOS/white_bg_keyboard.png differ diff --git a/iOS/xcode-9-tips.md b/iOS/xcode-9-tips.md new file mode 100644 index 0000000..4d8fb5d --- /dev/null +++ b/iOS/xcode-9-tips.md @@ -0,0 +1,19 @@ +# Xcode 9 tips + +* press the `Cmd+Ctrl+E` buttons to rename + +* `Cmd+Ctrl+left mouse button` or `Cmd+Ctrl+J` or `Cmd+Right mouse click` to jump to definition + +* `.xcodesamplecode.plist` is what triggers Xcode to render the Markdown as seen in their sample. This file can be found under the `.xcodeproj` (within Package Contents). The content of this file is as the below. Reference:[https://dev.to/danielinoa_/rendering-markdown-in-xcode-9](https://dev.to/danielinoa_/rendering-markdown-in-xcode-9) + +``` + + + + + +``` + +* The Main Thread Checker is a standalone tool for Swift and C languages that detects invalid usage of AppKit, UIKit, and other APIs on a background thread. + +* Select the segue object in Interface Builder, you can select the `Preview & Commit Segues` checkbox under `Peek & Pop` section. \ No newline at end of file diff --git a/iOS/xcode-debugging-tips.md b/iOS/xcode-debugging-tips.md new file mode 100644 index 0000000..77d4754 --- /dev/null +++ b/iOS/xcode-debugging-tips.md @@ -0,0 +1,18 @@ +# Xcode debugging tips + +1. Using `Debugger Commond` - `expression NSLog("Loading friends...")` is faster than `Log Message` in a breakpoint + +2. Open the jump bar of the source editor and type, and you can search function names. + +3. Add a `New Run Script Phase` to generate warning for `TODO` and `FIXME` + + ``` + TAGS="TODO:|FIXME: + find "${SRCROOT}" \( -type f -name "*.swift" \) -print0 | xargs -0 egrep --with-filename --line-number --only-matching "($TAGS).*\$" | perl -p -e "s/($TAGS)/ warning: \$1/" + ``` + +4. Use `expression gift.name = "Xbox"` to change a runtime value + + +Reference: +[Intermediate Debugging with Xcode 8](https://www.raywenderlich.com/152276/intermediate-debugging-xcode-8) \ No newline at end of file diff --git a/index.md b/index.md deleted file mode 100644 index 1eb5d67..0000000 --- a/index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -# You don't need to edit this file, it's empty on purpose. -# Edit theme's home layout instead if you wanna make some changes -# See: https://jekyllrb.com/docs/themes/#overriding-theme-defaults -layout: home ---- diff --git a/raspberrypi/interesting-pi-projects.md b/raspberrypi/interesting-pi-projects.md new file mode 100644 index 0000000..0464ead --- /dev/null +++ b/raspberrypi/interesting-pi-projects.md @@ -0,0 +1,5 @@ +# Some interesting Raspberry PI projects + +1. [Smart Security Camera](https://github.com/HackerHouseYT/Smart-Security-Camera) + +2. [Smart Mirror](https://github.com/HackerHouseYT/Smart-Mirror) \ No newline at end of file