【Apple WWDC24】Swift ネタをサンプルコードとともに眺めていくページ

いよいよです。



👉 WWDC24 - Apple Developer hatena-bookmark

Apple 公式の GitHub では、

「sample」

の prefix をつけてリポジトリを公開していますよね。

洗練されていて、Swift の方向性も示されてるようで。

👉 Repository search results hatena-bookmark

いや、もしかしたら、GitHub 公開は遅れるかもしれん。

(更新中 ...)



【macOS】Find and remove all .DS_Store files

🧑🏻‍💻 Terminal から .DS_Store を消す方法

MacのFinderは、各フォルダのメタデータを保存するために .DS_Store ファイルを生成します。しかし、これらのファイルが不要な場合や煩わしい場合もあります。カレントディレクトリ配下のすべての .DS_Store ファイルを確認するには、以下のコマンドを使用します。


find . -type f -name ".DS_Store"

このコマンドは、現在のディレクトリとそのサブディレクトリ内のすべての .DS_Store ファイルをリストアップします。次に、これらのファイルを一括で削除するには、以下のコマンドを実行します。


find . -type f -name ".DS_Store" -delete

これにより、指定されたディレクトリ以下のすべての .DS_Store ファイルが削除され、ディレクトリがクリーンになります。

 

🧑🏻‍💻 .DS_Store ファイルの自動作成を制御する方法

ネットワークドライブや外部ドライブにアクセスする際に .DS_Store ファイルが生成されるのを防ぎたい場合、以下のコマンドを使って自動生成を停止できます。


defaults write com.apple.desktopservices DSDontWriteNetworkStores True
killall Finder

この設定により、これらのドライブに対して .DS_Store ファイルが作成されなくなります。必要に応じて、再度作成を許可する場合は、以下のコマンドを実行します。


defaults write com.apple.desktopservices DSDontWriteNetworkStores False
killall Finder

これにより、元の設定に戻すことができます。

 

🧑🏻‍💻 まとめ

.DS_Store ファイルはFinderのメタデータを保存するために重要な役割を果たしますが、時には不要で煩わしいこともあります。Terminalを使用してこれらのファイルを削除したり、自動生成を制御する方法を知っておくと、作業環境を整えるのに役立ちます。また、macOSのバージョンによっては .DS_Store ファイルの仕様が変わることがあるため、新しいバージョンにアップデートした際には設定を再確認することが重要です。これにより、効率的でスムーズな作業環境を維持できます。

 

🧑🏻‍💻 まとめ

結局、消さないほうがいい。

制御するなら以下のどれかで。


// newtork drive
defaults write com.apple.desktopservices DSDontWriteNetworkStores true
defaults write com.apple.desktopservices DSDontWriteNetworkStores false

// removable drive
defaults write com.apple.desktopservices DSDontWriteUSBStores -bool true
defaults write com.apple.desktopservices DSDontWriteUSBStores -bool false

// finder
defaults write com.apple.finder AppleShowAllFiles -boolean false;killall Finder
defaults write com.apple.finder AppleShowAllFiles FALSE;killall Finder
defaults write com.apple.Finder AppleShowAllFiles TRUE;killall Finder
defaults write com.apple.finder AppleShowAllFiles -boolean true;killall Finder

.gitignore とかリモートクライアントの設定で操作するべし。

Apple の意図は汲んだほうがいいと思える。


【macOS】ルーターの注意喚起が出たら arp-scan がいいよ

ああ、ルーターの機種がもろ該当。

 

🛜 Buffalo バッファロー のルーターで注意喚起が出た

こういうの良く出てますけども。

対象の製品を利用していること、そしてWeb設定画面のパスワードが工場出荷時のまま、もしくは推測しやすい文字列を設定していることの両方を満たす場合には、bot感染の可能性がある。

👉 バッファローが一部Wi-Fiルーターで注意喚起、bot感染増加を受け パスワード変更やファームウェア更新を - ITmedia NEWS hatena-bookmark

1つは、一旦設定を初期化すること。「インターネット設定等を工場出荷時のまま利用されている場合は、可能な限り設定を初期化しご利用ください」との表現がされているが、工場出荷時の状態から利用し続けている場合、意図しない設定変更が行われているおそれがあるので、一度初期化したのち、以下の対策を行ってほしい、との意図だという。

 次に、パスワード(ここで指しているのは、Wi-Fi接続用のパスワードではなく、Web設定画面にログインするための管理パスワード)を推測されにくい複雑なものに変更するとともに、ファームウェアを更新すること。なお、WSR-600DHPは工場出荷時の状態でファームウェアが自動更新されるようになっているが、ほかの4製品は自動更新機能を持たないため、手動での更新が必要となる。

 最後に、Web設定画面の[詳細設定]-[管理]-[システム設定]にて、「Internet側リモートアクセス設定を許可する」が無効になっていることを確認すること。なお、設定の初期化を行った場合は、この設定は無効になるため、確認の必要はないという。

👉 【追記あり】バッファローのWi-Fiルーター「WSR-1166DHP」シリーズほかのボット感染が増加、NICTER解析チームが警告 - INTERNET Watch hatena-bookmark

脆弱性の話はいつもあいまいなはっきりしない対応策が多いので分かりづらい。

注意はすればするほど安全なのだろう。

バッファロー公式のアナウンスを見る。

👉 NICTERの投稿に関する重要なお知らせ(5/23更新) | バッファロー hatena-bookmark

調査中の雰囲気ですが、

「外部から管理画面にアクセスしてパスワードを突破されて何かを仕込まれる。」

ということですよね。

対処法としては、

- 外部からのアクセス機能をOFFにする。
- パスワードをややこしいものにする。
- ファームウェアを最新のものにする。

ということのようです。

「初期化」という言葉が話をややこしくしていますが、

どちらにしても、ルーターの設定を触る必要がありますね。

 

🛜 ルーターの管理画面

パソコンやスマホに公式設定アプリを入れて操作するのが簡単ですのでおすすめです。

👉 ソフトウェア | バッファロー hatena-bookmark

しかし、いちいちアプリを入れたくないですよね !

今どきの個人向けルーターは、

ほぼブラウザでアクセスできる管理画面を持っています。

そして、それぞれのOS上で動く設定アプリ内でも

そのネットワーク上に存在しているルーターの

ホスト名やIPアドレスを検出しているはずです。

ブラウザからIPアドレス直打ちで管理画面開きたいですよね!

 

🛜 IPアドレスを見つける

「arp-scan」を使います。


❯ brew install arp-scan


👉 royhills/arp-scan: The ARP Scanner hatena-bookmark

root 必要です。


❯ sudo arp-scan -l
Interface: en0, type: EN10MB, MAC: 63:7e:67:a2:cd:1f, IPv4: 192.168.151.16
Starting arp-scan 1.10.0 with 512 hosts (https://github.com/royhills/arp-scan)
192.168.151.11	84:a3:ec:9c:16:08	BUFFALO.INC
192.168.151.14	f8:3f:c2:31:d2:ee	Apple, Inc.

「BUFFALO」ありましたので、

まずは、コンソールからアクセスします。


❯ curl 192.168.151.11
<html>
<head>

<title>Redirect Page</title>
<meta http-equiv="expires" content="-1">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<SCRIPT language=JavaScript>
function init()
{
	top.location.replace("../login.html");
}
</SCRIPT>
</head>
<body onload='init();'>
<table><tr><td></td></tr></table>
</body>
</html>

❯ curl 192.168.151.11:443
curl: (7) Failed to connect to 192.168.151.11 port 443 after 16 ms: Couldn't connect to server

❯ curl 192.168.151.11:80
<html>
<head>

<title>Redirect Page</title>
<meta http-equiv="expires" content="-1">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<SCRIPT language=JavaScript>
function init()
{
	top.location.replace("../login.html");
}
</SCRIPT>
</head>
<body onload='init();'>
<table><tr><td></td></tr></table>
</body>
</html>

80 のみなので http のみです。

ブラウザから見ると login.html にリダイレクトされます。

あとは、ログインして公式アナウンスの推奨する対応策をやれば OK。

 

🛜 参考



【SwiftUI】iOS と macOS で互換したいコードの一つの解法

なるほどこうするのか。

iOS ↔ macOS と切り替えると、

ビルドで落ちて萎えるときの

一つの何かのきっかけに。

最新の SwiftUI ならシンプルです。


import SwiftUI

public extension Color {

    #if os(macOS)
    static let background = Color(NSColor.windowBackgroundColor)
    static let secondaryBackground = Color(NSColor.underPageBackgroundColor)
    static let tertiaryBackground = Color(NSColor.controlBackgroundColor)
    #else
    static let background = Color(UIColor.systemBackground)
    static let secondaryBackground = Color(UIColor.secondarySystemBackground)
    static let tertiaryBackground = Color(UIColor.tertiarySystemBackground)
    #endif
}

👉 ios - SwiftUI: Get the Dynamic Background Color (Dark Mode or Light Mode) - Stack Overflow hatena-bookmark

マルチなプラットフォーム作成時には、押さえておきたい記述です。



【SwiftUI】View を ドラッグ して移動 する

View をドラッグして動かします。


struct TestDragGesture: View {
  @State private var location = CGPoint(x: 150, y: 150)

  var body: some View {
    ZStack {
      VStack(alignment: .trailing) {
        Text("location.x: \(location.x)")
        Text("location.y: \(location.y)")
      }
      .monospaced()

      Circle()
        .fill(.red.opacity(0.5))
        .frame(width: 100)
        .position(location)
        .gesture(
          DragGesture()
            .onChanged { value in
              location = value.location
            }
        )
    }
  }
}

ドラッグ位置が変化するたびに View の位置を更新できます。

var location: CGPoint
The location of the drag gesture’s current event.

👉 DragGesture.Value | Apple Developer Documentation hatena-bookmark

Circle の position は Viewの中心

であることに対して

DragGesture().onChanged() で取得したドラッグ位置

とずれがあるため、

タップ位置を動かした瞬間に中心位置にジャンプしてしまいます。

なんか違和感がありますね !

 

👩🏼‍💻 startLocation と translation

計算方法を変えます。

以下を使います。

var startLocation: CGPoint
The location of the drag gesture’s first event.

var translation: CGSize
The total translation from the start of the drag gesture to the current event of the drag gesture.

👉 DragGesture.Value | Apple Developer Documentation hatena-bookmark


Circle()
  .fill(.red.opacity(0.5))
  .frame(width: 100)
  .position(location)
  .gesture(
    DragGesture()
      .onChanged { value in
        var newLocation = startLocation ?? location
        newLocation.x += value.translation.width
        newLocation.y += value.translation.height
        location = newLocation
      }
      .updating($startLocation) { _, startLocation, _ in
        startLocation = startLocation ?? location
      }
   )

Circle の中心位置に対して、ドラッグの移動量を増減することで、なめらかに違和感なく動くようになりました !



簡単なコードに見えますが、updating を使った位置情報の入れ替えとか、よくみると深い。

👉 updating(_:body:) | Apple Developer Documentation hatena-bookmark
👉 Move your view around with Drag Gesture in SwiftUI | Sarunw hatena-bookmark

しかし、なんか見通しが悪い。

@GestureState と updating() は使いづらい。

 

👩🏼‍💻 まとめ

これでいきます。



キモは、

「ドラッグの移動量を View のポジションに適用」

「ドラッグ開始時のドラッグ位置とView中心のズレ」