if loop that running asynchoursly - objective-c

Hello everyone, I want to create if loop that running asynchoursly with this code:
NSString *care = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://localhost/untitled.txt"]];
if (care == #"ONRED") { //untitled.txt = ONRED
[red_on setHidden:NO];
[red_off setHidden:YES];
}
How I can run the if statement like a loop?

If I get you right, you can put those statements in a method and call performSelectorInBackground:
(void)asyncMethod {
NSString *care = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://localhost/untitled.txt"]];
if (care == #"ONRED") { //untitled.txt = ONRED
[red_on setHidden:NO];
[red_off setHidden:YES];
}
}
// in some other method
[self performSelectorInBackground:#selector(asyncMethod) withObject:nil];
Another option is to use the grand central dispatch (as described in this answer):
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
(unsigned long)NULL), ^(void) {
NSString *care = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://localhost/untitled.txt"]];
if (care == #"ONRED") { //untitled.txt = ONRED
[red_on setHidden:NO];
[red_off setHidden:YES];
}
});

Related

OBJC AVSpeechUtterance writeUtterance how?

I am trying to create a TTS to file in Objc.
Since iOS13 can write it to a file.
But I'm stuck with writeUtterance:toBufferCallback.
Do someone has an exemple with this function in objc?
[synth speakUtterance:utterance];
Referring to the potential answer in Swift, this would be the Objective-C implementation
AVSpeechSynthesizer *synthesizer = [[AVSpeechSynthesizer alloc] init];
AVSpeechUtterance *utterance = [[AVSpeechUtterance alloc] initWithString:#"test 123"];
AVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithLanguage:#"en-US"];
[utterance setVoice:voice];
__block AVAudioFile *output = nil;
[synthesizer writeUtterance:utterance
toBufferCallback:^(AVAudioBuffer * _Nonnull buffer) {
AVAudioPCMBuffer *pcmBuffer = (AVAudioPCMBuffer*)buffer;
if (!pcmBuffer) {
NSLog(#"Error");
return;
}
if (pcmBuffer.frameLength != 0) {
//append buffer to file
if (output == nil) {
output = [[AVAudioFile alloc] initForWriting:[NSURL fileURLWithPath:#"test.caf"]
settings:pcmBuffer.format.settings
commonFormat:AVAudioPCMFormatInt16
interleaved:NO error:nil];
}
[output writeFromBuffer:pcmBuffer error:nil];
}
}];

Save Thread not working NSSavePanel when Sandboxed OSX

The following function is called after the savepanel save, the application is basically to splice an image into multiple pictures - this works however when sandboxed it doesn't, I believe it's the save thread which isn't working - does anyone know why this isn't working when sandboxed
- (void)saveThread{
NSLog(#"Save thread started");
#autoreleasepool {
NSImage *image = [[NSImage alloc] initWithContentsOfFile:tileCutterView.filename];
[rowBar setIndeterminate:NO];
[columnBar setIndeterminate:NO];
[rowBar setMaxValue:(double)[image rowsWithTileHeight:[heightTextField floatValue]]];
[rowBar setMinValue:0.];
[rowBar setDoubleValue:0.];
[columnBar setMinValue:0.];
[columnBar setMaxValue:(double)[image columnsWithTileWidth:[widthTextField floatValue]]];
[columnBar setDoubleValue:0.];
progressCol = 0;
progressRow = 0;
tileRowCount = [image rowsWithTileHeight:tileHeight];
tileColCount = [image columnsWithTileWidth:tileWidth];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
TileCutterOutputPrefs outputFormat = (TileCutterOutputPrefs)[defaults integerForKey:#"OutputFormat"];
for (int row = 0; row < tileRowCount; row++)
{
// Each row operation gets its own ImageRep to avoid contention
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:[image CGImageForProposedRect:NULL context:NULL hints:nil]];
TileOperation *op = [[TileOperation alloc] init];
op.row = row;
op.tileWidth = tileWidth;
op.tileHeight = tileHeight;
op.imageRep = imageRep;
op.baseFilename = baseFilename;
op.delegate = self;
op.outputFormat = outputFormat;
[queue addOperation:op];
}
}
}
UPDATE: I've added the other functions relating to this code:
- (IBAction)saveButtonPressed:(id)sender{
NSSavePanel *sp = [NSSavePanel savePanel];
[sp setRequiredFileType:#"jpg"];
[sp beginSheetForDirectory:[NSString stringWithFormat:#"%#/Pictures", NSHomeDirectory()]
file:#"output.jpg"
modalForWindow:window
modalDelegate:self
didEndSelector:#selector(didEndSaveSheet:returnCode:conextInfo:)
contextInfo:nil];
}
-(void)didEndSaveSheet:(NSSavePanel *)savePanel
returnCode:(int)returnCode conextInfo:(void *)contextInfo
{
if (returnCode == NSOKButton)
{
NSURL *fileURL = [savePanel URL];
NSString *filePath = [fileURL path];
self.baseFilename = filePath;
tileHeight = [heightTextField intValue];
tileWidth = [widthTextField intValue];
[self performSelector:#selector(delayPresentSheet) withObject:nil afterDelay:0.1];
}
}
- (void)delayPresentSheet{
[progressLabel setStringValue:#"Splicing imageā€¦"];
[rowBar setIndeterminate:YES];
[columnBar setIndeterminate:YES];
[rowBar startAnimation:self];
[columnBar startAnimation:self];
[NSApp beginSheet: progressWindow
modalForWindow: window
modalDelegate: self
didEndSelector: #selector(didEndSheet:returnCode:contextInfo:)
contextInfo: nil];
[self performSelectorInBackground:#selector(saveThread) withObject:nil];
}
UPDATE: CONSOLE ERROR:
06/05/2015 11:30:49.592 sandboxd[8455]: ([8720]) MyApp(8720) deny file-write-create /Users/Me/Documents/output_1_0.jpg
06/05/2015 11:30:49.592 sandboxd[8455]: ([8720]) MyApp(8720) deny file-write-create /Users/Me/Documents/output_1_1.jpg
06/05/2015 11:30:49.592 sandboxd[8455]: ([8720]) MyApp(8720) deny file-write-create /Users/Me/Documents/output_0_1.jpg
NSSavePanel can not grant you access for several files at once. You need to use a NSOpenPanel and ask the user to grant access for the whole directory. Use then the NSURL from the NSOpenPanel and add your files to this.
More explanation in the answer of your other question and in the Apple Documentation here.

how to open powerpoint by pspdfkit?

NSURL *documentURL = [[[NSBundle mainBundle] resourceURL] URLByAppendingPathComponent:#"item_70_1_3.ppt"];
PSPDFDocument *document = [PSPDFDocument documentWithURL:documentURL];
NSURL *tempURL = PSPDFTempFileURLWithPathExtension(#"flattened_signaturetest", #"pdf");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
[[PSPDFProcessor defaultProcessor] generatePDFFromDocument:document pageRange:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, document.pageCount)] outputFileURL:tempURL options:#{kPSPDFProcessorAnnotationTypes : #(PSPDFAnnotationTypeAll)} progressBlock:^(NSUInteger currentPage, NSUInteger numberOfProcessedPages, NSUInteger totalPages) {
// Access UI only from main thread.
dispatch_async(dispatch_get_main_queue(), ^{
[PSPDFProgressHUD showProgress:(numberOfProcessedPages+1)/(float)totalPages status:PSPDFLocalize(#"Preparing...")];
});
} error:NULL];
// completion
dispatch_async(dispatch_get_main_queue(), ^{
[PSPDFProgressHUD dismiss];
PSPDFDocument *flattenedDocument = [PSPDFDocument documentWithURL:tempURL];
PSPDFViewController *pdfController = [[PSPDFViewController alloc] initWithDocument:flattenedDocument];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:pdfController];
[self presentViewController:navController animated:YES completion:NULL];
});
});
i open a empty content using above code : (
The PSPDFProcessor feature is experimental. Please try if the PPT file works if you open it with Safari, it uses mostly Apple's libraries and they can fail for certain files. The code here looks like it's simply copied from my examples in PSPDFCatalog and is thus fine.

How to load several photos with assetForURL with a list of URLs

For a list of URLs I need to load the photos with ALAssetsLibrary:assetForURL, and this within one method.
Since this method works async but it is not iterating over the passed list of URLs, as we all know.
I found this snippet (which should work):
- (void)loadImages:(NSArray *)imageUrls loadedImages:(NSArray *)loadedImages callback: (void(^)(NSArray *))callback
{
if (imageUrls == nil || [imageUrls count] == 0) {
callback(loadedImages);
}
else {
NSURL *head = [imageUrls head];
__unsafe_unretained id unretained_self = self;
ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];
[library assetForURL:head resultBlock:^(ALAsset *asset) {
ALAssetRepresentation *assetRepresentation = asset.defaultRepresentation;
UIImage *image = [UIImage imageWithCGImage:assetRepresentation.fullResolutionImage scale:assetRepresentation.scale orientation:(UIImageOrientation)assetRepresentation.orientation];
[unretained_self loadImages:[imageUrls tail] loadedImages:[loadedImages arrayByAddingObject:image] callback:callback];
} failureBlock:^(NSError *error) {
[unretained_self loadImages:[imageUrls tail] loadedImages:loadedImages callback:callback];
}];
}
}
How do I write the method definition in the form (above all the callback)
void loadImages(NSArray *imageUrls, NSArray *loadedImages, ...) ?
How do I call this method from another method (again mainly the callback part) ?
Can the callback be in the calling method or a 3rd method needed for this? and how does this method need to be written?
I have found the snippet here: http://www.calebmadrigal.com/functional-programming-deal-asynchronicity-objective-c/
Use NSThread to call the loadImages method.
NSMutableArray *imageCollection = [NSThread detachNewThreadSelector:#selector (loadImages:)
toTarget:self
withObject:imageUrlsCollection];
- (NSMutableArray *)loadImages:(NSArray *)imageUrls
{
ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];
NSMutableArray *loadedImages = [[NSMutableArray alloc] init];
#try
{
for(int index = 0; index < [imageUrls count]; index++)
{
NSURL *url = [imageUrls objectAtIndex:index];
[library assetForURL:url resultBlock:^(ALAsset *asset) {
ALAssetRepresentation *assetRepresentation = asset.defaultRepresentation;
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *image = [UIImage imageWithCGImage:assetRepresentation.fullResolutionImage scale:assetRepresentation.scale orientation:(UIImageOrientation)assetRepresentation.orientation];
[loadedImages addObject:image];
});
} failureBlock:^(NSError *error) {
NSLog(#"Failed to get Image");
}];
}
}
#catch (NSException *exception)
{
NSLog(#"%s\n exception: Name- %# Reason->%#", __PRETTY_FUNCTION__,[exception name],[exception reason]);
}
#finally
{
return loadedImages;
}
}
Note: With ARC,take care about invalid attempt to access ALAssetPrivate past the lifetime of its owning ALAssetsLibrary issue
Here is the fix :)

playing second Sound

am trying to do a simple AVAudioPlayer based application to play 2 different music upon button pressed, there is 2 views, the first is the home view contains 2 buttons,each button set a song which is named as integer(1.mp3, 2.mp3.....etc)and here'e the code
#import "podHome.h"
#import "podMusic.h"
#import "ArabAppDelegate.h"
#implementation podHome
#synthesize song1;
#synthesize tabi;
int CurrentPlay;
NSString *Currenttxt;
-(IBAction)uae{
CurrentPlay=1;
Currenttxt=#"uae";
podMusic *newContro=[[podMusic alloc] init];
[newContro setCurrentPlay1:CurrentPlay setCurrentText:Currenttxt];
ArabAppDelegate *theDelegate = (ArabAppDelegate*)[[UIApplication sharedApplication] delegate];
tabi = theDelegate.tabcontrolPod;
tabi.selectedIndex = 1;
[newContro release];
}
-(IBAction)libya{
CurrentPlay=2;
Currenttxt=#"uae";
podMusic *newContro=[[podMusic alloc] init];
[newContro setCurrentPlay1:CurrentPlay setCurrentText:Currenttxt];
ArabAppDelegate *theDelegate = (ArabAppDelegate*)[[UIApplication sharedApplication] delegate];
tabi = theDelegate.tabcontrolPod;
tabi.selectedIndex = 1;
[newContro release];
}
these tow (IBActions) are linked to the two buttons when pressing on one of them it will change to the other view and start playing the song
- (void)viewWillAppear:(BOOL)animated {
if((played == 1)&&(isBacked==FALSE)){
NSString *filePath = [[NSBundle mainBundle] pathForResource:texting
ofType:#"txt"];
NSString *filenameString = [NSString stringWithContentsOfFile:filePath usedEncoding:nil error:nil];
CurrentTex.text = filenameString;
AudioSessionInitialize(NULL, NULL, NULL, NULL);
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,sizeof(sessionCategory), &sessionCategory);
AudioSessionSetActive(YES);
playBtnBG = [[UIImage imageNamed:#"play-pod.png"] retain];
pauseBtnBG = [[UIImage imageNamed:#"pause-pod.png"] retain];
[playButton setBackgroundImage:pauseBtnBG forState:UIControlStateNormal];
[self registerForBackgroundNotifications];
updateTimer = nil;
duration.adjustsFontSizeToFitWidth = YES;
currentTime.adjustsFontSizeToFitWidth = YES;
progressBar.minimumValue = 0.0;
NSString *path=[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%d",CurrentPlay] ofType:#"mp3"];
self.player=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[player stop];
//self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
if (self.player)
{
[self updateViewForPlayerInfo:player];
[self updateViewForPlayerState:player];
player.numberOfLoops = 0;
player.delegate = self;
}
[self startPlaybackForPlayer:player];
fileName.text= [[NSString alloc]initWithFormat:#"%#", songName];
// [fileURL release];
// CurrentPlay = 0;
isBacked = TRUE;
}
[super viewWillAppear:animated];
}
- (void)setCurrentPlay1:(int)varP setCurrentText:(NSString *)varT{
CurrentPlay = varP;
texting = varT;
played = 1;
isBacked = FALSE;
}
but the problem is that when the song is playing and am back to home view and pressing on the other song's button, it starts to play with the first one at the same time, i think the first should stop to begin the other, what should i release to do that???
My guess is that you have two instances of the AVAudioPlayer, and when you set them both to play, they both do!
One solution would be to tell other players to stop when you activate a new one, but that will quickly become troublesome as the number of players increases.
Instead you;'d be better of just setting up one player, and change it's song in accordance to what button was pressed. That way, there is no chance that two music tracks will play at the same time.
In your first button action write like this.
if(player2.isPlaying)
{
[player2 stop];
}
in the same way do the same thing in second button action like this.
if(player1.isPlaying)
{
[player1 stop];
}