嗯,这是我的第一篇文章 - 在这个网站,个人博客和iPhoneDevSDK论坛之间,我一直能够自己解决问题。我已经为iOS开发了大约五个月,并且从未在Google之外寻求过帮助。但这次,我被卡住了。
我已经成功实现了Matt Galagher的AudioStream类(必须删除链接,因为SO假设我的帖子是垃圾邮件)到我的应用程序中,我很高兴地报告它工作得很漂亮。我在一个视图控制器中使用它,它实际上是TabBar应用程序中父视图的子视图。事实上,我的实现与Matt's example中的实现差别不大 - 我只更改了一些UI元素。
到目前为止,当用户切换到另一个标签时,我一直在使用viewDidDisappear
来停止拖缆。但最近我决定,只要应用程序正在运行,就可以让音频流播放,无论顶视图是什么。这是一个非常简单的变化,现在我的音频流继续播放,无论我在应用程序中的哪个位置。
以下是视图控制器的工作原理:
以上所有工作都是完美的。如果我离开视图(通过弹出到父视图,或导航到另一个选项卡),音频将保持播放,这正是我想要的。但是当我返回到视图时,UI看起来好像我还没有启动它(播放按钮可见,导航提示被隐藏)。如果按下播放按钮,我会听到第二个流与第一个流同时播放。
updateProgress
似乎已停止(因为self.navigationItem.prompt
不再可见),我猜测playbackStateChanged
已“死”(不知道如何描述)。
我花了几个小时筛选AudioStreamer类试图找出如何保持对流的控制,但我已经筋疲力尽了。我希望有人能告诉我我错过了什么。
正如我之前所说,我的视图控制器几乎与示例相同(请参阅上面的超链接,因为SO仍假设我是垃圾邮件发送者),只有少量与UI相关的更改。
我想简短的问题是这样的:有没有人能够实现AudioSTreamer类,弹出它的视图,然后返回并能够查看已用时间或停止流?
编辑:下面是我的视图控制器实现AudioStreamer
#import <UIKit/UIKit.h>
#import <QuartzCore/CoreAnimation.h>
#import <MediaPlayer/MediaPlayer.h>
#import <CFNetwork/CFNetwork.h>
@class AudioStreamer;
@interface RadioViewController : UIViewController
{
IBOutlet UIButton *playButton;
IBOutlet UIButton *stopButton;
IBOutlet UIActivityIndicatorView *waitIndicator;
AudioStreamer *streamer;
NSTimer *progressUpdateTimer;
BOOL shouldAutoStop;
}
- (IBAction)play;
- (IBAction)stop;
- (void)createStreamer;
- (void)destroyStreamer;
- (void)updateProgress:(NSTimer *)aNotification;
- (void)checkWiFi;
@end
#import "AudioStreamer.h"
#import "ServerCheck.h"
#import "RadioViewController.h"
@implementation RadioViewController
- (void)viewDidLoad
{
[[self navigationItem] setTitle:@"WXK33 162.550"];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkWiFi) name:UIApplicationDidBecomeActiveNotification object:nil];
[super viewDidLoad];
}
- (void)viewDidAppear:(BOOL)animated
{
[self performSelector:@selector(checkWiFi)];
[super viewDidAppear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
//[self performSelector:@selector(stop)];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
[super viewDidDisappear:animated];
}
- (void)createStreamer
{
if ([ServerCheck serverReachable:@"audiostream.wunderground.com"])
{
if (streamer)
{
return;
}
[self destroyStreamer];
NSURL *url = [NSURL URLWithString:@"http://audiostream.wunderground.com/MaffooClock/San_Angelo.mp3"];
streamer = [[AudioStreamer alloc] initWithURL:url];
progressUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateProgress:) userInfo:nil repeats:YES];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackStateChanged:) name:ASStatusChangedNotification object:streamer];
}
else
{
[[self navigationController] popViewControllerAnimated:YES];
}
}
- (IBAction)play
{
[self createStreamer];
[waitIndicator startAnimating];
[streamer start];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
}
- (IBAction)stop
{
self.navigationItem.prompt = nil;
[streamer stop];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
}
- (void)playbackStateChanged:(NSNotification *)aNotification
{
if ([streamer isWaiting])
{
[playButton setHidden:YES];
[stopButton setHidden:YES];
[waitIndicator startAnimating];
}
else if ([streamer isPlaying])
{
[playButton setHidden:YES];
[stopButton setHidden:NO];
[waitIndicator stopAnimating];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
}
else if ([streamer isIdle])
{
[self destroyStreamer];
[playButton setHidden:NO];
[stopButton setHidden:YES];
[waitIndicator stopAnimating];
}
}
- (void)updateProgress:(NSTimer *)updatedTimer
{
if (streamer.bitRate > 0.0)
{
double progress = streamer.progress;
double minutes = floor(progress/60);
double seconds = trunc(progress - (minutes * 60));
self.navigationItem.prompt = [NSString stringWithFormat:@"Elapsed: %02.0f:%02.0f",minutes,seconds];;
if (shouldAutoStop && progress > 600)
[self performSelector:@selector(stop)];
}
else
{
self.navigationItem.prompt = nil;
}
}
- (void) checkWiFi
{
if (![ServerCheck wifiAvailable])
{
LogInfo(@"No Wi-Fi");
NSString * messageTitle = @"Notice";
NSString * messageText = @"It appears that you do not have an active Wi-Fi connection. Listening to streaming audio via cellular data may incurr additional data charges. Streaming will automatically stop after 10 minutes.";
UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:messageTitle message:messageText delegate:self cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
[errorAlert show];
[errorAlert release];
shouldAutoStop = YES;
}
else
shouldAutoStop = NO;
}
- (void)destroyStreamer
{
if (streamer)
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:ASStatusChangedNotification object:streamer];
[progressUpdateTimer invalidate];
progressUpdateTimer = nil;
[streamer stop];
[streamer release], streamer = nil;
}
}
- (void)dealloc
{
[self destroyStreamer];
if (progressUpdateTimer)
{
[progressUpdateTimer invalidate], progressUpdateTimer = nil;
}
[super dealloc];
}
@end
答案 0 :(得分:0)
事实证明,我只需要重新思考如何分配和推送视图。 “更多”选项卡显示表视图,每个单元格表示在选择该单元格时将被推送的子视图。我更改了此视图以在viewDidLoad
中分配所有子视图,然后只需在didSelectRowAtIndexPath
内执行推送,并在dealloc
中释放子视图。
这完全解决了我的问题。感谢Jason Coco让球得分。