<戻る(Back
【Xcode】プリプロセッサ >> macOSとiOSの処理分け

最終更新日:2024/9/25

							
#if os(macOS)
#elseif os(iOS)
#endif
							
						
参考元サイト: https://zenn.dev/fummicc1/articles/47dc53090e92ff
【Swift(SwiftUI)】 >> 通知

最終更新日:2024/9/26

[(プロジェクト名)App.swift]

							
import SwiftUI

@main
struct USBHostControllerApp: App
{
	#if os(macOS)
	@NSApplicationDelegateAdaptor private var appDelegate: AppDelegate
	#elseif os(iOS)
	@UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
	#endif

	var body: some Scene {
		WindowGroup {
			ContentView()
		}
	}
}
							
						

[ContentView.swift]

							
import Foundation
import SwiftUI

struct ContentView: View
{
    var body: some View {
        VStack( spacing: 20 ) {
            Button
            {
                NotificationCenter.default.post(name: notifyName, object: nil)
            } label: { Text("Send Notify-Test") }
        }
        .font(.system(size: 32, weight: .heavy))
        .onAppear()
        .onDisappear()
    }
}
							
						

[AppDelegate.swift]

							
import SwiftUI
import UserNotifications

/* アプリがフォアグラウンドにある時でも通知を受け付ける */
class AppDelegate: NSObject
{
}

#if os(macOS)
extension AppDelegate: NSApplicationDelegate
{
    func applicationDidFinishLaunching(_ notification: Notification)
    {
        UNUserNotificationCenter.current().delegate = self
        NotificationPopup.start()
    }
}
#elseif os(iOS)
extension AppDelegate: UIApplicationDelegate
{
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool
    {
        UNUserNotificationCenter.current().delegate = self
        NotificationPopup.start()
        return true
    }
}
#endif
extension AppDelegate: UNUserNotificationCenterDelegate
{
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
    {
        return completionHandler([.list, .banner, .sound])
    }
    
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async
    {
    }
}
							
						

[NotificationPopup.swift(自作のクラス名.swift)]

							
import Foundation
import UserNotifications

let notifyName = Notification.Name("ECNotification")

class NotificationPopup
{
    static let mainQueue = OperationQueue.main
    static var content = UNMutableNotificationContent()
    static let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 3, repeats: false)
    
    static func start()
    {
        /* 通知許可をユーザに申請 */
        userNotificationCenter.requestAuthorization(options: [.alert])
        {
            authorized, error in guard authorized else { return }
        }
        
        var token = NotificationCenter.default.addObserver(forName: notifyName, object: nil, queue: mainQueue)
        {
            (note) in Task { await NotificationPopup.notificationAsync(title: "Test Notification", message: "Receive Notify") }
        }
    }

    static func notificationAsync(title: String, message: String) async
    {
        do
        {
            //通知内容
            content.title = title
            content.body = message
            content.sound = UNNotificationSound.default
            content.badge = 1
            //通知リクエストを作成
            var request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
            
        try await UNUserNotificationCenter.current().add(request)
        }
        catch
        {
        }
    }
}
							
						

[(通知のデリゲートが定義したクラス).swift(自作のクラス名.swift)]

							
import Foundation

public protocol MyNotificationDelegate
{
    func receiveNotify()
}
public class MyNotification
{
    var delegate: MyNotificationDelegate?

    init() { }

    public func start()
    {
    	delegate?.receiveNotify()
    	(本当はここで、Notificationハンドルが必要なフレームワークなどの関数から呼び出す)
    }
}
							
						

[(通知を受け付けるクラス).swift(自作のクラス名.swift)]

							
import Foundation

struct ReceiveNotify: MyNotificationDelegate
{
    let NotifyToken = MyNotification()
    init() {
        NotifyToken.delegate = self
        NotifyToken.start()
    }
}
extension ReceiveNotify
{
    func receiveNotify()
    {
    	Task { await NotificationPopup.notificationAsync(title: "", message: "") }
    }
}
							
						

【Swift】コーディング

最終更新日:2024/9/26

struct宣言のものに対して、NSObjectを継承する事はできない

framework由来のdelegateは、classじゃないと実装できない(implementも)

struct宣言をextensionはできない

iOSは、View内でのinit()をサポートしていない(以下参考

							
import Foundation
import SwiftUI

struct ContentView: View
{
    var body: some View {
        VStack( spacing: 20 ) {
            Button
            {
                NotificationCenter.default.post(name: notifyName, object: nil)
            } label: { Text("Send Notify-Test") }
        }
    }
    // MacOSならできるが、iOSでinit()はエラーになる
    init() {
    }
}
							
						

NSObjectを継承したクラスでinit()を実装するならoverrideしないといけない(以下参考

最終更新日:2024/9/27

							
import Foundation

class Test: NSObject
{
    // こうしないといけない
    override init() {
    	super.init()
    }
}
							
						

オプショナル型(_、?、!)

最終更新日:2024/9/27

							
func F1(_ arg: String)	<- _は、ラベルの省略の意味

var a: String?		<- ?はnil(null)許容型で宣言している

let b: String = a!	<- !はnil(null)かもしれない変数を代入する場合