Swift 5 / Swift UI 中的随机 URL

Posted

技术标签:

【中文标题】Swift 5 / Swift UI 中的随机 URL【英文标题】:Random URL in Swift 5 / Swift UI 【发布时间】:2021-02-05 01:42:11 【问题描述】:

我正在尝试使用以下结构播放随机广播电台:

struct Radiostreamer 
    
    let streamingURL: URL
    
    var  radios = ["https://a", "https://b.mp3", "https://c.mp3", "d.mp3", "e.mp3"]
    
    
    private let player: AVPlayer?
    private let playerItem: AVPlayerItem?
    
    
    init() 
        self.streamingURL =  URL (string:radios.randomElement()!)!
        print(radios.randomElement() as Any)
        
        self.playerItem = AVPlayerItem(url: self.streamingURL)
        self.player = AVPlayer(playerItem: self.playerItem)
        
    
    
    public func playStreaming()  self.player?.play() 
    public func pauseStreaming()  self.player?.pause() 

然后在 SwiftUI 中

struct ContentView: View 
    
    var streamer = RadioStreamer()
    
    
    Button(action: 
        
        self.streamer.pauseStreaming()
        
        self.streamer.playStreaming()
        
        
    ) 
        Image(systemName: "forward.end").resizable()
        .frame(width: 45, height: 45)
        .aspectRatio(contentMode: .fit)
        .foregroundColor(.buttonColor)
    
    Spacer()

我想要实现的是,当单击按钮前进时,将加载一个新的 url。 我假设问题是当我初始化 var streamer = RadioStreamer() 时计算随机数所以问题是..当按下前进按钮时如何通过再次调用 RadioStreamer 来随机化它?

【问题讨论】:

【参考方案1】:

有(至少)两种方法可以解决这个问题。选项 1 是保持与您相同的 RadioStreamer,并在每次需要新播放器时重新创建它。您必须将其设为 @State 变量才能执行此操作:

struct ContentView: View 
    
    @State var streamer = RadioStreamer()
    
    var body: some View 
        Button(action: 
            
            self.streamer.pauseStreaming()
            
            self.streamer = RadioStreamer()
            
            self.streamer.playStreaming()
            
        ) 
            Image(systemName: "forward.end").resizable()
            .frame(width: 45, height: 45)
            .aspectRatio(contentMode: .fit)
            .foregroundColor(.buttonColor)
        
        Spacer()
    
    

这样,旧的流媒体会暂停(如果它正在播放),会创建一个新的流媒体,从而触发您的 init 方法,该方法选择一个随机元素,然后开始。

第二种是把RadioStreamer做成一个类并修改它,使它可以改变它的playerplayerItem属性。 请注意,它现在是一个类,而不是结构,因此它可以在不使用inout的情况下修改自己的属性@


class RadioStreamer 
    
    var streamingURL: URL?
    
    var  radios = ["https://a", "https://b.mp3", "https://c.mp3", "d.mp3", "e.mp3"]
    
    private var player: AVPlayer?
    private var playerItem: AVPlayerItem?
    
    public func createRandomPlayer() 
        guard let streamingURL = URL (string:radios.randomElement()!) else 
            assertionFailure("Invalid URL")
            return
        
        
        print(streamingURL)
        self.playerItem = AVPlayerItem(url: streamingURL)
        self.player = AVPlayer(playerItem: self.playerItem)
        self.streamingURL = streamingURL
    
    
    public func playStreaming()  self.player?.play() 
    public func pauseStreaming()  self.player?.pause() 



struct ContentView: View 
    
    var streamer = RadioStreamer()
    
    var body: some View 
        Button(action: 
            
                self.streamer.pauseStreaming()
            
                self.streamer.createRandomPlayer()
               
                self.streamer.playStreaming()
            
            
        ) 
            Image(systemName: "forward.end").resizable()
            .frame(width: 45, height: 45)
            .aspectRatio(contentMode: .fit)
        
        Spacer()
    
    
    

就我个人而言,我更喜欢第二条路线,再加上另一条路线——我会将RadioStreamer 设为ObservableObject 并在其上添加一些@Published 属性,例如isPlaying,我可以在我的观点中反映这些属性。

【讨论】:

太棒了!第一个解决方案非常适合我的需求,因为如果暂停 URL 保持不变,但如果接下来会生成一个新 URL。谢谢!!【参考方案2】:

在您的 RadioStreamer 类中,将 playerplayerItem 更改为 vars。

添加一个函数makeRandomPlayer(),它选择一个随机的URL字符串并使用它来填充playerplayerItem

通过您的按钮操作调用 self.streamer.makeRandomPlayer()

【讨论】:

能否提供代码示例?我试过了,但出现了一些错误(例如,无法在 makeRandomPlayer 函数中将属性分配给 self)。 因此,在问题的末尾添加您尝试的代码以及您遇到的错误。

以上是关于Swift 5 / Swift UI 中的随机 URL的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Swift 在 XCode UI 自动化中选择随机表格视图单元格

Swift UITesting 错误:文字中的转义序列无效。 \U201c

Swift 观察 UIApplication 属性

Swift - 调度队列和 U/I 串行运行

随机密码生成器 Swift 3?

swift Swift中的随机数