| 
									
										
										
										
											2025-09-15 15:54:03 +08:00
										 |  |  |  | import UIKit | 
					
						
							|  |  |  |  | import Flutter | 
					
						
							|  |  |  |  | import AVFoundation | 
					
						
							| 
									
										
										
										
											2025-07-11 11:03:21 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-15 15:54:03 +08:00
										 |  |  |  | @main | 
					
						
							|  |  |  |  | @objc class AppDelegate: FlutterAppDelegate { | 
					
						
							|  |  |  |  |   // 动态方向掩码(默认竖屏) | 
					
						
							|  |  |  |  |   static var orientationMask: UIInterfaceOrientationMask = .portrait | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-15 15:54:03 +08:00
										 |  |  |  |   override func application( | 
					
						
							|  |  |  |  |     _ application: UIApplication, | 
					
						
							|  |  |  |  |     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? | 
					
						
							|  |  |  |  |   ) -> Bool { | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-15 15:54:03 +08:00
										 |  |  |  |     let controller = window?.rootViewController as! FlutterViewController | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 1) orientation channel (你已有) | 
					
						
							|  |  |  |  |     let orientationChannel = FlutterMethodChannel(name: "app.orientation", | 
					
						
							| 
									
										
										
										
											2025-08-27 16:14:50 +08:00
										 |  |  |  |                                            binaryMessenger: controller.binaryMessenger) | 
					
						
							| 
									
										
										
										
											2025-09-15 15:54:03 +08:00
										 |  |  |  |     orientationChannel.setMethodCallHandler { [weak self] call, result in | 
					
						
							|  |  |  |  |       guard let self = self else { return } | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-15 15:54:03 +08:00
										 |  |  |  |       if call.method == "setOrientation" { | 
					
						
							|  |  |  |  |         guard let arg = call.arguments as? String else { | 
					
						
							|  |  |  |  |           result(FlutterError(code: "BAD_ARGS", message: "need 'landscape' | 'portrait'", details: nil)) | 
					
						
							|  |  |  |  |           return | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-15 15:54:03 +08:00
										 |  |  |  |         // 先更新允许的方向掩码 | 
					
						
							|  |  |  |  |         if arg == "landscape" { | 
					
						
							|  |  |  |  |           AppDelegate.orientationMask = .landscape | 
					
						
							|  |  |  |  |         } else if arg == "portrait" { | 
					
						
							|  |  |  |  |           AppDelegate.orientationMask = .portrait | 
					
						
							|  |  |  |  |         } else { | 
					
						
							|  |  |  |  |           result(FlutterError(code: "BAD_ARGS", message: "unknown arg", details: nil)) | 
					
						
							|  |  |  |  |           return | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 再请求实际旋转 | 
					
						
							|  |  |  |  |         if #available(iOS 16.0, *) { | 
					
						
							|  |  |  |  |             // 通知顶层 VC:其 supportedInterfaceOrientations 需要刷新 | 
					
						
							|  |  |  |  |             self.window?.rootViewController?.setNeedsUpdateOfSupportedInterfaceOrientations() | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-15 15:54:03 +08:00
										 |  |  |  |           if let scene = self.window?.windowScene { | 
					
						
							|  |  |  |  |             let orientations: UIInterfaceOrientationMask = | 
					
						
							|  |  |  |  |               (arg == "landscape") ? .landscape : .portrait | 
					
						
							|  |  |  |  |             do { | 
					
						
							|  |  |  |  |               try scene.requestGeometryUpdate(.iOS(interfaceOrientations: orientations)) | 
					
						
							|  |  |  |  |             } catch { | 
					
						
							|  |  |  |  |               result(FlutterError(code: "GEOMETRY_UPDATE_FAILED", | 
					
						
							|  |  |  |  |                                   message: error.localizedDescription, details: nil)) | 
					
						
							| 
									
										
										
										
											2025-08-27 16:14:50 +08:00
										 |  |  |  |               return | 
					
						
							|  |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-09-15 15:54:03 +08:00
										 |  |  |  |           } | 
					
						
							|  |  |  |  |         } else { | 
					
						
							|  |  |  |  |           let target: UIInterfaceOrientation = | 
					
						
							|  |  |  |  |             (arg == "landscape") ? .landscapeLeft : .portrait | 
					
						
							|  |  |  |  |           UIDevice.current.setValue(target.rawValue, forKey: "orientation") | 
					
						
							|  |  |  |  |           UIViewController.attemptRotationToDeviceOrientation() | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-15 15:54:03 +08:00
										 |  |  |  |         result(true) | 
					
						
							|  |  |  |  |       } else { | 
					
						
							|  |  |  |  |         result(FlutterMethodNotImplemented) | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-15 15:54:03 +08:00
										 |  |  |  |     // 2) permissions channel (新增): 用于 iOS 原生请求相机访问权限 | 
					
						
							|  |  |  |  |     let permissionChannel = FlutterMethodChannel(name: "qhd_prevention/permissions", | 
					
						
							|  |  |  |  |                                                  binaryMessenger: controller.binaryMessenger) | 
					
						
							|  |  |  |  |     permissionChannel.setMethodCallHandler { (call: FlutterMethodCall, result: @escaping FlutterResult) in | 
					
						
							|  |  |  |  |         if call.method == "requestCameraAccess" { | 
					
						
							|  |  |  |  |             // AVCaptureDevice.requestAccess 会在首次调用时触发系统权限弹窗 | 
					
						
							|  |  |  |  |             AVCaptureDevice.requestAccess(for: .video) { granted in | 
					
						
							|  |  |  |  |                 DispatchQueue.main.async { | 
					
						
							|  |  |  |  |                     result(granted) | 
					
						
							| 
									
										
										
										
											2025-08-27 16:14:50 +08:00
										 |  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-09-15 15:54:03 +08:00
										 |  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2025-08-27 16:14:50 +08:00
										 |  |  |  |             result(FlutterMethodNotImplemented) | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-09-15 15:54:03 +08:00
										 |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-15 15:54:03 +08:00
										 |  |  |  |     GeneratedPluginRegistrant.register(with: self) | 
					
						
							|  |  |  |  |     return super.application(application, didFinishLaunchingWithOptions: launchOptions) | 
					
						
							|  |  |  |  |   } | 
					
						
							| 
									
										
										
										
											2025-08-21 16:44:24 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-15 15:54:03 +08:00
										 |  |  |  |   // 关键:把当前的掩码提供给系统 | 
					
						
							|  |  |  |  |   override func application(_ application: UIApplication, | 
					
						
							|  |  |  |  |                             supportedInterfaceOrientationsFor window: UIWindow?) | 
					
						
							|  |  |  |  |     -> UIInterfaceOrientationMask { | 
					
						
							|  |  |  |  |     return AppDelegate.orientationMask | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | } |