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
做成一个类并修改它,使它可以改变它的player
和playerItem
属性。 请注意,它现在是一个类,而不是结构,因此它可以在不使用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
类中,将 player
和 playerItem
更改为 var
s。
添加一个函数makeRandomPlayer()
,它选择一个随机的URL字符串并使用它来填充player
和playerItem
。
通过您的按钮操作调用 self.streamer.makeRandomPlayer()
。
【讨论】:
能否提供代码示例?我试过了,但出现了一些错误(例如,无法在 makeRandomPlayer 函数中将属性分配给 self)。 因此,在问题的末尾添加您尝试的代码以及您遇到的错误。以上是关于Swift 5 / Swift UI 中的随机 URL的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Swift 在 XCode UI 自动化中选择随机表格视图单元格