Custom Sound for macosx notification - objective-c

I'm working on project that needs to create a notification in macosx(11.3, Big Sur) with a custom sound.
I have referenced apple official documents and found an obj-c code that should work which is written below.
// Configure the notification's payload.
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
content.title = [NSString localizedUserNotificationStringForKey:#"Hello!" arguments:nil];
content.body = [NSString localizedUserNotificationStringForKey:#"Hello_message_body"
arguments:nil];
content.sound = [UNNotificationSound defaultSound];
// Deliver the notification in five seconds.
UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger
triggerWithTimeInterval:5 repeats:NO];
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:#"FiveSecond"
content:content trigger:trigger];
// Schedule the notification.
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
[center addNotificationRequest:request];
The code works fine, however, when I fix the code to play a custom sound (example.wav) file. It does not apply and still plays the defaultSound.
...
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
content.title = [NSString localizedUserNotificationStringForKey:#"Hello!" arguments:nil];
content.body = [NSString localizedUserNotificationStringForKey:#"Hello_message_body"
arguments:nil];
content.sound = [UNNotificationSound soundNamed:#"example.wav"];
...
I have copied the wav file by using Xcode (target > Build Phases > Copy Bundle Resource) which copies the file to the bundles Contents/Resources directory. I believe that the code from the official document should work and I would appreciate any help I can get.

Related

YouTube PlayListitemInsert code not working API

I have code that executes a youtube upload that's working fine, when it's done, it then attempts to move the video to a specific playlist.
For testing, I have hardcoded the playlist (it's correct and re-verified) and the videoid (it does exist in my channel) into the code.
I cannot get the video to to the playlist I specify and get the output below from the NSlog query1, but no errors.
Query1: GTLQueryYouTube 0x1700b0860: {method:youtube.playlistItems.insert params:(part) bodyObject:GTLYouTubePlaylistItem}
Any ideas what I am missing?
// Enter PlaylistItem Code
GTLYouTubePlaylistItem *playlistitem = [[GTLYouTubePlaylistItem alloc] init];
GTLYouTubePlaylistItemSnippet *playlistitemSnippet = [[GTLYouTubePlaylistItemSnippet alloc] init];
playlistitemSnippet.playlistId = #"PL4YcQc6s41BjKOoAPAQ_B-KNC2JBB3gl2";
playlistitemSnippet.resourceId.kind = #"youtube#video";
playlistitemSnippet.resourceId.videoId = #"4frmxoGMOcQ";
GTLQueryYouTube *query1 = [GTLQueryYouTube queryForPlaylistItemsInsertWithObject:playlistitem part:#"snippet"];
UIAlertView *waitIndicator1 = [Utils showWaitIndicator:#"Moving Video to Playlist"];
NSLog(#"Query1: %#", query1);
[service executeQuery:query1
completionHandler:^(GTLServiceTicket *ticket,
GTLYouTubePlaylistItem *resource, NSError *error) {
[waitIndicator1 dismissWithClickedButtonIndex:0 animated:YES];
Ended up scrapping this and used the playlist auto add feature in youtube. Way easier.

Stuck Uploading (Google Drive Objective-C API on OS X)

I am trying to upload simple .txt file as a test. It's only 4kb. Here is my code:
-(IBAction)uploadFile:(id)sender{
if (![self.credentials canAuthorize]) {
GTMOAuth2WindowController *windowController;
windowController = [[[GTMOAuth2WindowController alloc] initWithScope:scope clientID:kClientID clientSecret:kClientSecret keychainItemName:kKeychainItemName resourceBundle:nil] autorelease];
[windowController signInSheetModalForWindow:self.window
delegate:self
finishedSelector:#selector(windowController:finishedWithAuth:error:)];
}else{
NSLog(#"Credentials already authorized.");
}
GTLDriveFile *driveFile = [GTLDriveFile object];
driveFile.title = #"myfile";
driveFile.descriptionProperty = #"Uploaded by Google Drive API test.";
driveFile.mimeType = #"text/plain";
NSData *data = [[NSFileManager defaultManager] contentsAtPath:#"/Users/Blake/Downloads/glm/util/autoexp.txt"];
GTLUploadParameters *params = [GTLUploadParameters uploadParametersWithData:data MIMEType:driveFile.mimeType];
GTLQueryDrive *query = [GTLQueryDrive queryForFilesInsertWithObject:driveFile uploadParameters:params];
NSLog(#"Starting Upload to Google Drive");
[self.progressBar setHidden:FALSE];
[self.progressBar startAnimation:sender];
[self.driveService executeQuery:query completionHandler:^(GTLServiceTicket *st, GTLDriveFile *df, NSError *error){
[self.progressBar setHidden:TRUE];
if (error == nil) {
NSLog(#"File upload succeeded");
}else{
NSLog(#"Uh-oh: File upload failed");
}
}];
}
The GTMOAuth2Authentication is authorized and the completion handler block never executes.
I looked at Activity Monitor and it says my application has sent 54 packets in the beginning. So I guess something is being sent.
How can I tell what's going wrong here, if the block never finishes to give me an error?
Could someone please help me understand what I am doing wrong?
I've recently got problem with sticking on GTMOAuth2WindowController. It was unable to present self window. I spent a lot of time in debugger and found that I forget to add WebKit.framework. It was not documented explicitly and there were no any messages in runtime (minus in google dev karma)))). So, maybe your problem also in that? Try to check your frameworks set and compare it with examples shipped with GTL.

How to launch Apps, from my App, with a custom parameter so I can check whether the app was launched by me?

I'm working on this app that launches other apps. I'm listening to app launches using:
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self
selector:#selector(appLaunched:) name:NSWorkspaceDidLaunchApplicationNotification
object:nil];
And I launch them using (Mail is just an example):
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSArray arrayWithObject:#"lalalala"], NSWorkspaceLaunchConfigurationArguments, nil];
[[NSWorkspace sharedWorkspace] launchApplicationAtURL:[NSURL URLWithString:#"/Applications/Mail.app"] options:NSWorkspaceLaunchWithoutActivation configuration:dict error:nil];
I did some research, and I saw that you can send an argument when you launch an app (that's why I used the var dict in the code above), but I'm having an issue with this: even using NSWorkspaceLaunchWithoutActivation, the Mail.app is launched and becomes focused with a new composing window. I don't know why it's doing that.
Another thing, if I manage to successfully send a custom argument without focusing the app, how can I check if the app was launched by me (check if the argument is there)?
PS: I'm looking for App Store-ready methods.
Send the timestamp (UTC) together with the app name you started to your server or a local file if possible.
Then you can track it.
Firstly, I'd try NSWorkspaceLaunchAndHide if NSWorkspaceLaunchWithoutActivation isn't "working". Not ideal, no.. but a kludge...
Secondly... here's a "full, running example" that does the trick..
#import <Cocoa/Cocoa.h>
NSString *psAUX(NSString*grep) {
FILE *read_f; char buff[BUFSIZ+1]; int char_rd; NSString *res, *cmnd;
memset(buff, '\0', sizeof(buff));
cmnd = [NSString stringWithFormat:#"/bin/ps aux|grep -i %#",grep];
read_f = popen(cmnd.UTF8String, "r");
if (read_f == NULL) return nil;
char_rd = fread(buff, sizeof(char), BUFSIZ, read_f);
if (!char_rd) return nil;
return res = [NSString stringWithUTF8String:buff], pclose(read_f), res;
}
int main(int argc, char *argv[]) { #autoreleasepool {
NSString* secretStr; NSURL *mailURL; NSDictionary *cfg; NSWorkspace *ws; NSApplication.sharedApplication;
secretStr = #"TAMPAX";
mailURL = [NSURL URLWithString:#"file:///Applications/Mail.app"];
cfg = #{NSWorkspaceLaunchConfigurationArguments:#[secretStr]};
ws = NSWorkspace.sharedWorkspace;
[ws launchApplicationAtURL:mailURL options:0 configuration:cfg error:nil];
fprintf(stderr,"%s",
[psAUX(#"Mail.app") containsString:secretStr]
? "You ARE Mail's baby's daddy!"
: "Hands off, she's NOT yours!");
[NSApp run]; } }
NSLog -> You ARE Mail's baby's daddy!
Congratulations!
You can create a new Task using NSTask. With NSTask you can set arguments as well as some environment variables to app so that you can check if it is launched by you or by someone else.
Here is the sample code sniffet to do so:
NSTask* taskApp = [[NSTask alloc] init];
[taskApp setLaunchPath:#"App path goes here"];
[taskApp setArguments:[NSArray arrayWithObjects:#"Arg1",#"arg2", nil]];
[taskApp setEnvironment: [[NSProcessInfo processInfo] environment]];
[taskApp launch];

How to get upload date of a file Amazon S3, AWS IOS SDK

I have a S3 bucket with files in it. I can successfully download and display the file on my app.
However I want to learn that if the document is the latest or not. With Firefox S3 extension I can see that in bucket file name, file size and upload time are saved to S3. An example of upload time is 10/10/2012 11:35 PM
to get url I use
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
// Set the content type so that the browser will treat the URL as an image.
S3ResponseHeaderOverrides *override = [[S3ResponseHeaderOverrides alloc] init];
override.contentType = #" ";
// Request a pre-signed URL to picture that has been uplaoded.
S3GetPreSignedURLRequest *gpsur = [[S3GetPreSignedURLRequest alloc] init];
gpsur.key = _fileName;
gpsur.bucket = [Constants pictureBucket];
gpsur.expires = [NSDate dateWithTimeIntervalSinceNow:(NSTimeInterval) 3600]; // Added an hour's worth of seconds to the current time.
gpsur.responseHeaderOverrides = override;
// Get the URL
NSError *error;
NSURL *url = [self.s3 getPreSignedURL:gpsur error:&error];
How can I get upload date of a file on Amazon S3?
EDIT::::ANSWER
OK thanks to answer with following method I can get the date
S3GetObjectMetadataRequest *getMetadataRequest = [[S3GetObjectMetadataRequest alloc] initWithKey:_fileName withBucket:[Constants pictureBucket]];
S3GetObjectMetadataResponse *getMetadataResponse = [self.s3 getObjectMetadata:getMetadataRequest];
NSString *fileLastModifiedDate = [[NSString alloc] init];
fileLastModifiedDate = [NSString stringWithFormat:#"%#",getMetadataResponse.lastModified];
NSLog(#"Last Modified date %#",fileLastModifiedDate);
You have to make a S3GetObjectMetadataRequest.
S3GetObjectMetadataRequest *getMetadataRequest = [[S3GetObjectMetadataRequest alloc] initWithKey:filePath withBucket:BUCKET_NAME];
S3GetObjectMetadataResponse *getMetadataResponse = [self getObjectMetadata:getMetadataRequest];
http://docs.amazonwebservices.com/AmazonS3/latest/dev/UsingMetadata.html
Mord Fustang, one thing though about the code in your answer. You don't need to allocate an NSString object before accessing it from the response.
NSString *fileModifiedDate = getMetadataResponse.lastModified;
NSLog(#"Last Modified date %#", fileModifiedDate);

Gdata objective-c upload photo error 400 photo data must be set(picasa)

Right now I am trying to upload a photo to Picasa using the objective c client like below:
GDataServiceGooglePhotos* service =
[self photoService];
// get the URL for the album
NSURL *albumURL = [GDataServiceGooglePhotos
photoFeedURLForUserID:userEmailAdress albumID:albumName
albumName:nil photoID:nil kind:#"album" access:#"all"];
// set a title and description for the new photo
NSDateFormatter *df = [[NSDateFormatter alloc] init];
df.dateFormat = #"yyyyMMddHHmmssSSSS";
GDataTextConstruct *title, *desc;
title = [GDataTextConstruct textConstructWithString:[df stringFromDate:[NSDate date]]];
desc = [GDataTextConstruct textConstructWithString:[descriptionTextfield text]];
GDataEntryPhoto *newPhoto = [GDataEntryPhoto photoEntry];
[newPhoto setTitle:title];
[newPhoto setPhotoDescription:desc];
// attach the photo data
NSData *data = UIImageJPEGRepresentation(imageView.image, 1.0);
[newPhoto setPhotoData:data];
[newPhoto setPhotoMIMEType:#"image/jpeg"];
[newPhoto setUploadData:data];
[newPhoto setUploadMIMEType:#"image/jpeg"];
[newPhoto setUploadSlug:title.stringValue];
// now upload it
GDataServiceTicket *ticket;
ticket = [service fetchEntryByInsertingEntry:newPhoto forFeedURL:albumURL delegate:self didFinishSelector:#selector(addPhotoTicket:finishedWithEntry:error:)];
[service setServiceUploadProgressSelector:nil];
And here is my addPhotoTicket:finishedWithEntry:error: method
if (error == nil) {
NSLog(#"UPLOADED");
} else {
NSLog(#"THERE WAS AN ERROR");
}
I keep getting "There was an error", and failedWithStatus:400 data:Photo data or source id must be included. Any help is greatly appreciated.
Thanks.
As shown in the GooglePhotosSample application, uploading should be done to the URL of an album's uploadLink. Don't try to make an album URL manually for uploading. The album ID is not the album's name.
UIImageJPEGRepresentation can easily fail; check that it is returning non-nil data.
setPhotoData: and setPhotoMIMEType: are synonyms for setUploadData: and setUploadMIMEType:; there is no need to call both.
setTitle: and setPhotoDescription: have "WithString" versions so there's no need to create a text construct explicitly to set those.
Enable the library's http logging to see the actual server requests and responses.