生活之中,如行径林间

Swift http请求

2016-06-15

分享一段swift http请求的代码:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let url = NSURL(string: "http://www.douban.com/j/app/radio/channels");
        let session = NSURLSession.sharedSession()
        let task = session.dataTaskWithURL(url!) { (data, response, error) in
            if let err = error{
                print(err)
            }else{
//                let str = NSString(data: data!, encoding: NSUTF8StringEncoding)
//                print(str)
                let json = try? NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions()) as! NSDictionary
                print("json:\(json)")
            }
        }
        task.resume()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

可能遇到的问题: - 网络请求报 App Transport Security has blocked a cleartext - 解决方案:

打开Info.plist,设置

配置示意图

或者直接打开source code,添加

<key>NSAppTransportSecurity</key>  
<dict>  
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>  

gulp入门

2016-05-17

gulp作为新一代前端项目自动化构件工具,已经普遍应用于前端工程中。大部分前端开发者对gulp已经不再陌生,但是对于刚接触gulp的开发人员而言,也免不了些许迷茫。试着从自己学习和使用经验讲一讲。
首先,回顾当下自己所开发的前端项目,是否包含js、css、images静态资源,在项目上线前,我们需要这些静态资源合并压缩。在学习自动化构件工具之前的开发流程中,我们一般需要找到一些工具,我常用的有oschina在线工具koala(js/css编译压缩)TinyPNG(图片压缩),配置文件输入输出,upload、download、我们不断重复着这些工作。烦不烦,反正我是有些厌倦了。

我们本该将更多的精力放在更有意义的事情上

所以,grunt、gulp这一类构件工具出现了,将我们解救于重复的工作中。就自己的理解,自动化构件工具的核心是将我们的工作流抽离为一个个任务(task),根据我们自己的需求,css的合并压缩可以为一个任务、js的合并压缩可以为一个任务、图片的压缩也可以为一个任务,我们可以将上线前对静态资源的操作分成以上三个任务。最后,我们只需要运行一个命令,这些任务就会自动执行。再加上对每个文件变化的监听,每次文件的修改都会触发自动构建。妈妈再也不担心我们做重复的事情了,是不是倍儿爽?

对于我,学习一个新的工具,首先是用起来。

  • gulp需要依赖node环境运行,首先确保自己安装有node环境

  • 全局安装gulp,npm install -g gulp

  • 在文件夹创建gulpfile.js

  • 文件夹下创建src/css/main.css和src/js/main.js

  • 安装gulp和gulp plugin,执行npm install --save-dev gulp {gulp插件名},以cssmin和uglifyjs为例,npm install --save-dev gulp-cssmin gulp-uglify gulp-rename

  • 配置gulpfile,以cssmin和uglifyjs为例

const gulp = require('gulp');  
const cssmin = require('gulp-cssmin');  
const rename = require('gulp-rename');  
const uglify = require('gulp-uglify');

gulp.task('min:css', function () {  
    return gulp.src('src/css/main.css')
    .pipe(cssmin())
    .pipe(rename({suffix: '.min'}))
    .pipe(gulp.dest('dist/css'));
});

gulp.task('min:js', function () {  
    return gulp.src('src/js/main.js')
        .pipe(uglify())
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest('dist/js'));
});

gulp.task('default', ['min:js', 'min:css']);
  • 执行gulp,运行gulp default任务,执行gulp min:css,根据taskname执行单个任务

  • 执行结果,目录下有新增dist/css/main.min.css和dist/js/main.min.js压缩文件

根据以上步骤,gulp基本使用起来了。

本章源码托管于github/demo-gulp,希望能对gulp初学者有帮助。

晒一手handlebar helper

2016-05-15

最近项目中用到hbs模版,结合express,感觉还不错。其中,helper是handlebar的核心,为了让自己用得更爽,经过搜集和琢磨,留下一手helper,亲测有效。

1. block与extend

  • 源码
let blocks = {};  
hbs.registerHelper('extend', function (name, context) {  
    let block = blocks[name];
    if (!block) {
        block = blocks[name] = [];
    }

    block.push(context.fn(this));
});

hbs.registerHelper('block', function (name) {  
    let val = (blocks[name] || []).join('\n');
    blocks[name] = [];
    return val;
});
  • 使用

layout.hbs(page1页面母版):

<head>  
    <meta charset="UTF-8">
    <title>{{{block "title"}}}</title>
</head>  

page1.hbs(子页面):

{{#extend "title"}}
测试标题
{{/extend}}

输出:

<head>  
    <meta charset="UTF-8">
    <title>测试标题</title>
</head>  

2. 包含

  • 源码
hbs.registerHelper('include', function (args1, args2, context) {  
    let array = args2.split(',');
    if (!_.isArray(array)) {
        return context.inverse(this);
    }
    if (_.includes(array, args1) || _.includes(array, args1.toString())) {
        return context.fn(this);
    }
});
  • 使用
{{#include '1' '1,2,3'}}
'1' include in '1,2,3'  
{{else}}
'1' not include in '1,2,3'  
{{/include}}
---
{{#include 'b' 'c,d'}}
'b' include in 'c,d'  
{{else}}
'b' not include in 'c,d'  
{{/include}}

输出:

'1' include in '1,2,3'  
---
'b' not include in 'c,d'  

3. 等于

  • 源码
hbs.registerHelper('equal', function (args1, args2, context) {  
    if (args1 === args2) {
        //满足添加继续执行
        return context.fn(this);
    } else {
        if (typeof(args1) === 'number' && args1.toString() === args2.toString()) {
            return context.fn(this);
        }
        //不满足条件执行{{else}}部分
        return context.inverse(this);
    }
});
  • 使用
{{#equal 1 2}}
1 === 2  
{{else}}
1 !== 2  
{{/equal}}

输出:

1 !== 2  

4. 大于等于

  • 源码
hbs.registerHelper('egt', function (args1, args2, context) {  
    if (args1 >= args2) {
        return context.fn(this);
    } else {
        return context.inverse(this);
    }

});
  • 使用同equal

5. 大于

  • 源码
hbs.registerHelper('gt', function (args1, args2, context) {  
    if (args1 > args2) {
        return context.fn(this);
    } else {
        return context.inverse(this);
    }

});
  • 使用同equal

6. 小于等于

  • 源码
hbs.registerHelper('elt', function (args1, args2, context) {  
    if (args1 <= args2) {
        return context.fn(this);
    } else {
        return context.inverse(this);
    }

});
  • 使用同equal

7. 小于

  • 源码
hbs.registerHelper('lt', function (args1, args2, context) {  
    if (args1 < args2) {
        return context.fn(this);
    } else {
        return context.inverse(this);
    }

});
  • 使用同equal

8. 结合each实现遍历N次

  • 源码
hbs.registerHelper('count', function (args1, context) {  
    let array = [];
    for (let i = 1; i <= args1; i++) {
        array.push(i);
    }
    return context.fn(array);
});
  • 使用
{{#count 5}}
  {{#each this |index|}}
    {{index}}、
  {{/each}}
{{/count}}

输出:

1、2、3、4、5  

9. 加法

  • 源码
hbs.registerHelper('add', function (args1, args2) {  
    return args1 + args2;
});
  • 使用
{{add 1 2}}

输出:

3  

10. 减法

  • 源码
hbs.registerHelper('sub', function (args1, args2) {  
    return args1 - args2;
});
  • 使用
{{sub 3 1}}

输出:

2  

Atom配置emmet快速编码

2016-05-15

Emmet 的前身是大名鼎鼎的 Zen coding,从事 Web 前端开发的同学对该插件一定不会陌生。在编写 html 时它使用仿 CSS 选择器的语法来生成代码,大大提高了 HTML/CSS 代码编写的速度。atom 默认是没有支持 emmet 的,需要我们自己安装。

安装

执行 apm install emmet 或者进入 atom 插件安装界面,搜索 emmet 完成安装

配置

大多数人应该习惯 tab 触发 emmet 快速生成代码,在 atom 中,我们可以配置自定义快捷键达到我们想要的效果。

  • 找到 keybinding > your keymap file ,打开 keymap.cson 配置文件

  • 添加如下配置:

'atom-text-editor[data-grammar="YOUR GRAMMAR HERE"]:not([mini])':  
    'tab': 'emmet:expand-abbreviation-with-tab'

YOUR GRAMMAR HERE 是你想要支持的语法,可在编辑代码时打开 atom 审查元素窗口,找到<atom-text-editor> 标签,例如,html 的 grammar 是 text html basic. 以下是我的配置。

'atom-text-editor[data-grammar="source js jsx"]:not([mini]),atom-text-editor[data-grammar="text html basic"]:not([mini])':  
    'tab': 'emmet:expand-abbreviation-with-tab'

MySQL配置外网访问

2016-05-01

有时需要在外网访问mysql以便管理。下面简单阐述一下我的执行的步骤:

1.以root身份登入mysql

mysql -u root -p  

2.创建可外网登陆用户

CREATE USER  
    'custom'@'%.example.com'
IDENTIFIED BY  
    'user_password';

3.为用户授权

GRANT  
    SELECT,INSERT,UPDATE,DELETE,CREATE,DROP  
ON  
    customer.*
TO  
    'custom'@'%';

4.检查/etc/mysql/my.cnf,去掉绑定ip

5.重启服务

sudo service mysql restart  

Checkbox美化

2015-12-17

原生的单选框和复选框相貌有些寒碜,大多数情况需要根据我们的界面需求去整个容。然而直接为Checkbox和Radio编写CSS样式一般也是不能达到我们想要的效果。

自己的项目中,使用过iCheck插件,多套皮肤可以使用,可以满足一部分需求(有兴趣的可以到官方网站了解)。但是个人不太喜欢其图片替换原生效果的方式,页面加载速度不佳的时候,能明显感觉到原生的效果一闪而过。

我们可以尝试自己使用CSS去美化使用的Checkbox和Radio,主要利用了CSS的+、:checked两个选择器和WebFont。

  • 样式代码
//样式代码使用scss编写,webfont使用[fontello](http://fontello.com/)得到。
@font-face {
  font-family: 'webfonts';
  src: url('../font/webfonts.eot?35182241');
  src: url('../font/webfonts.eot?35182241#iefix') format('embedded-opentype'),
  url('../font/webfonts.woff?35182241') format('woff'),
  url('../font/webfonts.ttf?35182241') format('truetype'),
  url('../font/webfonts.svg?35182241#webfonts') format('svg');
  font-weight: normal;
  font-style: normal;
}
body * {  
  box-sizing: border-box;
}
.custom-check {
  position: relative;
  padding-left: 20px;
  display: inline-block;
  input[type="checkbox"],
  input[type="radio"] {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
    height: 22px;
    width: 22px;
    margin: 0;
    padding: 0;
    opacity: 0;
    & + label {
      position: relative;
      display: inline-block;
      height: 20px;
      margin: 0;
      padding-left: 10px;
      vertical-align: middle;
      line-height: 20px;
      font-size: 14px;
      font-weight: 400;
      cursor: pointer;
      &::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        display: block;
        width: 20px;
        height: 20px;
        margin-left: -20px;
        border: 1px solid #e4eaec;
        background-color: #fff;
        -webkit-transition: all .3s ease-in-out 0s;
        -o-transition: all .3s ease-in-out 0s;
        transition: all .3s ease-in-out 0s;
      }
    }
  }
  input[type="checkbox"] {
    & + label {
      &::before {
        border-radius: 2px;
      }
    }
  }
  input[type="checkbox"]:checked {
    & + label {
      &::before {
        background-color: #0691cd;
        border-color: darken(#0691cd, 2%);
      }
      &::after {
        content: '\e800';
        position: absolute;
        top: 0;
        left: 0;
        display: block;
        width: 22px;
        height: 22px;
        padding-top: 2px;
        margin-left: -20px;
        font-family: "webfonts";
        color: #ffffff;
        text-align: center;
        line-height: 20px;
      }
    }
  }
  input[type="radio"] {
    & + label {
      &::before {
        border-radius: 100%;
      }
    }
  }
  input[type="radio"]:checked {
    & + label {
      &::before {
        background-color: #0691cd;
        border-color: darken(#0691cd, 2%);
      }
      &::after {
        content: ' ';
        position: absolute;
        top: 6px;
        left: 6px;
        display: block;
        width: 6px;
        height: 6px;
        margin-left: -20px;
        border: 2px solid #ffffff;
        border-radius: 100%;
      }
    }
  }
}
  • 使用代码
<div class="custom-check">  
    <input type="checkbox" id="checkbox"/>
    <label for="checkbox">复选框</label>
</div>  
<div class="custom-check">  
    <input type="radio" id="radio"/>
    <label for="radio">单选框</label>
</div>  
  • 效果

美化后效果