MKStore Manager - mkstorekit

how can i call [MKStoreManager sharedStorageManager] in applicationDidFinishLaunching

You simply import MKStoreManager.h at the top of your app delegate.m file where applicationDidFinishLaunching is and then inside applicationDidFinishLaunching, add [MKStoreManager sharedManager], that will initialize it and start it
...this is assuming you have already filled in the necessary information in the MkStoreManager/Observer.h files
#import "MKStoreManager.h"
- (void) applicationDidFinishLaunching {
/* ...other code you want performed...*/
[MKStoreManager sharedManager];
}
Note: the function header for applicationDidFinishLaunching that I wrote may be incomplete, meaning there might be a parameter...go look it up in the api, or have xcode auto fill it for you

Related

Privileged Helper Tool within a Swift project

I've created an Xcode project using Swift and a privileged Helper tool using Objective-C. The helper tool works fine within a project which has also been created in Objective-C but it doesn't seem to work within a project created with Swift.
The service itself is being installed. I can see the helper binary within the /Library/PrivilegedHelperTools directory and it's permissions seem to be okay (as well as the user: root). Removing the helper by using launchctl results in re-installing the tool when my project runs (that works as expected) but I can't call any method of the helper tool.
There is neither any exception being thrown nor does any other error occur (at least there seem to be no error as the Console shows nothing as well).
Does anybody know whether this might be an issue with Swift? Because running the same helper tool within another project (written in Objective-C) works well.
I could figure out what the problem was. The helper tool has a main.m wich contains a main() method. I just forgot to fill it with code that creates an instance of my helper class and trigger its listener:
#import <Foundation/Foundation.h>
#import "Helper.h"
int main(int argc, const char * argv[])
{
#autoreleasepool
{
Helper *helper = [[Helper alloc] init];
[helper run];
}
return EXIT_FAILURE;
}
This code causes the Helper instance to run in an infinite loop waiting for incoming connections (from Helper.h):
- (void)run
{
[_listener resume];
[[NSRunLoop currentRunLoop] run];
}
_listener is an instance of NSXPCListener.

How do I loop a sound, while some condition, using the AVAudioPlayer framework here?

EDIT : trying to implement Adam B's answer now...
I have a crashSound.wav file that I have put in my Supporting Files folder of my xCode project
I'm now trying to make it play inside a while loop, but the documentation isn't very clear as to how exactly I can do that. I know I have to create a delegate object somewhere (I guess my Game class) and get notifications as to whether stopButtonPressed is false and whether the file has finsihed playing so that it can loop and play again while the stopButtonPressed condition is false.. and I know I shouldn't be doing that by calling the [crashSound play] method but I'm not sure how to do it.. Any help?
#interface Game()
{
// code...
AVAudioPlayer *crashSound;
// code...
}
#end
#implementation Game
- (id) init
{
// code...
NSURL *crashSoundFile = [[NSURL alloc] initWithString:#"crashSound" ];
crashSound = [[AVAudioPlayer alloc] initWithContentsOfURL:crashSoundFile error:NULL];
// code...
}
-(void) play // this is my "main" method that will be called once the playButton is pressed
{
while(!self.stopButonPressed)
{
[crashSound play];
}
}
#end
You're structuring your code wrong for how most multimedia libraries would work (including AVPlayer, for example).
Instead of having a while loop, you would start the sound playing, and check if your condition is true each time it completes. You may need to trigger the "next" thing based on a timer or in that callback when the sound completes, instead of having the loop.
See this question and good answer for an example of how to setup AVPlayer and the notification function playerItemDidReachEnd:: Looping a video with AVFoundation AVPlayer?

Where does the main-loop go when creating an iOS app?

I am writing an iOS app for the iPhone in Xcode and I have created some classes as well as their methods inside their respective .h and .m files (that's two classes so basically I have two pairs of .h & .m files)
I now I want to start writing my main loop that will be executed whenever the user hits on the play button, but where exactly do I do that ?
Do I do that in ViewController.m ? e.g. inside this method :
- (IBAction)playPressed:(UIButton *)sender
{
// main loop executed in here ?
// or simply message to the main loop to start executing is *sent* from here ?
}
I read about a similar question in here and someone was suggesting AppDelegate. Now would that be AppDelegate.m or AppDelegate.h ? And if that's the case do I just start writing code or do I include everything inside something like :
int main(int argc, char **argv)
{
....
}
in the Appdelegate file?
I tried to simply start instantiating classes and declaring generic methods (not belonging to any particular class that is..) in a game.m file I created and I get a initializer element is not a compile-time constant warning as soon as I try instantiating anything
Any help? Coming from c++ it would really help me to clarify once and for all in which file exactly to write my main loop and whether I should wrap it in some kind of an int main() function..
thanks!
PS :
Just in case it makes any difference, my ViewController will only consist of a play button that would start the execution of my main loop whenever its pressed, and a stop button that would terminate the execution of the main loop
I have created their respective methods in ViewController.m :
- (IBAction)playPressed:(UIButton *)sender
{
//
}
- (IBAction)stopPressed:(UIButton *)sender
{
// ??
}
which are for the time being empty :)
The programming methodoly on iOS is different from the C++ methodoly.
In C++ , indeed , you would have to make an infinite loop and get the touches , draw everything , etc at each frame.
Until the player presses "exit" and you break the loop.
On iOS , things are done differently:
You already have a main.m file in which you have a main function.
That starts up the app delegate. That app delegate tells you when the app finished launching , goes to background , comes in foreground , etc.
When the app finished launching , you go to your first actual screen.
There , you ADD subviews. You don't draw them at each frame. That is done automatically for you once you have added the view to a parent view.
The programming on iOS is based on events. You don't have to check for touches and see if the
touch location is on a button and then call the method of that button.
Instead , you set a callback method for the button and it's called automatically for you once the button is pressed.
Of course , you first need to alloc the button and add it to a parent view.
Once you get used to this event based programming model , you will for sure like it.
At the start it may seam very different and maybe it doesn't make sense to you , but don't worry.
Comming from a C++ background is surely a good start.
Cheers,
George
EDIT: In that case , I can give more specific info:
So , you go from the AppDelegate in your first screen. Let's call it MainAppScreen.
Now , you need to add those 2 buttons and set selectors ( callback methods ) for them. I can see you already did that.
Now :
- (IBAction)playPressed:(UIButton *)sender
{
running = TRUE;
[self performSelectorInBackground:#selector(myLoop) withObject:nil];
}
- (IBAction)stopPressed:(UIButton *)sender
{
running = FALSE;
}
- (void) myLoop
{
while(running)
{
//this is your loop. You can code in here.
}
}
Where running is an instance variable in the MainAppScreen class.
Hope this helps.
Cheers!
Every iOS app, as well as every executable file has an entry point - this is the main(). You can't have more than one entry points of an executable.And if you look closely into the project you will see that there is an automatically generated main.m file in the Supporting Files group in Xcode's navigator, which looks like this:
#import <UIKit/UIKit.h>
#import "MyAppDelegate.h"
int main(int argc, char *argv[])
{
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([MyAppDelegate class]));
}
}
What you want to do is not clear enough, but it's a good start reading about the structure and the lifecycle of iOS apps, objective-c syntax, get familiar with the UIKit and at least some of the frameworks Apple provide.
You don't have a main in iOS apps (well, technically you do have a main, but you don't have to worry about writing it). That's all handled for you. The runloop is all done for you too. All you have to do is create your button and then tell it (via addTarget method) which method to run when it gets pressed.
Update:
This is pseudo(ish) code for what you'd need to do....
[startButton addTarget:#selector(startPressed:)];
[stopButton addTarget:#selector(stopPressed:)];
-(void)startPressed {
backgroundThread = [[NSThread alloc] initWithWhateverYouWantToRun];
[backgroundThread start];
}
-(void)stopPressed {
[backgroundThread stop];
}
In your background thread, if you want to update the UI, you would call sendMessageOnMainThread (or something similar - can't remember the exact details at the moment!)

IOS values passed to a view are lost or forgotten

This is my first app, and actually isn't even fully mine but rather involves re-working an existing app to add functionality.
It involves a JSON feed which I'm successfully reading in and then trying to pass the value of a URL to a view. Here's the code from my app delegate that is successfully fired once the feed is read in:
- (void)JSONFetch:(MYJSONFetch *)fetch gotTheCollection:(id)collection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
self.testViewController.feedURL = [NSURL URLWithString:[collection objectForKey:#"Listings"]];
[JSONFetch release];
JSONFetch = nil;
}
Then in my testViewController I have this viewDidLoad method:
- (void)viewDidLoad {
[super viewDidLoad];
if(self.feedURL)
{
[self startDownload];
}
}
Eventhough, when I debug, the gotTheCollection method passes a value to the feedURL of the view, it then fails on the if(self feedURL) check within the view and thus the view never gets populated.
As I'm so new to this code I've no idea if the sequence is wrong, or maybe it's how I'm passing the variable.
I know the description is relatively vague but even on a basic level I don't know if this functionality works in objective C, it doesn't cause any errors though, just sits there not loading because it can't get the data.
UPDATE: Definition of FeedURL follows, in the H file:
NSURL *feedURL;
then
#property (nonatomic, retain) NSURL *feedURL;
then in the M file:
#synthesize feedURL;
Thanks for the help guys, I finally decided to just restart the entire upgrade as the project had become a mess of reworked code and I couldn't be sure what worked and what didn't. As a result there's no clear answer to this but I imagine Franks was probably the closest so I'll mark that as the answer.
The NSURL is being autoreleased, you will need to retain it yourself
Assign the NSURL to feedURL, like so
self.testViewController.feedURL = [[NSURL URLWithString:[collection objectForKey:#"Listings"]] retain];
This will also mean you will have to release it yourself.

Navigating between View controllers?

In my Iphone application I am trying to navigate from one table view controller to next table view controller. Problem I am facing is that I have to fetch data using http request and then parse this data when the user select a cell. I am able to fetch and parse the data but the view controller is not waiting for the data to parsed and the next view controller is shown (which is empty). How to over come this problem.
indexSelected = [NSString stringWithFormat: #"%d",[indexPath row] ];
[[MySingletonClass sharedMySingleton] doAnAuthenticatedAPIFetch_Subscriber_Detail : indexSelected];
SubscribersDetailViews2 *viewController = [[SubscribersDetailViews2 alloc] initWithNibName:#"SubscribersDetailViews2" bundle:nil];
[[self navigationController] pushViewController:viewController animated:YES];
[viewController release];
This is what you do:
indexSelected = [NSString stringWithFormat: #"%d",[indexPath row] ];
SubscribersDetailViews2 *viewController = [[SubscribersDetailViews2 alloc] initWithNibName:#"SubscribersDetailViews2" bundle:nil];
[[MySingletonClass sharedMySingleton] doAnAuthenticatedAPIFetch_Subscriber_Detail:indexSelected delegate:self];
[[self navigationController] pushViewController:viewController animated:YES];
[viewController release];
You define a protocol that your view controller conforms to and when the fetching and parsing of data is done you call a method on the delegate to let the view controller know that the data is ready to be displayed.
If you need more information on how to do this, leave a comment.
EDIT: So here's how to declare and use a protocol. I'm going to try to keep it as simple as possible. I'm not sure if I like your naming convention, but I'll still use it for this example.
So let's get down to the code. This is how you declare a protocol:
#protocol MySingletonClassDelegate <NSObject>
#optional
- (void)didDoAnAuthenticatedAPIFetch_Subscriber_Detail_WithData:(NSArray *)data;
- (void)failedToDoAnAuthenticatedAPIFetch_Subscriber_Detail_WithError:(NSError *)error;
#end
Again, I'm not too fond of the naming convention. You shouldn't have underscores in objective-c method names.
The protocol should be defined in MySingletonClass.h before the declaration of MySingletonClass.
I declared two methods in the protocol, one for delivering the data and one for delivering an error if it fails, so that you can notify the user that it failed.
To use the protocol you need the following:
#interface SubscribersDetailViews2 : UITableViewController <MySingletonClassDelegate>
You also need to implement the methods declared in the protocol, but I'll leave that implementation to you.
Since the fetching of data already seems to be happening in the background I don't think I'll need to explain how to do that. One important thing to remember is that you want to execute the delegate methods on the main thread. Here's the code to do that:
- (void)doAnAuthenticatedAPIFetch_Subscriber_Detail:(NSUInteger)index delegate:id<MySingletonClassDelegate>delegate {
// Fetching data in background
if (successful) {
[self performSelectorOnMainThread:#selector(didDoAnAuthenticatedAPIFetch_Subscriber_Detail_WithData:) withObject:data waitUntilDone:NO];
} else {
[self performSelectorOnMainThread:#selector(failedToDoAnAuthenticatedAPIFetch_Subscriber_Detail_WithError:) withObject:error waitUntilDone:NO];
}
}
Just to be clear the // Fetching data in background is supposed to be replaced by your code. I assume that your code produces the variables (NSArray *data, NSError *error, BOOL successful) that I use.
That's about it, if you need clarification on anything let me know.
There are a number of options:
Cache the data, i.e., take a full copy of it on the iOS device (may not be practical of course)
Display an interstitial screen saying "loading" and then move to the "real" screen when the data has downloaded
Have, effectively, two different data sources for your table. The first is your current one. The second would be a single cell saying "Loading..."
In short, there's no point and click way of doing this but there's no problem downloading the data on the fly as long as you tell your users what's happening.