runo のすべての投稿

Mac ターミナルのカスタマイズ

bash

設定ファイル:.bash_profile

alias ls='ls -G'
alias l='ls -la'

emacs

設定ファイル:.emacs

(custom-set-variables
  ;; custom-set-variables was added by Custom -- don't edit or cut/paste it!
  ;; Your init file should contain only one such instance.
 '(case-fold-search t)
 '(global-font-lock-mode t nil (font-lock))
 '(show-paren-mode t nil (paren))
 '(transient-mark-mode t))
(custom-set-faces
  ;; custom-set-faces was added by Custom -- don't edit or cut/paste it!
  ;; Your init file should contain only one such instance.
 )

(setq make-backup-files nil)
(column-number-mode t)
(line-number-mode t)

Ubuntu 16.04 に autofs を入れる

特定のディレクトリーにアクセスした時に、自動的にデバイス(USBポータブルHDD等)をマウントする。

インストール


sudo apt-get install autofs

設定

/etc/auto.master を編集する。

設定例

次の行を/etc/auto.masterの最後に追加。

/-      /etc/auto.runodrive
  • 外部ファイル /etc/auto.runodrive に指定された各ディレクトリーを自動マウントするようにする。

/etc/auto.runodriveにデバイスの設定。

/media/runodrive        -fstype=exfat,rw,exec,auto,relatime,noatime,iocharset=utf8,user,umask=111,dmask=000             UUID=57F0-5FB5
  • デバイスのUUIDを知るには sudo blkid

再起動


sudo service autofs restart

ViewControllerを別のViewControllerの任意ビューにはめ込む処理

public extension UIView {

    public func fillSuperviewWithConstaints() {

        let constraints = NSLayoutConstraint.constraints(fillingSuperviewOf: self)

        if #available(iOS 8, *) {
            NSLayoutConstraint.activate(constraints)
        } else {
            if let superview = superview {
                superview.addConstraints(constraints)
            }
        }
    }

}

public extension NSLayoutConstraint {

    public static func constraints(fillingSuperviewOf view: UIView) -> [NSLayoutConstraint] {
        guard let superview = view.superview else {
            return []
        }

        return [NSLayoutConstraint(item: view, attribute: .top, relatedBy: .equal, toItem: superview, attribute: .top, multiplier: 1.0, constant: 0.0),
                NSLayoutConstraint(item: view, attribute: .bottom, relatedBy: .equal, toItem: superview, attribute: .bottom, multiplier: 1.0, constant: 0.0),
                NSLayoutConstraint(item: view, attribute: .leading, relatedBy: .equal, toItem: superview, attribute: .leading, multiplier: 1.0, constant: 0.0),
                NSLayoutConstraint(item: view, attribute: .trailing, relatedBy: .equal, toItem: superview, attribute: .trailing, multiplier: 1.0, constant: 0.0),
        ]
    }

}

public extension UIViewController {

    public func addChildViewController(_ childViewController: UIViewController, filling parentView: UIView, withContraints: Bool) {

        addChildViewController(childViewController)
        childViewController.didMove(toParentViewController: self)

        if let subView = childViewController.view {
            parentView.addSubview(subView)

            if withContraints {
                subView.translatesAutoresizingMaskIntoConstraints = false
                subView.fillSuperviewWithConstaints()
            } else {
                subView.frame = parentView.bounds
            }
        }
    }

}

Protocol and Value Oriented Programming in UIKit Apps

WWDC2016で、Swiftのstruct、protocol、enumの有効な使い方について紹介するセッションがあった。

Protocol and Value Oriented Programming in UIKit Apps (WWDC 2016 – Session 419)

そのセッションで使われたサンプルコードがこちら。

LucidDreams: Protocol and Value Oriented Programming Sample Code

とても興味深くて、勉強になると思ったが、まだマスターできていない。

Ubuntu 16.04 に Transmission daemon を入れる

インストール


sudo apt-get install transmission-daemon

設定

設定ファイルは /etc/transmission-daemon/settings.json

デーモンが停止(再起動)されるときに、設定ファイルが起動中の設定で上書きされる。
そのためデーモンを一旦停止してから編集する。


sudo service transmission-daemon stop

RPCと基本的な設定

RPCさえ利用可能にすれば、 他の重要な設定はウェブから変更できる。
次の設定を/etc/transmission-daemon/settings.json側で行う。

    "rpc-password": "password",
    "rpc-username": "admin",
    "rpc-port": 9091,
    "rpc-whitelist": "127.0.0.1",
    "rpc-whitelist-enabled": false,
    "umask": 2
    "download-dir": "/media/usbtmp/transmission",
  • rpc-passwordは、クリアにパスワードを入力してもOK。デーモンを起動したらハッシュに変換してくれる。
  • rpc-whitelist-enabledfalseにするか、rpc-whitelistに許可IP範囲(例:127.0.0.1,10.0.*.*)を設定するかで外部からのアクセスを可能にできる。
  • ファイルは全員が見れる用に umask を設定する。
  • download-dir に指定したパスにファイルがダウンロードされる。

RPCを設定したら、ウェブからアクセスできるようになるので、デーモンを起動し、ウェブ(http://ipaddress:9091/)を開く。


sudo service transmission-daemon start

その他設定

個人的に設定を変更にした箇所。

2c2
<     "alt-speed-down": 100, 
---
>     "alt-speed-down": 50, 
8c8
<     "alt-speed-up": 1, 
---
>     "alt-speed-up": 50, 
15c15
<     "download-dir": "/media/usbtmp/transmission", 
---
>     "download-dir": "/var/lib/transmission-daemon/downloads", 
20,22c20,22
<     "encryption": 2, 
<     "idle-seeding-limit": 1, 
<     "idle-seeding-limit-enabled": true, 
---
>     "encryption": 1, 
>     "idle-seeding-limit": 30, 
>     "idle-seeding-limit-enabled": false, 
43,44c43,44
<     "ratio-limit": 0.0098, 
<     "ratio-limit-enabled": true, 
---
>     "ratio-limit": 2, 
>     "ratio-limit-enabled": false, 
62,63c62,63
<     "speed-limit-up": 10, 
<     "speed-limit-up-enabled": true, 
---
>     "speed-limit-up": 100, 
>     "speed-limit-up-enabled": false, 

ゼロから Core Data を学ぶ

とりあえず読み書きができるまで

プロジェクト作成

Single View Application を作成。
ゼロから作成するので Use Core Data はチェックしない。

Data Model 追加

TestData と名前をつけてプロジェクトに追加。
TestData.xcdatamodeld/TestData.xcdatamodel が作成される。

テストモデルでデータの読み書き

TestModel という Entity を追加し、属性 text: String を追加。

ViewController にボタンを設置し、そのボタンを押すたびにモデルが増えるコードを書く。

import UIKit
import CoreData

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // データをロード
        print("load begin")
        container = NSPersistentContainer(name: "TestData")
        container.loadPersistentStores { (desc, error) in
            if let error = error {
                print("load error: \(error)")
            } else {
                print("load ok: \(desc)")
            }
        }
    }

    @IBAction func testButton(_ sender: Any) {

        let context = container.viewContext

        // データ追加、textに任意文字列設定
        let testModel = NSEntityDescription.insertNewObject(forEntityName: "TestModel",
                                                            into: context)
        testModel.setValue(UUID().uuidString, forKey: "text")

        // 保存
        try! context.save()

        // 列挙
        let request = NSFetchRequest<NSManagedObject>(entityName: "TestModel")
        let models = try! context.fetch(request)
        print("-- model count: \(models.count)")
        for model in models {
            let text = model.value(forKey: "text")!
            print("text: \(text)")
        }
    }

    var container: NSPersistentContainer!
}

ボタンを3回押したときの出力:

load begin
load ok: <NSPersistentStoreDescription: 0x60800004d9b0> (type: SQLite, url: file:///Users/rsahara/Library/Developer/CoreSimulator/Devices/D9D49483-571C-409D-87F2-88556CB3D351/data/Containers/Data/Application/C53CF83C-77F4-4719-BA87-242D158B3DC7/Library/Application%20Support/TestData.sqlite)
-- model count: 1
text: E4AA836E-3F59-4F96-B6EF-CB79EFFA57BB
-- model count: 2
text: E4AA836E-3F59-4F96-B6EF-CB79EFFA57BB
text: 3A64EDFE-D6B2-4C9D-A3AD-4D53DFAD4FFE
-- model count: 3
text: E4AA836E-3F59-4F96-B6EF-CB79EFFA57BB
text: 3A64EDFE-D6B2-4C9D-A3AD-4D53DFAD4FFE
text: F0690E43-8E0A-46B0-A491-482E3E407585

アプリを再起動しても、データは保存されている:

load begin
load ok: <NSPersistentStoreDescription: 0x600000241ce0> (type: SQLite, url: file:///Users/rsahara/Library/Developer/CoreSimulator/Devices/D9D49483-571C-409D-87F2-88556CB3D351/data/Containers/Data/Application/6DE5C1D8-FB7C-48F2-9A38-B2BDF0A8885C/Library/Application%20Support/TestData.sqlite)
-- model count: 4
text: E4AA836E-3F59-4F96-B6EF-CB79EFFA57BB
text: 3A64EDFE-D6B2-4C9D-A3AD-4D53DFAD4FFE
text: F0690E43-8E0A-46B0-A491-482E3E407585
text: F1E3B4FB-9BB9-49CA-B886-C4589A698A5F

Ubuntu 16.04 で USB ストレージを起動時にマウント

USBストレージをUUIDで参照し、特定のディレクトリにマウントする方法。

ストレージのUUIDを取得

一例:


sudo blkid
/dev/sdb1: LABEL="PORTABLE" UUID="6522-1DE5" TYPE="vfat"

fstab編集

/etc/fstab に適切に設定を追加。一例:

UUID=6522-1DE5 /media/usbtmp vfat rw,exec,auto,relatime,noatime,iocharset=utf8,user,umask=111,dmask=000 0 0

iOSアプリデータの保存

iOSアプリの開発を初めて以来、データを保存する際に考察したこと、改善したことが多々あるので、まとめて記事をQiitaにて書いた。

iOSアプリデータの保存 – Qiita

この状態に至るまで、開発中で出合った諸問題:

  • ストレージのスペースが足りなくてハングする問題。
  • Realmファイルがメモリに乗らない問題。
  • Realmファイルのマイグレーションで失敗して起動できない問題。
  • 使用しない無駄なキャッシュを蓄積してしまう問題。
  • キャッシュが増え続ける問題。

無用の用

松山大耕氏が書籍『ビジネスZEN入門』やサミット等で共有していた内容で印象に残ったこと。

仏教には「無用の用」ということばがある。

「水が一杯入ったコップに更に水を追加することはできない。
コップが空であることによって、水を入れられる。」

心も同じであり、
瞑想、座禅、マインドフルネスで心を空っぽにすることができる。

マインドフルネスはアメリカの大手企業もやっていて、免疫力が上がる効果もあるらしい。
ただし、座禅と比べると目的は異なる。
大手企業はマインドフルネスによるゲインを得ることを目的としているが、座禅はゲインを求めない。
座禅をするために座禅をするだけ。