実機でtestFlightをしたらクラッシュしないが、AppStoreConnectに審査に出すとクラッシュしたといわれた

実現したいこと

クラッシュの問題を解決し、AppStoreConnectの審査に通りたい

前提

xcodeのバージョンは15.1 iosは17.2、実機では一度もクラッシュした経験がない,ipadのシュミレーターではボタンが重なるなどの問題はない、

発生している問題・エラーメッセージ

コードではエラーメッセージが発生していない

該当のソースコード

import UIKit import SceneKit import ARKit import ReplayKit class ViewController: UIViewController, ARSCNViewDelegate, UITextFieldDelegate, RPPreviewViewControllerDelegate { @IBOutlet weak var Label1: UILabel! @IBOutlet weak var Label2: UILabel! @IBOutlet weak var textfield1: UITextField! @IBOutlet weak var textfield2: UITextField! @IBOutlet weak var jumpButtonPressed: UIButton! @IBOutlet weak var hozon: UIButton! @IBOutlet weak var sceneView2: SCNView! var isJumping = false var labelTimer: Timer? var isShowingLabel1 = true var isRecording = false let recorder = RPScreenRecorder.shared() override func viewDidLoad() { super.viewDidLoad() setupUI() setupScene() sceneView2.backgroundColor = UIColor.clear } func setupUI() { updateButtonTitle() textfield1.delegate = self textfield2.delegate = self setupGradientBackground() setupButtonStyles() setupScene() } func setupScene() { let scene = SCNScene() setupSceneView(scene) loadScene(named: "Flying.dae", into: scene) } func setupGradientBackground() { let gradientLayer = CAGradientLayer() gradientLayer.frame = view.bounds let topColor = UIColor(red: 144.0/255.0, green: 238.0/255.0, blue: 144.0/255.0, alpha: 1.0).cgColor let bottomColor = UIColor(red: 173.0/255.0, green: 255.0/255.0, blue: 47.0/255.0, alpha: 1.0).cgColor // gradientLayer.colors = [topColor, bottomColor] gradientLayer.locations = [0.0, 1.0] view.layer.insertSublayer(gradientLayer, at: 0) } func setupButtonStyles() { configureButtonStyle(jumpButtonPressed) configureButtonStyle(Button1) configureButtonStyle(Button2) configureButtonStyle(Button3) configureButtonStyle(Button4) let buttonAttributes: [NSAttributedString.Key: Any] = [ .font: UIFont.boldSystemFont(ofSize: 27), ] let attributedTitle = NSAttributedString(string: "再生", attributes: buttonAttributes) jumpButtonPressed.setAttributedTitle(attributedTitle, for: .normal) } func configureButtonStyle(_ button: UIButton) { button.layer.cornerRadius = 14 button.clipsToBounds = true } func setupSceneView(_ scene: SCNScene) { sceneView2.scene = scene sceneView2.autoenablesDefaultLighting = true sceneView2.showsStatistics = false } func loadScene(named sceneName: String, into scene: SCNScene) { if let newScene = SCNScene(named: sceneName) { sceneView2.scene = newScene } } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { view.endEditing(true) super.touchesBegan(touches, with: event) } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) } func textFieldShouldReturn(_ textField: UITextField) -> Bool { if textField == textfield1 { textField.resignFirstResponder() } else if textField == textfield2 { textField.resignFirstResponder() } return true } func loadScene(named sceneName: String) { if let newScene = SCNScene(named: sceneName) { sceneView2.scene = newScene } } @IBAction func hozon(_ sender: UIButton) { toggleRecording() } func toggleRecording() { if !isRecording { startRecording() } else { stopRecording() } updateButtonTitle() } func updateButtonTitle() { let title = isRecording ? "停止" : "録画" hozon.setTitle(title, for: .normal) } func startRecording() { guard recorder.isAvailable else { print("録画できません") return } recorder.startRecording { [weak self] error in if let error = error { print("録画の開始に失敗しました: \(error.localizedDescription)") } else { self?.isRecording = true self?.updateButtonTitle() print("録画を開始しました") } } } func stopRecording() { recorder.stopRecording { [weak self] (previewViewController, error) in if let error = error { print("録画の停止に失敗しました: \(error.localizedDescription)") return } if let previewVC = previewViewController { previewVC.previewControllerDelegate = self self?.present(previewVC, animated: true, completion: nil) } self?.isRecording = false self?.updateButtonTitle() print("録画を停止しました") } } func previewController(_ previewController: RPPreviewViewController, didFinishWithActivityTypes activityTypes: Set<String>) { if activityTypes.contains("com.apple.UIKit.activity.SaveToCameraRoll") { print("カメラロールに保存されました") } if activityTypes.contains("com.apple.UIKit.activity.OpenInPlace") { print("別のアプリで開いた") } dismiss(animated: true, completion: nil) } func previewControllerDidFinish(_ previewController: RPPreviewViewController) { dismiss(animated: true, completion: nil) } @IBAction func jumpButtonPressed(_ sender: Any) { if let text = textfield1.text, !text.isEmpty { Label1.text = text } else { Label1.text = "文字を入力してボタンを押してね" } DispatchQueue.main.asyncAfter(deadline: .now() + 0.0) { [weak self] in guard let self = self else { return } if let text = self.textfield2.text, !text.isEmpty { self.Label2.text = text } else { self.Label2.text = "フィギュアがうごくよ" } } if isJumping { // 停止中の処理 isJumping = false jumpButtonPressed.setTitle("再生", for: .normal) // textfield1とtextfield2を表示する textfield1.isHidden = false textfield2.isHidden = false labelTimer?.invalidate() // タイマー停止 Label1.isHidden = false Label2.isHidden = false // ラベルを表示 let attributes: [NSAttributedString.Key: Any] = [ .font: UIFont.boldSystemFont(ofSize: 27), // Increase font size and set bold ] let attributedTitle = NSAttributedString(string: "再生", attributes: attributes) jumpButtonPressed.setAttributedTitle(attributedTitle, for: .normal) } else { // 再生中の処理 isJumping = true jumpButtonPressed.setTitle("停止", for: .normal) // textfield1とtextfield2を非表示にする textfield1.isHidden = true textfield2.isHidden = true Label1.isHidden = false Label2.isHidden = true // 最初はLabel2のみ表示 labelTimer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(updateLabels), userInfo: nil, repeats: true) let _ = [NSAttributedString.Key: Any]() } let buttonAttributes: [NSAttributedString.Key: Any] = [ .font: UIFont.boldSystemFont(ofSize: 27), // Set the initial font size and set bold ] let playTitle = NSAttributedString(string: "再生", attributes: buttonAttributes) let stopTitle = NSAttributedString(string: "停止", attributes: buttonAttributes) jumpButtonPressed.setAttributedTitle(isJumping ? stopTitle : playTitle, for: .normal) } @objc func updateLabels() { if isShowingLabel1 { Label1.isHidden = false Label2.isHidden = true } else { Label1.isHidden = true Label2.isHidden = false } isShowingLabel1 = !isShowingLabel1 } }

試したこと

xcodeのバージョンのアップ、対応のiosアップ、コードをきれいにした、録画関係のコードを変更した

補足情報(FW/ツールのバージョンなど)

AppStoreConnectの返信

The issues we previously identified still need your attention.

If you have any questions, we are here to help. Reply to this message in App Store Connect and let us know.

Guideline 2.1 - Performance - App Completeness

Your app is still crashing when proceeding with the following steps:

  • Tap 録画
  • Tap 画面を収録
  • Tap 停止
  • App crashes

Review device details:

  • Device type: iPad
  • OS version: iOS 17.2

コメントを投稿

0 コメント