Warning for unused variable 'completion' - objective-c

Have this implementation file which compiles and runs fine, but gives me an unused variable warning in a block. Am new to blocks, so am not quite sure what is wrong. Have commented the line where the warning is.
Can someone please explain this? Thanks in advance!
#import "RTViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
#interface RTViewController () {
AVAudioPlayer *backgroundAudioPlayer;
SystemSoundID burnRubberSoundID;
}
#end
#implementation RTViewController
#synthesize car;
#synthesize testDriveButton;
#synthesize backgroundImage;
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Road Trip";
NSURL* backgroundURL = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"CarRunning"
ofType:#"aif"]];
backgroundAudioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:backgroundURL error:nil];
backgroundAudioPlayer.numberOfLoops = -1;
[backgroundAudioPlayer prepareToPlay];
NSURL* burnRubberURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"BurnRubber" ofType:#"aif"]];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)burnRubberURL, &burnRubberSoundID);
}
- (void)viewDidUnload
{
[self setCar:nil];
[self setTestDriveButton:nil];
[self setBackgroundImage:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
//return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (IBAction)TestDrive:(id)sender {
AudioServicesPlaySystemSound(burnRubberSoundID);
[self performSelector:#selector(playCarSound) withObject:self afterDelay:.2];
CGPoint center = CGPointMake(car.center.x, self.view.frame.origin.y + car.frame.size.height/2);
[UIView animateWithDuration:3 animations:^ {
car.center = center;
}
completion:^(BOOL finished) {
[self rotate];
}];
}
-(void)playCarSound {
[backgroundAudioPlayer play];
}
- (void)rotate {
CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI);
void (^animation) () = ^() {
car.transform = transform;
};
void (^completion) (BOOL) = ^ (BOOL finished) {
[self returnCar];
};
[UIView animateWithDuration:3 animations:animation completion:completion];
}
- (void)returnCar {
CGPoint center = CGPointMake(car.center.x, self.view.frame.origin.y + self.view.frame.size.height - car.frame.size.height/2);
void (^animation)() = ^() {
car.center = center;
};
void (^completion)(BOOL) = ^(BOOL finished) {
[self continueRotation];
};
[UIView animateWithDuration:3 animations:animation completion:completion];
}
- (void)continueRotation {
CGAffineTransform transform = CGAffineTransformMakeRotation(0);
void (^animation)() = ^() {
car.transform = transform;
};
void (^completion)(BOOL) = ^(BOOL finished) { //Unused variable 'completion'
[backgroundAudioPlayer stop];
[backgroundAudioPlayer prepareToPlay];
};
[UIView animateWithDuration:3 animations:animation completion:nil];
}
#end

The problem is that you forgot to use the variable completion in the line:
[UIView animateWithDuration:3 animations:animation completion:nil];
^^^
Here
So change that line to this:
[UIView animateWithDuration:3 animations:animation completion:completion];
Also, note that you can write your code like this:
- (void)continueRotation
{
[UIView animateWithDuration:3 animations:^{
car.transform = CGAffineTransformMakeRotation(0);
} completion:^(BOOL finished) {
[backgroundAudioPlayer stop];
[backgroundAudioPlayer prepareToPlay];
}];
}

That warning simply means that you've instantiated a variable but are not using it anywhere in the code.
But it's a warning, your code will still compile and should work fine. It's just telling you there's no reason to instantiate something if it's never gonna be used.

Related

Unable to call up my video files using AVFoundation

I'm having difficulty playing back video that I've recently recorded in a hybrid image/video camera akin to Snapchat (e.g. tap to take a photo, press and hold to record a video, playback on button release).
I'm currently saving the video file to NSFileManager. When I log it out I do verify that something is being saved but can't inspect the file because it has to be tested on the phone.
The file path when I log it out:
file:///var/mobile/Containers/Data/Application/7D86B14D-ACFF-4494-AD61-CBBD32DCA7A5/Documents/test.mov
When I go to load the asset from the file manager I log out an error that it can't open the files. I've only just started working with AVFoundation so not sure what some of the issues/considerations are when debugging. Any insight would be greatly appreciated, thank you!
Referenced tutorial
Referenced github repository
Referenced code:
PlayerView.h (reference)
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#interface PlayerView : UIView
#property (nonatomic) AVPlayer *player;
- (void)setPlayer:(AVPlayer *)player;
#end
PlayerView.m (reference)
#import "PlayerView.h"
#implementation PlayerView
+ (Class)layerClass {
return [AVPlayerLayer class];
}
- (AVPlayer *)player {
return [(AVPlayerLayer *)[self layer] player];
}
- (void)setPlayer:(AVPlayer *)player {
[(AVPlayerLayer *)[self layer] setPlayer:player];
}
#end
HybridCameraViewController.h (reference)
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import "PlayerView.h"
#interface HybridCameraViewController : UIViewController
#property UIButton *button;
#property UIButton *saveButton;
#property UIImageView *previewView;
#define VIDEO_FILE #"test.mov"
#end
HybridCameraViewController.m (reference)
#import "HybridCameraViewController.h"
static const NSString *ItemStatusContext;
#class PlayerView;
#interface HybridCameraViewController () <AVCaptureFileOutputRecordingDelegate>
#end
#implementation HybridCameraViewController
AVCaptureSession *session;
AVCaptureStillImageOutput *imageOutput;
AVCaptureMovieFileOutput *movieOutput;
AVCaptureConnection *videoConnection;
AVPlayer *player;
AVPlayerItem *playerItem;
PlayerView *playerView;
- (void)viewDidLoad {
[super viewDidLoad];
[self testDevices];
self.view.backgroundColor = [UIColor blackColor];
//Image preview
self.previewView = [[UIImageView alloc]initWithFrame:self.view.frame];
self.previewView.backgroundColor = [UIColor whiteColor];
self.previewView.contentMode = UIViewContentModeScaleAspectFill;
self.previewView.hidden = YES;
[self.view addSubview:self.previewView];
//Playerback setup
playerView = [[PlayerView alloc]initWithFrame:self.view.frame];
playerView.backgroundColor = [UIColor redColor];
[self syncUI];
//Buttons
self.button = [self createButtonWithTitle:#"REC" chooseColor:[UIColor redColor]];
UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:#selector(handleLongPressGesture:)];
[self.button addGestureRecognizer:longPressRecognizer];
[self.button addTarget:self action:#selector(captureImage) forControlEvents:UIControlEventTouchUpInside];
self.saveButton = [self createSaveButton];
[self.saveButton addTarget:self action:#selector(saveActions) forControlEvents:UIControlEventTouchUpInside];
}
- (void)viewWillAppear:(BOOL)animated {
//Tests
[self initializeAVItems];
NSLog(#"%#", videoConnection);
NSLog(#"%#", imageOutput.connections);
NSLog(#"%#", imageOutput.description.debugDescription);
}
#pragma mark - AV initialization
- (void)initializeAVItems {
//Start session, input
session = [AVCaptureSession new];
if ([session canSetSessionPreset:AVCaptureSessionPresetHigh]) {
session.sessionPreset = AVCaptureSessionPresetHigh;
}
AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error;
AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:&error];
if ([session canAddInput:deviceInput]) {
[session addInput:deviceInput];
} else {
NSLog(#"%#", error);
}
AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:session];
[previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
//Layer preview
CALayer *viewLayer = [[self view] layer];
[viewLayer setMasksToBounds:YES];
CGRect frame = self.view.frame;
[previewLayer setFrame:frame];
[viewLayer insertSublayer:previewLayer atIndex:0];
//Image Output
imageOutput = [AVCaptureStillImageOutput new];
NSDictionary *imageOutputSettings = [[NSDictionary alloc]initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil];
imageOutput.outputSettings = imageOutputSettings;
//Video Output
movieOutput = [AVCaptureMovieFileOutput new];
[session addOutput:movieOutput];
[session addOutput:imageOutput];
[session startRunning];
}
- (void)testDevices {
NSArray *devices = [AVCaptureDevice devices];
for (AVCaptureDevice *device in devices) {
NSLog(#"Device name: %#", [device localizedName]);
if ([device hasMediaType:AVMediaTypeVideo]) {
if ([device position] == AVCaptureDevicePositionBack) {
NSLog(#"Device position : back");
}
else {
NSLog(#"Device position : front");
}
}
}
}
#pragma mark - Image capture
- (void)captureImage {
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in imageOutput.connections) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:AVMediaTypeVideo]) {
videoConnection = connection;
break;
}
}
if (videoConnection) {
break;
}
}
NSLog(#"Requesting capture from: %#", imageOutput);
[imageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if (imageDataSampleBuffer != NULL) {
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
UIImage *image = [UIImage imageWithData:imageData];
self.previewView.image = image;
self.previewView.hidden = NO;
}
}];
[self saveButtonFlyIn:self.saveButton];
}
#pragma mark - Video capture
- (void)captureVideo {
NSLog(#"%#", movieOutput.connections);
[[NSFileManager defaultManager] removeItemAtURL:[self outputURL] error:nil];
videoConnection = [self connectionWithMediaType:AVMediaTypeVideo fromConnections:movieOutput.connections];
[movieOutput startRecordingToOutputFileURL:[self outputURL] recordingDelegate:self];
}
- (AVCaptureConnection *)connectionWithMediaType:(NSString *)mediaType fromConnections:(NSArray *)connections {
for (AVCaptureConnection *connection in connections) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:mediaType]) {
return connection;
}
}
}
return nil;
}
#pragma mark - Show Last Recording
- (void)presentRecording {
NSLog(#"unplaying");
NSLog(#"%#",[self outputURL]);
}
- (IBAction)loadAssetFromFile {
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:[self outputURL] options:nil];
NSString *tracksKey = #"tracks";
[asset loadValuesAsynchronouslyForKeys:#[tracksKey] completionHandler:^{
dispatch_async(dispatch_get_main_queue(),^{
NSError *error;
AVKeyValueStatus status = [asset statusOfValueForKey:tracksKey
error:&error];
if (status == AVKeyValueStatusLoaded) {
playerItem = [AVPlayerItem playerItemWithAsset:asset];
[playerItem addObserver:self forKeyPath:#"status"
options:NSKeyValueObservingOptionInitial
context:&ItemStatusContext];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:playerItem];
player = [AVPlayer playerWithPlayerItem:playerItem];
[playerView setPlayer:player];
}
else {
NSLog(#"The asset's tracks were not loaded:\n%#", [error localizedDescription]);
}
});
}];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (context == &ItemStatusContext) {
dispatch_async(dispatch_get_main_queue(),^{
[self syncUI];
});
return;
}
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
return;
}
- (void)playerItemDidReachEnd:(NSNotification *)notification {
[player seekToTime:kCMTimeZero];
}
- (void)syncUI {
if ((player.currentItem != nil) &&
([player.currentItem status] == AVPlayerItemStatusReadyToPlay)) {
self.button.enabled = YES;
}
else {
self.button.enabled = NO;
}
}
#pragma mark - AVCaptureFileOutputRecordingDelegate
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error {
if (!error) {
NSLog(#"Success!!!!");
} else {
NSLog(#"Error: %#", [error localizedDescription]);
}
}
#pragma mark - Recoding Destination URL
- (NSURL *)outputURL {
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:VIDEO_FILE];
return [NSURL fileURLWithPath:filePath];
}
#pragma mark - Buttons
- (void)handleLongPressGesture:(UILongPressGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateBegan) {
NSLog(#"Press");
self.button.backgroundColor = [UIColor greenColor];
[self captureVideo];
}
if (recognizer.state == UIGestureRecognizerStateEnded) {
NSLog(#"Unpress");
self.button.backgroundColor = [UIColor redColor];
[movieOutput stopRecording];
[self performSelector:#selector(loadAssetFromFile)];
[player play];
}
}
- (UIButton *)createButtonWithTitle:(NSString *)title chooseColor:(UIColor *)color {
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(self.view.center.x, self.view.frame.size.height - 100, 85, 85)];
button.layer.cornerRadius = button.bounds.size.width / 2;
button.backgroundColor = color;
button.tintColor = [UIColor whiteColor];
[self.view addSubview:button];
return button;
}
- (UIButton *)createSaveButton {
UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(self.view.frame.size.width, self.view.frame.size.height - 100, 85, 85)];
button.layer.cornerRadius = button.bounds.size.width / 2;
button.backgroundColor = [UIColor greenColor];
button.tintColor = [UIColor whiteColor];
button.userInteractionEnabled = YES;
[button setTitle:#"save" forState:UIControlStateNormal];
[self.view addSubview:button];
return button;
}
- (void)saveButtonFlyIn:(UIButton *)button {
CGRect movement = button.frame;
movement.origin.x = self.view.frame.size.width - 100;
[UIView animateWithDuration:0.2 animations:^{
button.frame = movement;
}];
}
- (void)saveButtonFlyOut:(UIButton *)button {
CGRect movement = button.frame;
movement.origin.x = self.view.frame.size.width;
[UIView animateWithDuration:0.2 animations:^{
button.frame = movement;
}];
}
#pragma mark - Save actions
- (void)saveActions {
[self saveButtonFlyOut:self.saveButton];
self.previewView.image = nil;
self.previewView.hidden = YES;
}
#end
The approach was overly complex. Where you went wrong was 1) not loading the url properly and 2) not adding the 'player layer' sublayer to the main view.
Here is an example of successful playback:
//TestURL
self.videoURL = [NSURL URLWithString:(NSString *)[self.selectedVideo objectForKey:#"source"]];
//Video
self.player = [AVPlayer playerWithPlayerItem:[[AVPlayerItem alloc]initWithAsset:[AVAsset assetWithURL:self.videoURL]]];
//Player layer
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
self.playerLayer.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height / 3);
[self.view.layer addSublayer:self.playerLayer];
[self.player play];
All you would need to do is redirect the url to the one you just saved:
self.videoURL = [self outputURL];

Beacon didRangeBeacons in Region not Called

My code was working perfectly some months ago. i dint chnage anything
I dont understand why the didRangeBeacons in Region not trigger when i launch my app :
#import "ESTViewController.h"
#import "PresentViewController.h"
#import <ESTBeaconManager.h>
#import <Parse/Parse.h>
#import <AudioToolbox/AudioToolbox.h>
#interface ESTViewController () <ESTBeaconManagerDelegate>
#property (nonatomic, strong) ESTBeaconManager* beaconManager;
#property (nonatomic, strong) ESTBeacon* selectedBeacon;
#property (nonatomic, strong) NSArray *beaconsArray;
#end
#implementation ESTViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// setup Estimote beacon manager.
// Create the manager instance.
self.beaconManager = [[ESTBeaconManager alloc] init];
// Setup the delegate
self.beaconManager.delegate = self;
// Avoiding unknown state or not
self.beaconManager.avoidUnknownStateBeacons = NO;
// create sample region object (beacons in this case have all same uuid and same major)
region = [[ESTBeaconRegion alloc] initWithProximityUUID:ESTIMOTE_PROXIMITY_UUID identifier:#"multibeacons"];
[self.beaconManager requestStateForRegion:region];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// start looking for estimote beacons in region
// when beacon ranged beaconManager:didRangeBeacons:inRegion: invoked
[self.beaconManager startRangingBeaconsInRegion:region];
[self.beaconManager startMonitoringForRegion:region];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
// stop looking for estimote beacons in region
[self.beaconManager stopRangingBeaconsInRegion:region];
[self.beaconManager stopMonitoringForRegion:region];
}
#pragma mark - ESTBeaconManager delegate
-(void)beaconManager:(ESTBeaconManager *)manager
didRangeBeacons:(NSArray *)beacons
inRegion:(ESTBeaconRegion *)region
{
// descriptor on distance to sort the array of beacons by distance
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"distance" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
// sorting the array of beacons
// beacon array is sorted based on distance
// closest beacon is the first one
self.beaconsArray = [beacons sortedArrayUsingDescriptors:sortDescriptors];
if([self.beaconsArray count] > 0)
{
if(!self.selectedBeacon)
{
// initialy pick closest beacon
self.selectedBeacon = [beacons objectAtIndex:0];
currentBeaconMinor = self.selectedBeacon.minor;
}
else
{
//sorting the array of beacons
self.beaconsArray = [beacons sortedArrayUsingDescriptors:sortDescriptors];
//updating the selected beacon with the first element of the array (closest beacon)
if(self.selectedBeacon != [beacons objectAtIndex:0] )
{
self.selectedBeacon = [beacons objectAtIndex:0];
currentBeaconMinor = self.selectedBeacon.minor;
}
}
// Switch on proximity of the closest beacon
switch (self.selectedBeacon.proximity)
{
case CLProximityUnknown:
{
self.rangeStatusImageView.image = [UIImage imageNamed:#"lost.jpg"];
self.rangeStatusImageView.hidden = NO;
self.signalStatusImageView.hidden = YES;
self.descriptionStateLabel.text = #"Recherche de signal ... Si le problème persiste, contactez l'accueil";
[UIView animateWithDuration:1.0
delay: 0.0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
self.rangeStatusImageView.alpha = 0.3;
}
completion:^(BOOL finished){
[UIView animateWithDuration:1.0
delay: 0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.rangeStatusImageView.alpha = 1.0;
}
completion:nil];
}];
break;
}
case CLProximityImmediate:
{
if ([currentBeaconMinor floatValue] == 128)
{
NSLog(#"128 128 128");
[self performSegueWithIdentifier: #"presentSegue1" sender: self];
}
else if ([currentBeaconMinor floatValue] == 228)
{
NSLog(#"228 228 228");
[self performSegueWithIdentifier: #"presentSegue2" sender: self];
}
else if ([currentBeaconMinor floatValue] == 328)
{
NSLog(#"328 328 328");
[self performSegueWithIdentifier: #"presentSegue3" sender: self];
}
break;
}
case CLProximityNear:
{
self.rangeStatusImageView.image = [UIImage imageNamed:#"near.jpg"];
self.signalStatusImageView.hidden = NO;
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
[UIView animateWithDuration:1.0
delay: 0.0
options: UIViewAnimationOptionCurveEaseIn
animations:^{
self.rangeStatusImageView.alpha = 0.3;
}
completion:^(BOOL finished){
[UIView animateWithDuration:1.0
delay: 0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.rangeStatusImageView.alpha = 1.0;
}
completion:nil];
}];
self.rangeStatusImageView.hidden = NO;
self.descriptionStateLabel.font = [UIFont systemFontOfSize:17];
self.descriptionStateLabel.text = #"Approchez vous d'un article pour obtenir plus d'informations";
break;
}
case CLProximityFar:
{
self.rangeStatusImageView.image = [UIImage imageNamed:#"far.jpg"];
[self.rangeStatusImageView stopAnimating];
self.rangeStatusImageView.hidden = NO;
self.signalStatusImageView.hidden = NO;
self.descriptionStateLabel.text = #"Bienvenue dans notre ... ";
break;
}
default:
break;
}
self.beaconsArray = [beacons sortedArrayUsingDescriptors:sortDescriptors];
}
}
i have a break point at the line after the pragma mark , it never reach that code. I really dont understand why.
Thanks for your help.
I found a solution :
i updated the Info.plist file with :
<key>NSLocationAlwaysUsageDescription</key>
<string>This application monitors your location to show you promotional offers in shops you're passing by.</string>
In the iphone i have change the settings for localisation for my app to "always"

iAd Banner Error "Too many instances of iAd"

I have an ad banner view on one my view controllers that acts as an instructional page for my game. When that view controller has been loaded multiple times I receive the following error.
WARNING: More than 10 instances of ADBannerView or ADInterstitialView currently exist. This is a misuse of the iAd API, and ad performance will suffer as a result. This message is printed only once.
I have searched this error on stackoverflow, read the responses but nothing has worked for me. I have read that you are meant to release the ad banner and then nil it etc. which I have and still am receiving this error. The code for my "viewWillAppear" and "viewWillDissapear" is below. Any help will be appreciated!
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
_adBanner = [[ADBannerView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height, 320, 50)];
_adBanner.delegate = self;
[self.view addSubview:_adBanner];
}
-(void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (_adBanner != nil) {
_adBanner.delegate = nil;
_adBanner.hidden = YES;
[_adBanner release];
_adBanner = nil;
}
}
Try removing the iAd from its superview before setting it to nil:
-(void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (_adBanner != nil) {
[_adBanner removeFromSuperview]; // <-new line
_adBanner.delegate = nil;
_adBanner.hidden = YES;
[_adBanner release];
_adBanner = nil;
}
Here is the code for iAd that I am already using in my apps with no problems:
implementation ViewController
{
ADBannerView *adView;
BOOL bannerIsVisible;
}
- (void)viewDidLoad
{
[super viewDidLoad];
adView = [[ADBannerView alloc] initWithFrame:CGRectZero];
adView.frame = CGRectOffset(adView.frame, 0, -50);
adView.requiredContentSizeIdentifiers = [NSSet setWithObject:ADBannerContentSizeIdentifier320x50];
adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifier320x50;
[self.view addSubview:adView];
adView.delegate=self;
bannerIsVisible=NO;
}
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
if (!bannerIsVisible)
{
[UIView beginAnimations:#"animateAdBannerOn" context:NULL];
// banner is invisible now and moved out of the screen on 50 px
banner.frame = CGRectOffset(banner.frame, 0, 50);
[UIView commitAnimations];
bannerIsVisible = YES;
}
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
if (bannerIsVisible)
{
[UIView beginAnimations:#"animateAdBannerOff" context:NULL];
// banner is visible and we move it out of the screen, due to connection issue
banner.frame = CGRectOffset(banner.frame, 0, -50);
[UIView commitAnimations];
bannerIsVisible = NO;
}
}
Instead of initializing the adBannerView in the individual class, create it in the AppDelegate.
I put:
#property (strong, nonatomic) ADBannerView *adBanner;
in my AppDelegate.h and:
self.adBanner = [[ADBannerView alloc] init];
in my AppDelegate.m
And then in the individual class I put:
#property (strong, nonatomic) ADBannerView *adBanner;
in the .h and in the .m I put:
{
BOOL _bannerIsVisible;
}
right below the #interface and in the #implementation I put:
#pragma mark Ads
- (WTMAppDelegate *) appdelegate {
return (WTMAppDelegate *)[[UIApplication sharedApplication] delegate];
}
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
NSLog(#"Retreieved Ad");
[self bringBannerBack];
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
NSLog(#"Failed to retrieve ad");
[self moveBannerViewOffScreen];
}
- (void)bringBannerBack
{
[self.adBanner setAlpha:1];
[self.adBanner setNeedsDisplay];
[UIView beginAnimations:#"MoveView" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDuration:0.1];
self.adBanner.frame = CGRectMake(0, self.view.bounds.size.height - 50, 320, 50);
[UIView commitAnimations];
_bannerIsVisible = YES;
[self.adBanner setAlpha:1];
}
//Move the banner off the screen.
- (void)moveBannerViewOffScreen
{
[self.adBanner setAlpha:0];
[self.adBanner setNeedsDisplay];
_bannerIsVisible = NO;
}
and in the viewWillAppear and ViewWillDisappear:
- (void) viewWillDisappear:(BOOL)animated{
self.adBanner.delegate=nil;
self.adBanner=nil;
[self.adBanner removeFromSuperview];
}
- (void) viewWillAppear:(BOOL)animated
{
self.adBanner = [[self appdelegate] adBanner];
self.adBanner.delegate = self;
[self.view addSubview:self.adBanner];
if (self.adBanner.bannerLoaded == NO){
NSLog(#"NO initial banner loaded");
[self moveBannerViewOffScreen];
} else {
NSLog(#"Initial ad loaded");
[self bringBannerBack];
}
}

ADBannerView Full Ad Orientation Not Changing

I use the code right out of the Apple iAd Suite demo code to implement my banner ad with a tab bar controller. It was working fine until recently, when I noticed that the test ads became more colorful, and not just black rectangles with the words "test ad" in them.
However, I am now seeing that, while the banner view rotates okay, the full ad is only showing in landscape orientation. The rest of the app rotates okay, but no matter what orientation the device is in, the full add only shows in landscape.
I don't see how to control this.
Here is the code:
#import "BannerViewController.h"
NSString * const BannerViewActionWillBegin = #"BannerViewActionWillBegin";
NSString * const BannerViewActionDidFinish = #"BannerViewActionDidFinish";
#implementation BannerViewController
{
ADBannerView *_bannerView;
UIViewController *_contentController;
}
- (id)initWithContentViewController:(UIViewController *)contentController
{
self = [super init];
if (self != nil) {
_bannerView = [[ADBannerView alloc] init];
_bannerView.delegate = self;
_contentController = contentController;
}
return self;
}
- (void)loadView
{
UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[contentView addSubview:_bannerView];
[self addChildViewController:_contentController];
[contentView addSubview:_contentController.view];
[_contentController didMoveToParentViewController:self];
self.view = contentView;
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return [_contentController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
- (void)viewDidLayoutSubviews
{
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
_bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
} else {
_bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape;
}
CGRect contentFrame = self.view.bounds;
CGRect bannerFrame = _bannerView.frame;
if (_bannerView.bannerLoaded) {
contentFrame.size.height -= _bannerView.frame.size.height;
bannerFrame.origin.y = contentFrame.size.height;
} else {
bannerFrame.origin.y = contentFrame.size.height;
}
_contentController.view.frame = contentFrame;
_bannerView.frame = bannerFrame;
}
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
[UIView animateWithDuration:0.25 animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
[UIView animateWithDuration:0.25 animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
- (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave
{
[[NSNotificationCenter defaultCenter] postNotificationName:BannerViewActionWillBegin object:self];
return YES;
}
- (void)bannerViewActionDidFinish:(ADBannerView *)banner
{
[[NSNotificationCenter defaultCenter] postNotificationName:BannerViewActionDidFinish object:self];
}
#end
In the shouldAutorotateToInterfaceOrientation: method, the interfaceOrientation is portrait, and it is evaluating to true. The full ad still shows in landscape.
What is causing this and how can I control it?
It seems only one orientation is supported in Sandboxing mode.

Expected expression for IBAction in storyboard

Am getting an "Expected expression" error but can't figure out why on an IBAction method. Have commented out the error.
Can you tell me what's wrong? Thank you.
#import "RTViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
#interface RTViewController () {
AVAudioPlayer *backgroundAudioPlayer;
SystemSoundID burnRubberSoundID;
BOOL touchInCar;
}
#end
#implementation RTViewController
#synthesize car;
#synthesize testDriveButton;
#synthesize backgroundImage;
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Road Trip";
NSURL* backgroundURL = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"CarRunning"
ofType:#"aif"]];
backgroundAudioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:backgroundURL error:nil];
backgroundAudioPlayer.numberOfLoops = -1;
[backgroundAudioPlayer prepareToPlay];
NSURL* burnRubberURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"BurnRubber" ofType:#"aif"]];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)burnRubberURL, &burnRubberSoundID);
[testDriveButton setBackgroundImage:[UIImage animatedImageNamed:#"Button" duration:1.0 ] forState:UIControlStateNormal];
}
- (void)viewDidUnload
{
[self setCar:nil];
[self setTestDriveButton:nil];
[self setBackgroundImage:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
//return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (IBAction)TestDrive:(id)sender {
AudioServicesPlaySystemSound(burnRubberSoundID);
[self performSelector:#selector(playCarSound) withObject:self afterDelay:.2];
CGPoint center = CGPointMake(car.center.x, self.view.frame.origin.y + car.frame.size.height/2);
[UIView animateWithDuration:3 animations:^ {
car.center = center;
}
completion:^(BOOL finished) {
[self rotate];
}];
}
-(void)playCarSound {
[backgroundAudioPlayer play];
}
- (void)rotate {
CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI);
void (^animation) () = ^() {
car.transform = transform;
};
void (^completion) (BOOL) = ^ (BOOL finished) {
[self returnCar];
};
[UIView animateWithDuration:3 animations:animation completion:completion];
}
- (void)returnCar {
CGPoint center = CGPointMake(car.center.x, self.view.frame.origin.y + self.view.frame.size.height - car.frame.size.height/2);
void (^animation)() = ^() {
car.center = center;
};
void (^completion)(BOOL) = ^(BOOL finished) {
[self continueRotation];
};
[UIView animateWithDuration:3 animations:animation completion:completion];
}
- (void)continueRotation {
CGAffineTransform transform = CGAffineTransformMakeRotation(0);
void (^animation)() = ^() {
car.transform = transform;
};
void (^completion)(BOOL) = ^(BOOL finished) {
[backgroundAudioPlayer stop];
[backgroundAudioPlayer prepareToPlay];
};
[UIView animateWithDuration:3 animations:animation completion:completion];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if(CGRectContainsPoint(car.frame, [touch locationInView:self.view]))
touchInCar=YES;
else {
touchInCar=NO;
[super touchesBegan:touches withEvent:event];
}
UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(handleSwipeGesture:)];
swipeGesture.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:swipeGesture];
- (IBAction)handleSwipeGesture:(id)sender { // Expected expression
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"Content"];
[[self navigationController]pushViewController:viewController animated:YES];
}
}
#end
The problem is that you never closed out the method
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
with its own curly brace. One visual cue is that the method
- (IBAction)handleSwipeGesture:(id)sender
(where your error is) starts out indented.