NSTimer don't stop when I present another viewcontroller - ios

I have a viewController1 setting a timer.
When the timer countdown to 0, I'll present viewController2.
The timer also keeps going, although I call the timer function invalidate
Then I mark present viewcontroller code, it seems stop correctly.
//ViewController2 *vc = [[ViewController2 alloc] init];
//[self presentViewController:vc animated:false completion:nil];
What's wrong with code?
#import "ViewController.h"
#import <WebKit/WebKit.h>
#import "ViewController2.h"
#interface ViewController ()<WKScriptMessageHandler, WKNavigationDelegate,WKUIDelegate>
#property (nonatomic,strong) WKWebView* webView;
#property (nonatomic, strong) WKWebViewConfiguration * webConfig;
#property (nonatomic, strong) NSTimer *timer;
#property (nonatomic) int count;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:[self createWKWebApp]];
[self.view addSubview: self.webView];
[self.webView.configuration.preferences setValue:#YES forKey:#"allowFileAccessFromFileURLs"];
self.webView.scrollView.bounces = NO;
[self.webView setContentMode:UIViewContentModeScaleAspectFit];
self.webView.navigationDelegate = self;
self.webView.UIDelegate = self;
NSURL *url = [NSURL URLWithString:#"https://www.google.com.tw"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
self.count = 5;
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(timerFired) userInfo:nil repeats:YES];
}
-(void)timerFired {
NSLog(#"===) self.count : %d", self.count);
if (self.count == 0) {
ViewController2 *vc = [[ViewController2 alloc] init];
[self presentViewController:vc animated:false completion:^{
[self.timer invalidate];
self.timer = nil;
}];
} else {
self.count -= 1;
}
}
- (WKWebViewConfiguration *)createWKWebApp {
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
WKUserContentController *userContent = [[WKUserContentController alloc] init];
config.userContentController = userContent;
return config;
}
- (void)userContentController:(WKUserContentController*)userContentController didReceiveScriptMessage:(WKScriptMessage*)message {
}
#end

Before present a ViewController, stop the timer
[self.timer invalidate];
self.timer = nil;
ViewController2 *vc = [[ViewController2 alloc] init];
[self presentViewController:vc animated:false completion:nil];

Invalidate the timer in viewWillDisappear delegate method and tigger again whenever view will appear again.

Related

Need to stop AVPlayer before playing new stream

I have On-line Radio app. Located on the first viewController (tableView) audio streams. Audio streams are made as a table. By clicking on the name of the stream screen opens with AVpalyer. The problem is that when opening the second stream, the ашкые stream is played simultaneously. How to make so that would be played if one thread, and the second was turned down?
avplayer:
#interface RadioViewController ()
#end
#implementation RadioViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSString *restorationId = self.restorationIdentifier;
NSString *streamId = _detail.label;
NSString* identifer = [restorationId stringByAppendingString: streamId];
NSLog(#"%#", identifer);
self.title = apptitle;
self.streamLabel.text = _detail.label;
//Определение потока
NSString *streamURL;
if (_detail.label == #"ПЕРВЫЙ"){
streamURL = streamURLpervyj;
} if (_detail.label == #"РОК") {
streamURL = streamURLrok;
} if (_detail.label == #"БИТ") {
streamURL = streamURLbit;
} if (_detail.label == #"ПО-РУССКИ") {
streamURL = streamURLporusski;
} if (_detail.label == #"ХИП-ХОП") {
streamURL = streamURLhiphop;
} if (_detail.label == #"РЕЛАКС") {
streamURL = streamURLrelax;
} if (_detail.label == #"РЕТРО") {
streamURL = streamURLretro;
}
if(![self connected]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Невозможно установить соединение" message:#"Проверьте соединение с интернетом" delegate:self cancelButtonTitle:#"ОК" otherButtonTitles: nil];
[alert show];
} else {
//Start stream
AVPlayerItem* playerItem = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:streamURL]];
[playerItem addObserver:self forKeyPath:#"timedMetadata" options:NSKeyValueObservingOptionNew context:nil];
music = [AVPlayer playerWithPlayerItem:playerItem];
[music play];
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playButton:)
name:#"TogglePlayPause"
object:nil];
//Set Title View
titleView = [[UILabel alloc] initWithFrame:CGRectMake(0, 240, myScrollView.frame.size.width, 40)];
[self setStyle]; //Set style layers
titleView.text = #"Подключаюсь...";
CGFloat textLength = titleView.intrinsicContentSize.width;
[myScrollView addSubview: titleView];
[self.view addSubview:myScrollView];
if (textLength < 240) {
[self centerText];
}
timer = [NSTimer scheduledTimerWithTimeInterval:(1.0/2.0) target:self selector:#selector(timed) userInfo:nil repeats:YES];
}
http://dev.b4u.by/radio.jpg
You can decleare avplayer object "music" in your appdelegate then access it by this way
AppDelegate *mainDelegate = [UIApplication sharedApplication].delegate;
[mainDelegate.music pause];
mainDelegate.music = nil;
when you want to start new stream or before alloc init
StreamViewController.h
#interface APStreamsViewController : UIViewController <UITableViewDataSource>
{
AVPlayer *musicSegue;
}
StreamViewController.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
if (indexPath) {
APStreamsData *item = [_data objectAtIndex:indexPath.row];
[segue.destinationViewController setDetail:item];
}
RadioViewController *music = [segue destinationViewController];
[music setMusic: musicSegue];
}
RadioViewController.h
#property (nonatomic, strong) AVPlayer *music;
And in RadioViewController change music to _music )))

Read data from NSOperation subclass to multiple viewcontrollers

I will explain scenario.
I have a NSOperation subclass. In this class , I am reading data from multiple bluetooth devices.
I am creating an object of NSOperation class in ViewController A and get data using delegate methods in NSoperation subclass.
Now, I want to read data from Viewcontroller B without creating an object of NSoperation.
Please check my NSOperation Subclass
NOPerationSubclass.h
`
#protocol NOPerationSubclassDelegate`;
#interface NOPerationSubclass : NSOperation{
BOOL executing;
BOOL finished;
}
#property id<NOPerationSubclassDelegate> delegate;
- (id)initWithConnectDevice:(ConnectDevice *)cDevice toPeripheral:(CBPeripheral *)peripheral;
#end
#protocol NOPerationSubclassDelegate
-(void)updateUIFromOperation:(NOPerationSubclass *)operation;
#end
NOPerationSubclass.m
- (id)initWithConnectDevice:(ConnectDevice *)cDevice toPeripheral:(CBPeripheral *)peripheral{
if (self = [super init]) {
executing = NO;
finished = NO;
self.connectDevice = cDevice;
[self.connectDevice setDelegate:self];
self.connectedPeripheral = peripheral;
dataDic = [[NSMutableDictionary alloc] init];
}
return self;
}
-(BOOL)isConcurrent{
return YES;
}
- (BOOL)isExecuting {
return executing;
}
- (BOOL)isFinished {
return finished;
}
-(void) terminateOperation {
[self willChangeValueForKey:#"isFinished"];
[self willChangeValueForKey:#"isExecuting"];
finished = YES;
executing = NO;
[self didChangeValueForKey:#"isExecuting"];
[self didChangeValueForKey:#"isFinished"];
}
- (void)start {
#autoreleasepool {
if (self.isCancelled){
[self willChangeValueForKey:#"isFinished"];
finished = YES;
[self didChangeValueForKey:#"isFinished"];
return;
}
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(timerFired:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] run];
}
-(void)timerFired:(id)sender{
if (self.isCancelled){
[self willChangeValueForKey:#"isFinished"];
finished = YES;
[self didChangeValueForKey:#"isFinished"];
return;
}
[connectDevice calldiscoverServicesForPeripheral:connectedPeripheral];
}
-(void)getDataFromPeripheral:(CBPeripheral *)peripheral Data:(NSString *)data{
[dataDic setValue:[peripheral.identifier UUIDString] forKey:#"identifier"];
[dataDic setValue:data forKey:#"data"];
[[[AppDelegate app] devicesDataArray] addObject:dataDic];
[(NSObject *)self.delegate performSelectorOnMainThread:#selector(updateUIFromOperation:) withObject:dataDic waitUntilDone:NO];
NSLog(#"PERIPHERAL DATA::+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%#",peripheral.name);
}
And, I am calling this NSOpeartion class from ViewController A like this
NOPerationSubclass *queue = [[NOPerationSubclass alloc] initWithConnectDevice:connectDevices toPeripheral:peripheral];
queue.delegate = self;
[[[AppDelegate app] mainOperationQueue] addOperation:queue];
You can use a shared instance class, this is what I always do:
Database.h
#import <Foundation/Foundation.h>
#interface Database : NSObject
#property (nonatomic, readonly) NSArray* myTable;
+(Database*) sharedInstance;
#end
Database.m
#import "Database.h"
#implementation Database
Database* _db = nil;
+(Database*) sharedInstance {
if (!_db)
_db = [[Database alloc] init];
return _db;
}
-(id) init {
self = [super init];
// Do loading here
return self;
}
#end
Then whenever you want to access the data:
[Database sharedInstance].myTable;

Avoid audio to continue in another view

I have an app where I play an audio-file on launch in the View Controller. I also have a button that switches to my second view. My problem is that the audio continues to play even after I have switched view. Here's my code for ViewController.m:
#import <AVFoundation/AVFoundation.h>
#interface ViewController ()
#end
#implementation ViewController
//When I go to this view, I want the audio to stop
- (IBAction)SwitchView:(id)sender {
SecondViewController *second = [[SecondViewController alloc] initWithNibName:nil bundle:nil];
[self presentViewController:second animated:YES completion:NULL];
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"home_sound"
ofType:#"mp3"]];
NSError *error;
homeaudioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:url
error:&error];
if (error)
{
NSLog(#"Error in audioPlayer: %#",
[error localizedDescription]);
} else {
homeaudioPlayer.delegate = self;
[homeaudioPlayer setNumberOfLoops: -1];
[homeaudioPlayer prepareToPlay];
}
[homeaudioPlayer play];
}
#end
How can I do this?
Thanks.
update your SwitchView code-
- (IBAction)SwitchView:(id)sender {
[homeaudioPlayer stop];
SecondViewController *second = [[SecondViewController alloc] initWithNibName:nil bundle:nil];
[self presentViewController:second animated:YES completion:NULL];
}
Simply add [homeaudioPlayer stop]; to your switchView method. This should stop all sound that the player is playing.

Send Audio by Email

How could I get the audio from phone and get it to share via email?
Will it available?
Can we share it simply like music at application?
Your question could have been better, you should show what you've tried, your specific problem, your actual results and your expected result.
Having said that, this sounded like a nice challenge.. so the answer follows.
I'm not sure if you wanted to get the music from the iPod or the app bundle so I implemented the iPod version as (in my opinion), it's more complex.
SSCCE:
main.m
#import "AppDelegate.h"
int main(int argc, char * argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
AppDelegate.h
#import UIKit;
#import MessageUI;
#import MediaPlayer;
#interface AppDelegate : UIResponder <UIApplicationDelegate, MFMailComposeViewControllerDelegate, MPMediaPickerControllerDelegate>
#property (strong, nonatomic) UIWindow *window;
#end
AppDelegate.m
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window makeKeyAndVisible];
UIViewController *controller = [[UIViewController alloc] init];
_window.rootViewController = controller;
MPMediaPickerController *mediaPicker = [[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeAny];
mediaPicker.delegate = self;
mediaPicker.allowsPickingMultipleItems = YES;
mediaPicker.prompt = #"Select songs to play";
[_window.rootViewController presentViewController:mediaPicker animated:YES completion:^{
}];
return YES;
}
-(void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
NSLog(#"Result:%d", result);
[controller dismissViewControllerAnimated:YES completion:nil];
}
-(void) mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection
{
[mediaPicker dismissViewControllerAnimated:YES completion:^{
NSArray *recipents = #[#"a#b.com"];
MFMailComposeViewController *messageController = [[MFMailComposeViewController alloc] init];
messageController.mailComposeDelegate = self;
[messageController setToRecipients:recipents];
[messageController setMessageBody:#"Here is a music track" isHTML:NO];
[messageController setSubject:#"Music"];
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
for (MPMediaItem *item in mediaItemCollection.items)
{
NSURL *url = [item valueForProperty:MPMediaItemPropertyAssetURL];
AVAsset *asset = [AVAsset assetWithURL:url];
NSArray *presets = [AVAssetExportSession exportPresetsCompatibleWithAsset:asset];
AVAssetExportSession *session = [AVAssetExportSession exportSessionWithAsset:asset presetName:presets[0]];
session.outputURL = [[tmpDirURL URLByAppendingPathComponent:#"item"] URLByAppendingPathExtension:#"m4a"];
session.outputFileType = [session supportedFileTypes][0];
[session exportAsynchronouslyWithCompletionHandler:^{
NSData *data = [NSData dataWithContentsOfURL:session.outputURL];
[messageController addAttachmentData:data mimeType:#"audio/mp4" fileName:#"musicAttachment.m4a"];
}];
}
[_window.rootViewController presentViewController:messageController animated:YES completion:^{
}];
}];
}
-(void) mediaPickerDidCancel:(MPMediaPickerController *)mediaPicker
{
}
#end

i want navigate to another file in webview.

i want to call objective c file from javascript.
- (void)viewDidLoad
{
webview.delegate = self;
myButton.enabled = NO;
NSString *path=[[NSBundle mainBundle]pathForResource:#"1" ofType:#"html" inDirectory:#"files"];
NSURL *url=[NSURL fileURLWithPath:path];
NSURLRequest *request=[NSURLRequest requestWithURL:url];
[webview loadRequest:request];}
i am using this code to call my html page successfully and i use the below code to call shouldStartLoadWithRequest method in objective c.
<img src="cercle24px.png" />
now i went to call new TestViewController.m file how to i call this file, i used the below code.its print the nslog correctly and give alert box also.but doesn't navigate to next file.please help me if any one know.i am waiting for your valuable reply please.
- (BOOL)webView:(UIWebView*)webview shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
NSLog(#"what");
UIAlertView *tstAlert = [[UIAlertView alloc] initWithTitle:#"" message:#"Allowed only alphabets and numeric" delegate:self cancelButtonTitle:nil otherButtonTitles:#"Ok",nil];
[tstAlert show];
NSString *absoluteUrl = [[request URL] absoluteString];
NSLog(#"absolute%#",absoluteUrl);
if ([absoluteUrl isEqualToString:#"didtap://button1"]) {
NSLog(#"yes");
TestViewController *testview=[[TestViewController alloc]initWithNibName:#"TestViewController" bundle:nil];
[self.navigationController pushViewController:testview animated:YES];
return NO;
}
NSLog(#"no");
return YES;
}
Alright, I copy & tested your code, it works well, maybe somewhere else did wrong...
Create a new "Empty Template" Xcode project with ARC enabled, paste below into AppDelegat.m:
//
// AppDelegate.m
// WebTest
//
// Created by Elf Sundae on 8/5/13.
// Copyright (c) 2013 www.0x123.com. All rights reserved.
//
#import "AppDelegate.h"
#interface SampleViewController : UITableViewController
#end
#implementation SampleViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Sample Controller";
}
#end
#pragma mark -
#interface WebViewController : UIViewController <UIWebViewDelegate>
#end
#implementation WebViewController
- (void)viewDidLoad
{
[super viewDidLoad];
UIWebView *web = [[UIWebView alloc] initWithFrame:self.view.bounds];
web.delegate = self;
[self.view addSubview:web];
[web loadHTMLString:#"<a href='didTap://button1'><img src='cercle24px.png' /></a>" baseURL:nil];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
{
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:nil message:#"alert message" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
NSString *urlString = request.URL.absoluteString;
if ([urlString caseInsensitiveCompare:#"didtap://button1"] == NSOrderedSame) {
#define __use_method 3 // it could be: 1/2/3
#if (__use_method == 1)
SampleViewController *controller = [[SampleViewController alloc] init];
[self.navigationController pushViewController:controller animated:YES];
#elif (__use_method == 2)
/* method 2 */
SampleViewController *controller = [[SampleViewController alloc] init];
[self.navigationController performSelector:#selector(pushViewController:animated:)
withObject:controller
withObject:#(YES)];
#elif (__use_method == 3)
/* method 3 */
__unsafe_unretained __typeof(self) _self = self;
double delayInSeconds = 0.01;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
SampleViewController *controller = [[SampleViewController alloc] init];
[_self.navigationController pushViewController:controller animated:YES];
});
#endif
return NO;
}
return YES;
}
#end
#pragma mark -
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window makeKeyAndVisible];
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:
[WebViewController new]];
return YES;
}
#end

Resources