In cocoa touch 4.x Its possible create or edit a music playlist into the default/bundle music app for iphone/ipad? if it is, how will be the code?
Finally, I found the solution for iOS 9.3 and above. You can use MPMediaLibrary to achieve that.
// Setup your playlist metadata
__auto_type metadata = [[MPMediaPlaylistCreationMetadata alloc] initWithName:#"Playlist Name"];
metadata.authorDisplayName = #"My app name";
metadata.descriptionText = #"Playlist description";
// Save it to get the same playlist next time
NSUUID *uuid = [NSUUID UUID];
// Items to add to your playlist
NSArray<MPMediaItem *> *mediaItems = self.items;
// Get or create your playlist in Apple Music
[[MPMediaLibrary defaultMediaLibrary] getPlaylistWithUUID:uuid creationMetadata:metadata completionHandler:^(MPMediaPlaylist * _Nullable playlist, NSError * _Nullable error) {
// Handle the error
NSLog(#"Got error — %#", error);
// You can add items to your playlist
[playlist addMediaItems:mediaItems completionHandler:^(NSError * _Nullable addError) {
// Handle the error
NSLog(#"finished! error — %#", addError);
}];
}];
You can access information from the iPod Library (iPod Library Access Programming Guide) by creating MPMediaQuerys. This will allow you to retrieve playlists (using the MPMediaPickerControllerDelegate) but I don't think you'll be able to create playlists as you are only given read-only access (as well as playback).
Related
I am using Objective-c to develop an app for iPad. I need to fetch the address book for the contacts. But I get no access request prompt and the access stays denied. The boolean "granted" is never true and the code to get the contacts array is never reached. Therefore the contacts array contactsArray stays empty.
Following is the code I am using:
-(void) fetchAllContacts
{
contactsArray = [[NSMutableArray alloc] init];
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType : CNEntityTypeContacts completionHandler : ^(BOOL granted, NSError * _Nullable error)
{
if (granted)
{
// Code to get the contacts array
// contactsArray = ....
}
}];
}
Any help?
Thank you
iOS will only present the modal access request prompt once. If you have denied the access the first time, the app will be unable to access it until the user changes the app's permissions in the iOS settings.
One option is to present a custom prompt saying access is denied with a button to navigate directly to the app settings page, using UIApplicationOpenSettingsURLString as an URL.
//objc
NSURL * url = [[NSURL alloc] initWithString:UIApplicationOpenSettingsURLString];
[UIApplication.sharedApplication openURL:url];
//swift
if let url = URL(string: UIApplicationOpenSettingsURLString) {
UIApplication.shared.openURL(url)
}
I'm trying to use the new Apple Music APIs from 9.3 to add a song to a playlist created by my app, without adding it to the user's library.
Consider the productID 316654632, it's the song Lisztomania by Phoenix, in the US iTunes Store.
Using the following code, I can play the song
MPMusicPlayerController *musicPlayer = [MPMusicPlayerController systemMusicPlayer];
[musicPlayer setQueueWithStoreIDs:#[#"316654632"]];
[musicPlayer play];
Using the following code, I can add the song to my Apple Music library
[[MPMediaLibrary defaultMediaLibrary] addItemWithProductID:#"316654632" completionHandler:^(NSArray<__kindof MPMediaEntity *> * _Nonnull entities, NSError * _Nullable error) {
NSLog(#"%#", error);
}];
Error is nil, and I can see the song in my library.
But trying the same with a playlist doesn't work.
[[MPMediaLibrary defaultMediaLibrary] getPlaylistWithUUID:uuid creationMetadata:[[MPMediaPlaylistCreationMetadata alloc] initWithName:#"Test Playlist"] completionHandler:^(MPMediaPlaylist * _Nullable playlist, NSError * _Nullable error) {
NSLog(#"%#", error);
if (!error) {
[playlist addItemWithProductID:#"316654632" completionHandler:^(NSError * _Nullable error) {
NSLog(#"%#", error);
}];
}
}];
The playlist is created, I can see it in Music.app, but when I try to add the same product ID I played & added to my library to the playlist, I get an error
Error Domain=MPErrorDomain Code=4 "The requested id could not be found" UserInfo={NSLocalizedDescription=The requested id could not be found}
But how could it not be found if I successfully added the same item to my library?
UPDATE
Good news! Apple has fixed rdar://26408683 on 10.2.1!
In my playlist conversion app (mixlib), the only solution I have found to reliably add some tracks to a newly created playlist is to wait.
In my tests, waiting five seconds seems to be enough.
[[MPMediaLibrary defaultMediaLibrary] getPlaylistWithUUID:uuid creationMetadata:[[MPMediaPlaylistCreationMetadata alloc] initWithName:#"Test Playlist"] completionHandler:^(MPMediaPlaylist * _Nullable playlist, NSError * _Nullable error) {
if (!error) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 /*seconds*/ * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)), ^() {
[playlist addItemWithProductID:#"316654632" completionHandler:^(NSError * _Nullable error) {
NSLog(#"%#", error);
}];
}
}];
I suspect it is a server/network related issue because it sometimes works without waiting. The "requested id" which is not found may be the playlist id, not the track id.
When it starts to work for a playlist, then it will always work. So you don't need to wait before adding each additional track, but only before adding the first one.
I want to implement a functionality in a chat app by which user will be able to search a group by its unique provided code. I have used quickblox for implementing chat functionality. so please provide me a way to do that functionality with quickblox.
Please check official Document of Quickchat .
SimpleSample-chat_users-ios
They have mention all the detail in their document.
Moreover , Just Download the demo and try to implement.
Group_chat
Before implement Group chat don't forget to read typical setting section.
Typical settings [Functionality in Groupchat]
Authentication: Chat history: you may wish to keep
the archive of all public discussion history which is easily supported
by QuickBlox. Some platforms will also require you to implement abuse
and moderation mechanisms which are also supported both via API and
admin panel. File attachments: typically attachments are not supported
1:1 / IM chat: in many applications you may wish to allow users start
a private communication with other user Friending: QuickBlox supports
friending or adding other users to favourites which you may use in
your application - see also [chat: friending / favourite users lists]
start groupchat with creating Dialogue.
Create_new_group_chat_dialog
QBChatDialog *chatDialog = [[QBChatDialog alloc]
initWithDialogID:null type:QBChatDialogTypeGroup];
chatDialog.name = #"Chat with Bob, Sam, Garry"; //set according to requirement
chatDialog.occupantIDs = #[#(55), #(678), #(22)];
[QBRequest createDialog:chatDialog successBlock:^(QBResponse *response, QBChatDialog *createdDialog) {
} errorBlock:^(QBResponse *response) {
}];
Second step --> Create chatnotification
- (QBChatMessage *)createChatNotificationForGroupChatCreation:(QBDialog *)dialog
{
// create message:
QBChatMessage *inviteMessage = [QBChatMessage message];
NSMutableDictionary *customParams = [NSMutableDictionary new];
customParams[#"xmpp_room_jid"] = dialog.roomJID;
customParams[#"name"] = dialog.name;
customParams[#"_id"] = dialog.ID;
customParams[#"type"] = #(dialog.type);
customParams[#"occupants_ids"] = [dialog.occupantIDs componentsJoinedByString:#","];
// Add notification_type=1 to extra params when you created a group chat
//
customParams[#"notification_type"] = #"1";
inviteMessage.customParameters = customParams;
return inviteMessage;
}
...
for (NSString *occupantID in dialog.occupantIDs) {
QBChatMessage *inviteMessage = [self createChatNotificationForGroupChatCreation:dialog];
NSTimeInterval timestamp = (unsigned long)[[NSDate date] timeIntervalSince1970];
customParams[#"date_sent"] = #(timestamp);
// send notification
//
inviteMessage.recipientID = [occupantID integerValue];
[[QBChat instance] sendSystemMessage:inviteMessage completion:^(NSError * _Nullable error) {
}];
}
You will receive opponent in this delegate .
- (void)chatDidReceiveSystemMessage:(QBChatMessage *)message
{
}
You can implement required functionality in group-chat with abolve link.
Like , Get online users ,Leave group chat dialog , Attachment in group. etc.
I am able to access Workout data using workout session but unable to do the same with others such as accessing Height,Weight,Dietary Water, Body Temperature,Blood Pressure etc.
Also i am able to access heart rate but unable to access body temp. Both of them are same vital sign identifiers.
Is it that watch can access only Workout data as mentioned in WWDC 2015 video?
Sample Code:
-(void)bodyTempForLabel :(WKInterfaceLabel *)bodyTempLabel {
HKSampleType *bodyTemp = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyTemperature];
[self readMostRecentSampleType:bodyTemp withCompletion:^(HKQuantitySample *quantitySample, NSError *error) {
if(error) {
NSLog(#"Error Reading Weight From health Kit");
}
self.bodyTemp = quantitySample;
double bodyTempinDegree = [[self.bodyTemp quantity] doubleValueForUnit:[HKUnit unitFromString:[NSString stringWithFormat:#"%#C", #"\u00B0"]]];
dispatch_async(dispatch_get_main_queue(), ^{
[bodyTempLabel setText:[NSString stringWithFormat:#"%f",bodyTempinDegree]];
});
}];
}
-(void)readMostRecentSampleType : (HKSampleType *)sampleType withCompletion:(void(^)(HKQuantitySample *quantitySample,NSError *error))recentSample {
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:HKSampleSortIdentifierEndDate ascending:NO];
HKQuery *sampleQuery = [[HKSampleQuery alloc] initWithSampleType:sampleType predicate:nil limit:HKObjectQueryNoLimit sortDescriptors:#[sortDescriptor] resultsHandler:^(HKSampleQuery * _Nonnull query, NSArray<__kindof HKSample *> * _Nullable results, NSError * _Nullable error) {
if(!error) {
// No results retuned array empty
HKQuantitySample *mostRecentSample = results.firstObject;
recentSample(mostRecentSample,error);
}
}];
[_healthStore executeQuery:sampleQuery];
}
Any help would be appreciated. Thanks!!!
It seems you'll need to use a real device to debug. I'm unable to get any value from HK when running the simulator but it works fine in the Apple Watch. (Using XCode 7 Beta 5).
The apple watch has access to all health kit types (though only a subset of the data). Has your app asked for permission for all of those types? Each type you want to read or write needs to be explicitly asked for when you setup your health store. For example, to read energy burned, distance, and heart rate you need to include:
let typesToRead = Set([
HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierActiveEnergyBurned)!,
HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDistanceWalkingRunning)!,
HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)!
])
self.healthStore.requestAuthorizationToShareTypes(typesToShare, readTypes: typesToRead) { success, error in
// ...
}
I am developing a board game. Using Game Center for multiplayer, but currently stuck at how to send or receive invitations of GKTurnBasedMatch. I am creating match programmatically using:
GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.defaultNumberOfPlayers = 2;
[GKTurnBasedMatch findMatchForRequest:request
withCompletionHandler:
^(GKTurnBasedMatch *match, NSError *error) {
if(error) {
NSLog(#"%#", error.localizedDescription);
return;
}
[self.delegate startGameForMatch:match];
}];
The GKTurnBasedMatch instance in parameter of above block, has only local player with other player as nil and I need to display details of opponent in the game.
NSMutableArray *participantIds = [[NSMutableArray alloc] init];
NSLog(#"%#", match.participants);
for (GKTurnBasedParticipant *participant in match.participants) {
if(participant.playerID) [participantIds addObject:participant.playerID];
}
[GKPlayer loadPlayersForIdentifiers:participantIds
withCompletionHandler:^(NSArray *players, NSError *error) {
NSMutableString *string = [[NSMutableString alloc] init];
for (GKPlayer *player in players) {
[string appendFormat:#"---- Alias: %# DisplayName: %#", player.alias, player.displayName];
}
NSLog(#"%#", string);
}];
Am I missing something or Game Center works like this?
I read that participants of the match wont get invitations until that GKTurnBasedParticipant is GKTurnBasedMatch.currentParticipant but I need to display the details of opponent when game started.
Thanks for the help. Point me in correct direction.
This happens when you create a match against a random opponent. Try creating a second test user in iTunesConnect and signing into that user on a second device.
Then, send that second test player an invite to be your friend. This will allow you to more easily test your game with multiplayer features without having to wait for a random match to be found.
After the friend request is accepted, try creating a new game once more. Now, invite your 'Friend' to your game and start your turn. You will now notice that the (null) variables will - for the most part - be filled in. Something like this should now appear in your log-
GKTurnBasedParticipant 0xb9432e0 - playerID:G:123456789 status:Invited matchOutcome:None lastTurnDate:(null) timeoutDate:(null)