20200801のMacに関する記事は4件です。

【Unity】Macでバージョン管理ができる? SnailSVNを解説

これまでWindowsで利用していたリポジトリをMacで利用する必要が出てきたので
今回はMacでSubversion利用するためのソフトの紹介や設定方法
Windowsリポジトリをチェックアウトするところまでを解説したいと思います。

本文はこちらです。
https://tedenglish.site/how-to-manage-unity-project-svnmac/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Mac】MacのOSアップデートを実施する

<< 【Mac】MacOSの基本操作を覚える

MacOSを最新版にする

WindowsUpdateと同じくMacもしっかりとバージョンアップしておかないとね。
インターネットに接続できたら最初に実施しましょう。

現状のバージョンを把握する

まずは現状のバージョン把握を行いますかね。

01.png

[アップルマーク(っていうのかな?)] - [このMacについて] をクリックします。

02.png

[システムレポート...]をクリックして、関係しそうなところを確認してみましょう。

03.png

ソフトウェアが関係しそうなので確保しました。

アップデートを実施する

02.png!

先ほどの画面の[ソフトウェア・アップデート...]をクリックします。

03.png

アップデートがあることが表示されるので、[今すぐアップデート]をクリックします。

[Macを自動的に最新の状態に保つ]のチェックを有効にするかどうかは任意ですよねー。

今回は個人で勉強がてら利用するつもりなのでアップデートも意識しながら作業したい。
そんなわけでチェックはつけずにすすめることにします。

04.png

始まりそうな問いかけがきました。
[ダウンロードして再起動]をクリックするとアップデートが始まります。

05.png

時間がそこそこかかるので別作業していると、OS再起動する瞬間を見逃しました(笑)

最新のバージョンを確認する

改めてバージョン情報を確認してみましょう。

07.png

あがってますね。

項目 アップデート前 アップデート後
システムのバージョン macOS 10.15.1(19888) macOS 10.15.6(19G73)
カーネルのバージョン Darwin 19.0.0 Darwin 19.6.0

他に確認すべき項目があるのかしら?気づけば追々追加しましょうかね。

お疲れ様でした。


2020-08-01 初稿

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】ゼロからのCombineフレームワーク - とりあえずViewにデータバインディングしたいための人の最小実装

意外と難しかったCombine

RxSwiftならある程度使えるし、簡単に使えるようになるかな?と思っていました。
しかし、いざ試してみるとなかなか苦労したので、まずは普段の開発に取り入れられる部分から切り出してみました。

Viewに値をバインドする最小実装 UIKit版

import Combine
import UIKit

class ViewModel {
    @Published var labelText: String = "Default value."
}

class ViewController: UIViewController {
    var label: UILabel! // 適当な場所(storyboard, viewDidLoadなど)で初期化する
    let viewModel = ViewModel()

    private var cancellables = Set<AnyCancellable>()

    override func viewDidLoad() {
        super.viewDidLoad()

        viewModel.$labelText
            .map({ Optional($0) })
            .receive(on: DispatchQueue.main)
            .assign(to: \UILabel.text, on: label)
            .store(in: &cancellables)
    }
}

適当なタイミングで、viewModel.labelText = "Hello!"などと値を変更すると、自動的にUILabelが更新されます。

解説

@PublishedPublisherプロトコル

バインドしたいプロパティの変更を監視するために、import Combineしたうえで、@PublishedというProperty Wrapperをバインドしたいプロパティに付与します。

ViewModel
class ViewModel {
    @Published var labelText: String = "Default value."
}

Property Wrapperを付与したプロパティをもつクラスには、自動的に$labelTextのようにプロパティ名の先頭に$がついたgetterが生成されます。@Publishedを付与した場合、このgetterはPublished<Output>.Publisher型になります。

Publisherというのが監視される側のプロトコルです(RxSwiftならObservable)。また、この場合Output = Stringです。

バインド

Publisherに準拠したプロパティをUIViewにバインドするには、assignメソッドを使います。

viewModel.$labelText
    .map({ Optional($0) })
    .receive(on: DispatchQueue.main)
    .assign(to: \UILabel.text, on: label)
    .store(in: &cancellables)

assign

assignメソッドの定義は次のようになっています。

public func assign<Root>(to keyPath: ReferenceWritableKeyPath<Root, Self.Output>, on object: Root) -> AnyCancellable

keyPathには\UILabel.text1のようにバインド先のUIViewの型名とそのプロパティ名を記載します。

assignメソッドはAnyCancellableというCancellableプロトコルに準拠したクラスのインスタンスを返します。このインスタンスのcancelメソッドを呼ぶことでバインド(監視)が解除されます。

また、AnyCancellableのインスタンスはメモリから解放されるタイミングでもcancelメソッドを呼んでバインドを解除するようです2。そのため、ViewControllerSet<AnyCancellable>型のプロパティを持たせて参照を保持します。追加する際にチェーンでメソッドを呼べるようにstoreメソッドが用意されています。

map

Publisherには様々なオペレーターが用意されており、監視している値に変更を加えたり、流れてくる時間や回数などの条件によって流れをせきとめたりすることができます。

mapはもっとも基本的なオペレーターで、流れてきた値を加工することができます。
ここでは、UILabel.text: String?の型に合わせて、ViewModel.labelText: StringOptional型に変換しています。

receive(on: DispatchQueue.main)

receive(on:)はメソッドチェーンのうちで、このメソッド以降のチェーン内の処理が行われるスレッドを指定することができます。

assignメソッドはUIの更新処理にあたるので、メインスレッドを指定しています。

Viewに値をバインドする最小実装 SwiftUI版

import Combine
import SwiftUI

class ViewModel: ObservableObject {
    @Published var labelText: String = ""
}

struct ContentView: View {
    @ObservedObject private var viewModel = ViewModel()

    var body: some View {
        NavigationView {
            VStack {
                Text(viewModel.labelText)
                TextField("Title", text: $viewModel.labelText)
                    .multilineTextAlignment(.center)
            }
        }
    }
}

解説

@ObservedObject/ObservableObject

SwiftUIのViewにバインドするには、バインドしたいプロパティをもつviewModel@ObservedObjectを付与します。
ObservableObjectプロトコルに準拠させることで、@ObservedObjectが付与できるようになります。)

struct ContentView: View {
    @ObservedObject private var viewModel = ViewModel()
    ...
}

class ViewModel: ObservableObject {
    @Published var labelText: String = ""
}

バインド

var body: some View {
    NavigationView {
        VStack {
            Text(viewModel.labelText)
            TextField("Title", text: $viewModel.labelText)
                .multilineTextAlignment(.center)
        }
    }
}

@ObservedObjectを付与したプロパティはViewに監視されるようになり、値の変更があればUIが自動更新されます。
そのため、通常のString型を引数にとるクラスではviewModel.labelTextを渡すだけでバインド完了です。

@ObservedObjectによって生成された$viewModelプロパティのlabelTextBinding<String>という型を返します。これをBinding<String>型を引数にとるTextFieldに渡すことによって、双方向バインディングとなります。

こちらのSwiftUI版では、viewModel.labelTextの値を変更するとTextTextFieldの値が更新されますし、キーボードからTextFieldを変更しても、viewModel.labelText(とText)の値が更新されます。


  1. バックスラッシュはKey-Pathを表現するときの記法です。ドキュメントはこちら Key-Path Expression 

  2. ドキュメントに記述を見つけられなかったのですが、参照を保持しなかった場合はviewDidLoadを抜けた時点でcancelが呼ばれていました。 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】ゼロからのCombineフレームワーク - UIKitでデータバインディング

意外と難しかったCombine

RxSwiftならある程度使えるし、簡単に使えるようになるかな?と思っていました。
しかし、いざ試してみるとなかなか苦労したので、まずは普段の開発に取り入れられる部分から切り出してみました。

UIKitに値をバインドする

import Combine
import UIKit

class ViewModel {
    @Published var labelText: String = "Default value."
}

class ViewController: UIViewController {
    var label: UILabel! // 適当な場所(storyboard, viewDidLoadなど)で初期化する
    let viewModel = ViewModel()

    private var cancellables = Set<AnyCancellable>()

    override func viewDidLoad() {
        super.viewDidLoad()

        viewModel.$labelText
            .map({ Optional($0) })
            .receive(on: DispatchQueue.main)
            .assign(to: \UILabel.text, on: label)
            .store(in: &cancellables)
    }
}

適当なタイミングで、viewModel.labelText = "Hello!"などと値を変更すると、自動的にUILabelが更新されます。

解説

@PublishedPublisherプロトコル

バインドしたいプロパティの変更を監視するために、import Combineしたうえで、@PublishedというProperty Wrapperをバインドしたいプロパティに付与します。

ViewModel
class ViewModel {
    @Published var labelText: String = "Default value."
}

Property Wrapperを付与したプロパティをもつクラスには、自動的に$labelTextのようにプロパティ名の先頭に$がついたgetterが生成されます。@Publishedを付与した場合、このgetterはPublished<Output>.Publisher型になります。

Publisherというのが監視される側のプロトコルです(RxSwiftならObservable)。また、この場合Output = Stringです。

バインド

Publisherに準拠したプロパティをUIViewにバインドするには、assignメソッドを使います。

viewModel.$labelText
    .map({ Optional($0) })
    .receive(on: DispatchQueue.main)
    .assign(to: \UILabel.text, on: label)
    .store(in: &cancellables)

assign

assignメソッドの定義は次のようになっています。

public func assign<Root>(to keyPath: ReferenceWritableKeyPath<Root, Self.Output>, on object: Root) -> AnyCancellable

keyPathには\UILabel.text1のようにバインド先のUIViewの型名とそのプロパティ名を記載します。

assignメソッドはAnyCancellableというCancellableプロトコルに準拠したクラスのインスタンスを返します。このインスタンスのcancelメソッドを呼ぶことでバインド(監視)が解除されます。

また、AnyCancellableのインスタンスはメモリから解放されるタイミングでもcancelメソッドを呼んでバインドを解除するようです2。そのため、ViewControllerSet<AnyCancellable>型のプロパティを持たせて参照を保持します。追加する際にチェーンでメソッドを呼べるようにstoreメソッドが用意されています。

map

Publisherには様々なオペレーターが用意されており、監視している値に変更を加えたり、流れてくる時間や回数などの条件によって流れをせきとめたりすることができます。

mapはもっとも基本的なオペレーターで、流れてきた値を加工することができます。
ここでは、UILabel.text: String?の型に合わせて、ViewModel.labelText: StringOptional型に変換しています。

receive(on: DispatchQueue.main)

receive(on:)はメソッドチェーンのうちで、このメソッド以降のチェーン内の処理が行われるスレッドを指定することができます。

assignメソッドはUIの更新処理にあたるので、メインスレッドを指定しています。

おまけ:SwiftUI版

import Combine
import SwiftUI

class ViewModel: ObservableObject {
    @Published var labelText: String = ""
}

struct ContentView: View {
    @ObservedObject private var viewModel = ViewModel()

    var body: some View {
        NavigationView {
            VStack {
                Text(viewModel.labelText)
                TextField("Title", text: $viewModel.labelText)
                    .multilineTextAlignment(.center)
            }
        }
    }
}

解説

@ObservedObject/ObservableObject

SwiftUIのViewにバインドするには、バインドしたいプロパティをもつviewModel@ObservedObjectを付与します。
ObservableObjectプロトコルに準拠させることで、@ObservedObjectが付与できるようになります。)

struct ContentView: View {
    @ObservedObject private var viewModel = ViewModel()
    ...
}

class ViewModel: ObservableObject {
    @Published var labelText: String = ""
}

バインド

var body: some View {
    NavigationView {
        VStack {
            Text(viewModel.labelText)
            TextField("Title", text: $viewModel.labelText)
                .multilineTextAlignment(.center)
        }
    }
}

@ObservedObjectを付与したプロパティはViewに監視されるようになり、値の変更があればUIが自動更新されます。
そのため、通常のString型を引数にとるクラスではviewModel.labelTextを渡すだけでバインド完了です。

@ObservedObjectによって生成された$viewModelプロパティのlabelTextBinding<String>という型を返します。これをBinding<String>型を引数にとるTextFieldに渡すことによって、双方向バインディングとなります。

こちらのSwiftUI版では、viewModel.labelTextの値を変更するとTextTextFieldの値が更新されますし、キーボードからTextFieldを変更しても、viewModel.labelText(とText)の値が更新されます。


  1. バックスラッシュはKey-Pathを表現するときの記法です。ドキュメントはこちら Key-Path Expression 

  2. ドキュメントに記述を見つけられなかったのですが、参照を保持しなかった場合はviewDidLoadを抜けた時点でcancelが呼ばれていました。 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む