Matt Gallagher的AudioStream:如何处理视图控制器pop

时间:2011-01-20 04:08:23

标签: iphone objective-c ios audiostreamer

嗯,这是我的第一篇文章 - 在这个网站,个人博客和iPhoneDevSDK论坛之间,我一直能够自己解决问题。我已经为iOS开发了大约五个月,并且从未在Google之外寻求过帮助。但这次,我被卡住了。

我已经成功实现了Matt Galagher的AudioStream类(必须删除链接,因为SO假设我的帖子是垃圾邮件)到我的应用程序中,我很高兴地报告它工作得很漂亮。我在一个视图控制器中使用它,它实际上是TabBar应用程序中父视图的子视图。事实上,我的实现与Matt's example中的实现差别不大 - 我只更改了一些UI元素。

到目前为止,当用户切换到另一个标签时,我一直在使用viewDidDisappear来停止拖缆。但最近我决定,只要应用程序正在运行,就可以让音频流播放,无论顶视图是什么。这是一个非常简单的变化,现在我的音频流继续播放,无论我在应用程序中的哪个位置。

以下是视图控制器的工作原理:

  1. 我有一个播放按钮和一个停止按钮,位于同一位置,隐藏了停止按钮。
  2. 当用户按下播放按钮时,播放按钮隐藏,显示UIActivityIndi​​catorView(`[streamer isWaiting]`)
  3. 当流开始播放时(`[streamer isPlaying]`),隐藏了'UIActivityIndi​​catorView`,并出现一个停止按钮
  4. 另外,当`[streamer isPlaying]`时,我在导航提示中显示经过的时间(mm:ss),每秒更新一次
  5. 以上所有工作都是完美的。如果我离开视图(通过弹出到父视图,或导航到另一个选项卡),音频将保持播放,这正是我想要的。但是当我返回到视图时,UI看起来好像我还没有启动它(播放按钮可见,导航提示被隐藏)。如果按下播放按钮,我会听到第二个流与第一个流同时播放。

    updateProgress似乎已停止(因为self.navigationItem.prompt不再可见),我猜测playbackStateChanged已“死”(不知道如何描述)。

    我花了几个小时筛选AudioStreamer类试图找出如何保持对流的控制,但我已经筋疲力尽了。我希望有人能告诉我我错过了什么。

    正如我之前所说,我的视图控制器几乎与示例相同(请参阅上面的超链接,因为SO仍假设我是垃圾邮件发送者),只有少量与UI相关的更改。

    我想简短的问题是这样的:有没有人能够实现AudioSTreamer类,弹出它的视图,然后返回并能够查看已用时间或停止流?

    编辑:下面是我的视图控制器实现AudioStreamer

    ·H

    #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
    

    的.m

    #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
    

1 个答案:

答案 0 :(得分:0)

事实证明,我只需要重新思考如何分配和推送视图。 “更多”选项卡显示表视图,每个单元格表示在选择该单元格时将被推送的子视图。我更改了此视图以在viewDidLoad中分配所有子视图,然后只需在didSelectRowAtIndexPath内执行推送,并在dealloc中释放子视图。

这完全解决了我的问题。感谢Jason Coco让球得分。