node-notifierでES6とSCSSをコンパイルした時のエラー内容をデスクトップに通知させる

node-notifierとはWindows/Mac/Linuxのデスクトップに通知を出すライブラリです。これを使うと簡単にデスクトップに通知を発行できます。

node-notifierを使ってES6とSCSSをコンパイルした時のエラー内容をデスクトップに通知させると開発がかなり捗るようになったので以下に手順を記しておきます。
ちなみにコンパイルにはgulpを使用しています。

手順

依存パッケージをインストール

npm install gulp gulp-sass gulp-watch gulp-plumber gulp-notifier gulp-babel node-notifier

※ gulp-plumberを使用するとwatchプロセスでファイルを監視中にエラーが起きてもプロセスが落ちなくなります。

gulpfile.js

プロジェクトのルートディレクトリの直下にscss,css,buildディレクトリがある場合は以下になります。

var gulp = require('gulp');
var watch = require('gulp-watch');
var plumber = require('gulp-plumber');
var notifier = require('node-notifier');
var sass = require('gulp-sass');
var babel = require('gulp-babel');


function onError(msg){
    //エラーが出力されたらデスクトップにメッセージを通知させる。
    var type = msg.name;
    var msg = msg.message;
    notifier.notify({
        'title': type,
        'message': msg
    });
};

gulp.task('sass',function(){
    //scssをコンパイルする。
    gulp.src('./scss/**/*.scss')
               .pipe(sass())
               .on('error',onError)
               .pipe(gulp.dest('./css'));
});

gulp.task('babel',function(){
    //ES6をコンパイルする。
    gulp.src('src/**/*.js')
    .pipe(plumber())
    .pipe(babel())
    .on('error',onError)
    .pipe(gulp.dest('build'));
});

gulp.task('watch', function() {
    //ファイルに変更があればコンパイルする。
    var srcJS = 'src/**/*.js';
    var gulpSCSS = 'scss/**/*.scss';
    gulp.watch(srcJS,['babel']);
    gulp.watch(gulpSCSS,['sass']);
});

[Django] WhiteNoiseを使って静的ファイルを配信する

WhiteNoiseとは?

WhiteNoiseとはWSGIアプリケーションのための静的ファイルを配信するのを簡単にしてくれるライブラリです。
少しの設定をするだけでAmazon S3やNginxに頼ることなく静的ファイルを配信できます。
本番サーバーで画像やcss等を参照できるようにするには色々と手順を踏まないといけなかったのですが、WhiteNoiseを使うとそのような手間が省けて大変便利です。

Install

$pip install whitenoise

settings.py

BASE_DIR = os.path.dirname(os.path.abspath(__file__))

STATIC_ROOT = 'staticfiles'
STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'

wsgi.py

from django.core.wsgi import get_wsgi_application
from whitenoise.django import DjangoWhiteNoise

application = get_wsgi_application()
application = DjangoWhiteNoise(application)

静的ファイルをSTATICFILES_STORAGEにコピーする

$python manage.py collectstatic

Done!

これで本番サーバーでも静的ファイルを参照できるようになります。

UITableViewCellがタップされた時の背景色を変更する

UITableViewCellのUITableViewCellSelectionStyleを変更すればよい。
標準では以下の4種類のスタイルが用意されてある。

  • UITableViewCellSelectionStyle.Default
  • UITableViewCellSelectionStyle.Blue
  • UITableViewCellSelectionStyle.Gray
  • UITableViewCellSelectionStyle.None

例えば、背景色を表示させないようにする場合は以下の実装になる。

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell            {

    let cell = tableView.dequeueReusableCellWithIdentifier("UniqCell") as! UITableViewCell
    cell.selectionStyle = UITableViewCellSelectionStyle.None

}

上の4種類に含まれていない背景色にするには、selectedBackgroundViewに任意の色のUIViewを代入すれば実現できる。
赤色にする場合は以下のようになる。

...
// selectionStyleを使用しないので、UITableViewCellSelectionStyleNoneを設定。
cell.selectionStyle = UITableViewCellSelectionStyleNone
let selectedView = UIView()
selectedView.backgroundColor = UIColor.redColor()
cell.selectedBackgroundView =  selectedView

録音している時の音量を可視化するAudioMeterViewを作った

AudioMeterViewというライブラリを作りました。

AudioMeterViewを使うと、録音している時の音量をプログレスバー形式で表示することができます。

上のgifアニメのコードは以下のようになります。


import UIKit
import AVFoundation

class ViewController: UIViewController,AVAudioRecorderDelegate {
    @IBOutlet var audioMeterView: AudioMeterView! = AudioMeterView()
    var timer:NSTimer!
    var loaded:Bool = false
    var fname:String!
    var currentPath:NSURL!
    var soundRecorder:AVAudioRecorder!


    override func viewDidLoad() {
        super.viewDidLoad()
        self.setupRecorder()
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        if self.loaded == false {
            // setup audiometerView  
            self.audioMeterView.setup(0.4, backgroundColor: UIColor.lightGrayColor(), overLayColor: UIColor.redColor())
        }
    }

    func record(path:NSURL){
        let audioSession:AVAudioSession = AVAudioSession.sharedInstance()
        try! audioSession.setCategory(AVAudioSessionCategoryRecord)
        try! audioSession.setActive(true)
    }


    func setupRecorder(){
        self.fname = NSUUID().UUIDString + ".caf"
        let documentDirectoryURL = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
        let fileDestinationUrl = NSURL(string: documentDirectoryURL)!.URLByAppendingPathComponent(fname)
        self.currentPath = fileDestinationUrl
        self.record(self.currentPath)

        let recordSettings:[String:AnyObject] = [
            AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
            AVEncoderAudioQualityKey: AVAudioQuality.Max.rawValue,
            AVEncoderBitRateKey: 320000,
            AVNumberOfChannelsKey: 2,
            AVSampleRateKey: 44100.0
        ]


        self.soundRecorder = try! AVAudioRecorder(URL: self.currentPath, settings: recordSettings)
        self.soundRecorder.updateMeters()
        self.soundRecorder.delegate = self
        self.soundRecorder.prepareToRecord()
        self.soundRecorder.meteringEnabled = true


    }





    @IBAction func onToggleRecord(button: UIButton) {
        // Record/Stopボタンが押された時の挙動
        if button.titleLabel!.text == "Record" {
            button.setTitle("Stop", forState: .Normal)
            self.timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "updated", userInfo: nil, repeats: true)
            self.soundRecorder.record()
        }else{
            button.setTitle("Record", forState: .Normal)
            self.soundRecorder.stop()
            self.timer.invalidate()
        }




    }


    func updated(){
        //0.4秒ごとに音量を取得してself.audioMeterViewに反映させる
        self.audioMeterView.updateRecorderMeter(self.soundRecorder, duration: 0.4, channel: 0)
    }


AudioMeterViewのGitHubのリンクからサンプルプロジェクトをダウンロードできます。