Audio playback code broke with new version of Xcode - ios

first I have to say, I'm a beginner with iOS development. I would appreciate any help.
I've made a code that plays sounds when certain buttons are touched, it worked fine in previous Xcode version, but in this new one, no sounds are played. During the building of code no errors are reported and everything else works fine when I turn on simulator for iPhone 4s, that one is target for this code. Please help.
Here is my code:
file.h
#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
#import <CoreLocation/CoreLocation.h>
#interface DataViewController : UIViewController <CLLocationManagerDelegate> {
int nob, nof, nod;
CLLocationManager *locationManager;
}
#property (strong, nonatomic) IBOutlet UILabel *maxDistanceLabel;
#property (nonatomic,strong) NSArray *fetchedSettingsArray;
#property (nonatomic,retain) NSNumber *numB;
- (IBAction)forwardB:(id)sender;
- (IBAction)backB:(id)sender;
#property (strong, nonatomic) IBOutlet UILabel *numberB;
#end
file.m (just part where the audio needs to play)
- (IBAction)forwardB:(id)sender {
nob ++;
NSString *nobStr=[NSString stringWithFormat:#"%d",nob];
[numberB setText:nobStr];
numB=[NSNumber numberWithInt:nob];
//sound at button touch
NSString *effectTitle;
effectTitle =#"Buckklick";
SystemSoundID soundID;
NSString *soundPath = [[NSBundle mainBundle] pathForResource:effectTitle ofType:#"wav"];
NSURL *soundUrl = [NSURL fileURLWithPath:soundPath];
AudioServicesCreateSystemSoundID ((__bridge CFURLRef)soundUrl, &soundID);
AudioServicesPlaySystemSound(soundID);
}

I found explanation in some other discussion. Apparently simulator is not working properly.
And I found solution, simply downloading Xcode 5.1.1 to finish my project.

Related

WKWebKit Implementation (Objective-C)

Trying to display a web page in iOS, and I am having trouble implementing WKWebkit.
ViewController.h
#import WebKit;
#interface ViewController : BaseViewController
#property (retain, nonatomic) WKWebView *webView;
#end
ViewController.m
#interface ViewController ()
#property (strong, nonatomic) IBOutlet UIView *containerView;
#property (strong, nonatomic) IBOutlet NSLayoutConstraint *fieldViewBottomConstraintY;
#property (strong, nonatomic) IBOutlet NSLayoutConstraint *centerCredentialsConstraintY;
#end
#implementation ViewController
#synthesize webView;
-(void) viewDidLoad {
[super viewDidLoad];
webView = [[WKWebView alloc] initWithFrame:[[self view] bounds]];
NSURL *url = [NSURL URLWithString:#"https://www.google.com"];
NSURLRequest *urlReq = [NSURLRequest requestWithURL:url];
[webView loadRequest:urlReq];
[self.view addSubview:webView];
[self setupConfiguration];
// Do any additional setup after loading the view.
}
#end
I'm getting this error:
Class Unavailable: WKWebView before iOS 11.0 (NSCoding support was broken in previous versions)
I understand that this question is not very focused, but I'm on a tight schedule, still getting the hang of objective-c and iOS, and I haven't found a lot of implementable solutions, so I need help in solving this issue. I appreciate any help offered.
This is from a project that requires a minimum iOS version of iOS 12
Set your minimum iOS Deployment Target here:
and, check that it auto-updates here (and change it if not):
Set it to the minimum version you need to support.

Differences in behavior running on device w/ Xcode vs. running on device w/o Xcode

I'm a novice working through an old Objective C XCode project, when I noticed some unexpected behavior: a singleton behaves as expected when I run the project on an iPhone XSMax from XCode. It behaves differently when I run it on the iPhone without Xcode.
In this radio station app, I'm using the Basemodel Cocoapod (https://github.com/nicklockwood/BaseModel) as the basis for a singleton to store and persist favorite songs the user chooses as they listen to the radio. Each favorite item consists of several properties of strings, including track name, title, album, including one NSDictionary item that contains four value/key pairs for some html about the artist.
The user presses a button on a VC to save the current track info (trackInfoSRK) into a mutable array of other favorite tracks, that's then saved.
//FavoriteItem.h
#import <Foundation/Foundation.h>
#import "BaseModel.h"
#interface FavoriteItem : BaseModel;
#property (nonatomic, retain) NSDate *time;
#property (nonatomic, retain) NSTimeZone *listenedTimeZone;
#property (nonatomic, retain) NSString *artist;
#property (nonatomic, retain) NSString *title;
#property (nonatomic, retain) NSString *album;
#property (nonatomic, retain) NSString *year;
#property (nonatomic, retain) NSString *duration;
#property (nonatomic, retain) NSURL *albumURL;
#property (nonatomic, retain) UIImage *albumImg;
#property BOOL albumErr;
#property BOOL albumLoaded;
#property(nonatomic, retain) NSMutableDictionary *trackInfo;
#end
//FavoriteItem.m
#import <Foundation/Foundation.h>
#import "FavoriteItem.h"
#import "FavoriteList.h"
#implementation FavoriteItem
- (id)init
{
self = [super init];
if (self) {
self.albumErr=FALSE;
self.albumLoaded=FALSE;
}
return self;
}
- (BOOL)save
{
//save the favorites list
return [[FavoriteList sharedInstance] save];
}
#end
//FavoriteList.h
#interface FavoriteList : BaseModel
#property (nonatomic, strong) NSMutableArray *favorites;
#end
//FavoriteList.m
#import "FavoriteList.h"
#import "FavoriteItem.h"
#implementation FavoriteList
- (void)setUp
{
self.favorites = [NSMutableArray array];
}
+ (BMFileFormat)saveFormat
{
//return BMFileFormatHRCodedJSON;
return BMFileFormatHRCodedXML;
}
#end
When the properties are set in a VC:
//trackInfoSRK is currently playing trackInfo dict, and it set up in viewDidLoad:
trackInfoSRK = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"", #"PAArtistHTML",
#"", #"PAArtistLink",
#"", #"lastFMArtistHTML",
#"", #"lastFMArtistLink",nil];
//trackInfoSRK is populated along the way. Then when it's favorited:
FavoriteItem *thisFavorite =[[FavoriteItem alloc] init];
thisFavorite.artist = artistName;
thisFavorite.title = songTitle;
.
.
.
thisFavorite.trackInfo = trackInfoSRK;
[[FavoriteList sharedInstance].favorites insertObject:thisFavorite atIndex:0];
NSLog(#"Adding Favorite at index 0");
BOOL saveGood=[[FavoriteList sharedInstance] save];
This works just fine when the app is running on an iPhone XSMax launched from Xcode. However, when the app run by itself on the phone, any favorite and the contained properties are saved to the mutable array are saved properly except for the dictionary trackInfo property: the trackInfo for any new favorite made will instantly show the trackInfo for the currently playing track, trackInfoSRK (all the rest of the string properties are fine).
It's like the favorited track's trackInfo becomes a pointer to the variable it was being set to from the currently playing track, and it will always mirror that until the app is restarted (at which point the favorite is frozen to the last trackInfoSRK it had in this "mirroring" state.
Why would any behavior change from running it in Xcode on the device from running it standalone on the device?
What should I be looking for in this sense that would tell me how to fix this? I feel like I'm missing something Big But Simple here.
I'm using Xcode 10.2.1 with SDK 12.2. Deployment Target is iOS 11.0.
Thanks in advance!

iOS - JPSVolumeButtonHandler

I stumbled upon this git repo in an SO post and was just giving it a trial run. Basically, it's supposed to setup an observer for the volume button on your iphone. I installed it with Cocoapods, and tried the example but wasn't able to detect volume up/down pushes. Below is my code. Does anyone have any experience working with this package? is there something I'm missing?
I'm developing in XCode 7 and tested this on an iPhone 6.
ViewController.h
#import <UIKit/UIKit.h>
#import "JPSVolumeButtonHandler/JPSVolumeButtonHandler.h"
#interface ViewController : UIViewController
#property (weak, nonatomic) JPSVolumeButtonHandler *volumeHandler;
#property (strong, nonatomic) IBOutlet UILabel *outputLabel;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.outputLabel.text = #"";
self.volumeHandler = [JPSVolumeButtonHandler volumeButtonHandlerWithUpBlock:^{
self.outputLabel.text = #" Up! ";
} downBlock:^{
self.outputLabel.text = [self.outputLabel.text stringByAppendingString:#" Down! "];
}];
}
#end
You have a weak reference to JPSVolumeButtonHandler. This means that this property will be released just after assigning to it (or to be more precise, at a point after exiting from viewDidLoad). Just change weak to strong and everything will be working just fine.

App won't run on Xcode simulator but will run on iPhone

I wondering if anyone has ever ran into this problem.
This goes back to my other question where people are saying that codes just don't start working suddenly without reason.
I spent hours debugging my app going through every single line of code. It won't run if I launch my app from Xcode, simulator or iPhone. Yet when I launch my app on the iPhone without going through Xcode, it works perfectly.
I tried restarting Xcode and the same thing happened. Any idea what might be causing this?
#import "CardGameViewController.h"
#import "Deck.h"
#import "PlayingCardDeck.h"
#import "PlayingCard.h"
#import "CardMatchingGame.h"
#interface CardGameViewController ()
#property (nonatomic, strong) CardMatchingGame *game;
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;
#property (weak, nonatomic) IBOutlet UILabel *scoreLabel;
#end
#implementation CardGameViewController
-(CardMatchingGame *)game{
if (!_game) _game = [[CardMatchingGame alloc] initWithCardCount:[self.cardButtons count] usingDeck:[self createDeck]];
return _game;
}
-(Deck *)createDeck{
return [[PlayingCardDeck alloc] init];
}
- (IBAction)touchCardButton:(UIButton *)sender {
NSUInteger chosenButtonIndex = [self.cardButtons indexOfObject:sender];
[self.game chooseCardatIndex:chosenButtonIndex];
[self updateUI];
}
-(void)updateUI{
for (UIButton *cardButton in self.cardButtons){
NSUInteger cardButtonIndex = [self.cardButtons indexOfObject:cardButton];
Card *card=[self.game cardAtIndex:cardButtonIndex];
[cardButton setTitle:[self titleForCard:card] forState:UIControlStateNormal];
[cardButton setBackgroundImage:[self backgroundImageForCard:card] forState:UIControlStateNormal];
cardButton.enabled = !card.isMatched;
self.scoreLabel.text = [NSString stringWithFormat:#"Score: %d", self.game.score];
}
}
-(NSString *)titleForCard:(Card *)card {
return card.isChosen ? card.contents : #"";
}
-(UIImage*) backgroundImageForCard:(Card *)card{
return [UIImage imageNamed:card.isChosen ? #"cardFront" : #"cardBack"];
}
#end
There's a breakpoint at
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;
In the debugger, it says -0 [CardGameViewController setCardButtons:]
And all my properties in the console shows up as nil.
You set a breakpoint on this line:
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;
While I've never set a breakpoint in this place in my code, I suspect what is happening is that both the setter and the getter are getting breakpoints.
And right before "viewDidLoad" would get called in your "CardGameViewController", that's where the XIB/storyboard would be loaded and the IBOutletCollection of UIButtons would be loaded as well. Hence the breakpoint hitting.
If you turn that breakpoint off, I think you will have much better luck with launching your app on both the device and in the simulator.

AVAudioPlayer not playing without IVAR

Before I learned about categories, I had a declared a method for my entity in the generated NSManagedObject Subclass:
// UserRecording.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import <AVFoundation/AVFoundation.h>
#interface UserRecording : NSManagedObject {
AVAudioPlayer *audioPlayer;
}
#property (nonatomic, retain) NSDate * dateCreated;
#property (nonatomic, retain) NSData * audioData;
#property (nonatomic, retain) NSString * name;
-(void) URplay;
#end
and here's the implementation:
// UserRecording.m
#import "UserRecording.h"
#implementation UserRecording
#dynamic dateCreated;
#dynamic audioData;
#dynamic name;
-(void) URplay {
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithData:self.audioData error:&error];
[audioPlayer play];
}
#end
When I learned about categories (via the Stanford iTunes U videos), I moved the code to a category. But the sound stopped playing. The only difference was that there was no declared instance variable (IVAR). Indeed I tested it in my old code. The above code plays audio, but this code doesnt (in the Simulator):
// UserRecording.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#interface UserRecording : NSManagedObject
#property (nonatomic, retain) NSDate * dateCreated;
#property (nonatomic, retain) NSData * audioData;
#property (nonatomic, retain) NSString * name;
-(void) URplay;
#end
and the implementation:
// UserRecording.m
#import "UserRecording.h"
#import <AVFoundation/AVFoundation.h>
#implementation UserRecording
#dynamic dateCreated;
#dynamic audioData;
#dynamic name;
-(void) URplay {
NSError *error;
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithData:self.audioData error:&error];
[audioPlayer play];
}
#end
Maybe it have something to do with ARC? But regardless, what can I do? You can't declare an instance variable in a category so that won't do.
I'm paraphrasing what I learned on the Apple Developer Forums:
Due to ARC, local variables will be deallocated when they leave scope. So the AVAudioPlayer declared in the method will vanish before it gets a chance to play. While adding an IVAR is possible in some contexts, here it isn't. The reason is that you cannot add IVARs to categories. To elaborate, the above NSManagedObject subclass is generated by XCode - if I added an IVAR to the entity, it would get overwritten by XCode when I changed the entity & regenerated.
Therefore, the solution is to rethink where my persistent AVAudioPlayer should go. I'll probably add a persistent AVAudioPlayer* as an argument to the category's method and pass it along when the method gets called.
It has to do with ARC in the sense that your AVAudioPlayer is getting deallocated right after you instantiate it, because with ARC local variables are deallocated when you leave the scope, try declaring a property for it, you don't need an ivar per se:
In header file or interface declaration in the implementation:
#property (strong, nonatomic) AVAudioPlayer *audioPlayer;
In implementation:
#synthesize audioPlayer = _audioPlayer;
This last part implicitly creates an ivar _audioPlayer for your property. You can access it directly, but I'd suggest still going throw the setter self.audioPlayer =.

Resources