Search code examples
iosswiftxcodeswiftuiapp-store-connect

How can I make my function a public selector?


I've excluded the other protocol stubs of UIViewControllerRepresentable to shorten this code, but this code gives me an error only when trying to upload to Apple Connect.

Asset validation failed (50) The app references non-public selectors in Payload/some/path: volumeChanged: (ID: 060de305-b6d2-4314-a238-c679fa85404e)

How is my volumeChanged function not a public selector?

import SwiftUI
import AVFoundation
import MediaPlayer

struct VolumeEventReader<Content: View>: UIViewControllerRepresentable {
    class Coordinator: NSObject {
        var parent: VolumeEventReader
        var lastVolumeNotificationSequenceNumber: Int?
        var currentVolume = AVAudioSession.sharedInstance().outputVolume

        init(_ parent: VolumeEventReader) {
            self.parent = parent
        }

        @objc func volumeChanged(_ notification: NSNotification) {
            DispatchQueue.main.async { [self] in
                volumeControl(notification)
            }
        }

        func manageVolume(volume: Float, minVolume: Float) {
            switch volume {
            case minVolume: do {
                currentVolume = minVolume + 0.0625
            }
            case 1: do {
                currentVolume = 0.9375
            }
            default: break
            }

            parent.updateUIView(volume: volume)
            
            currentVolume = volume
        }

        func volumeControl(_ notification: NSNotification) {
            let minVolume: Float = 0.0625

            if let volume = notification.userInfo!["Volume"] as? Float {
                //avoiding duplicate events if same ID notification was generated
                if let seqN = self.lastVolumeNotificationSequenceNumber {
                    if seqN == notification.userInfo!["SequenceNumber"] as! Int {
                        // Duplicate nofification received
                    }
                    else {
                        self.lastVolumeNotificationSequenceNumber = (notification.userInfo!["SequenceNumber"] as! Int)
                        manageVolume(volume: volume, minVolume: minVolume)
                    }
                }
                else {
                    self.lastVolumeNotificationSequenceNumber = (notification.userInfo!["SequenceNumber"] as! Int)
                    manageVolume(volume: volume, minVolume: minVolume)
                }
            }
        }
    }

    func makeCoordinator() -> Coordinator {
        let coordinator = Coordinator(self)

        NotificationCenter.default.addObserver(
            coordinator,
            selector: #selector(Coordinator.volumeChanged),
            name: NSNotification.Name(rawValue: "SystemVolumeDidChange"),
            object: nil
        )

        return coordinator
    }
}

Solution

  • It isn't telling you that your function is a private selector, rather it is detecting that you are calling a selector that matches Apple's internal API.

    In other words, it appears that you are trying to call private API.

    Simply change the name of your function so that it doesn't match Apple's internal function.