How to interpret MPMediaItemCollection codes - ios

When I choose to print out MPMediaItemCollection in my app I simply receive codes such as 0x17eb5d30. Is anybody aware of how to get data from these random letters and numbers. I am looking at hopefully retrieving the title of the song as well as the length of the song in seconds.
My code is here
#IBAction func pickSong(sender: AnyObject) {
self.presentPicker(sender)
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var DestView: playMusicViewController = segue.destinationViewController as! playMusicViewController
DestView.selectedSong = MPMediaItemCollection()
}
}
func presentPicker (sender:AnyObject) {
let mediaPicker = MPMediaPickerController(mediaTypes: .Music)
mediaPicker.delegate = self
mediaPicker.allowsPickingMultipleItems = false
presentViewController(mediaPicker, animated: true, completion: {})
}
also the extension view controller
extension ViewController : MPMediaPickerControllerDelegate {
// must implement these, as there is no automatic dismissal
func mediaPicker(mediaPicker: MPMediaPickerController!, didPickMediaItems mediaItemCollection: MPMediaItemCollection!) {
let player = MPMusicPlayerController.applicationMusicPlayer()
player.setQueueWithItemCollection(mediaItemCollection)
player.play()
println(mediaItemCollection)
self.dismissViewControllerAnimated(true, completion: nil)
}
func mediaPickerDidCancel(mediaPicker: MPMediaPickerController!) {
self.dismissViewControllerAnimated(true, completion: nil)
}
}

The number and letter you are seem is a pointer to an address in memory (normally not very useful for us) if you want to access details about the music you need to access the properties of the objects you received back for the picker. The example below show how to retrieve the title of the music selected:
func mediaPicker(mediaPicker: MPMediaPickerController!, didPickMediaItems mediaItemCollection: MPMediaItemCollection!) {
let player = MPMusicPlayerController.applicationMusicPlayer()
player.setQueueWithItemCollection(mediaItemCollection)
player.play()
let item = mediaItemCollection.representativeItem
let title = item.title
println(title)
self.dismissViewControllerAnimated(true, completion: nil)
}
I hope that help you!

Related

How do i compile all contact's phone numbers into one cell - using CNContact

My code I am using to source the contact's phone number is below, what i would like to do is have all the contacts phone numbers (landline, mobiles etc) shown together, example 0402 000 000, 618 802336, 0423 000 000 (together in the one textField)
My code below
// Retrieve contact details ---------------------------
#IBAction func show(_ sender: Any) {
let contacVC = CNContactPickerViewController()
contacVC.delegate = self
self.present(contacVC, animated: true, completion: nil)
}
func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
print(contact.phoneNumbers)
let numbers = contact.phoneNumbers.first
print((numbers?.value)?.stringValue ?? "")
self.Phone.text = "\((numbers?.value)?.stringValue ?? "")"
}
func contactPickerDidCancel(_ picker: CNContactPickerViewController) {
self.dismiss(animated: true, completion: nil)
}
You can display all phone number as like below
let contact = CNContact()
let numbers = contact.phoneNumbers.compactMap { $0.value.stringValue }
self.Phone.text = numbers.joined(separator: ", ")

How to disable contact section ( message , call , video , mail ) from CNContactPickerViewController

I want to know it possible to remove or disable menu in that section.
Thank you.
extension ViewController: CNContactPickerDelegate {
#IBAction func pickerBtnAction(_ sender: Any) {
let contacVC = CNContactPickerViewController()
contacVC.displayedPropertyKeys = [CNContactPostalAddressesKey]
contacVC.hidesBottomBarWhenPushed = true
contacVC.displayedPropertyKeys = [CNContactGivenNameKey, CNContactImageDataAvailableKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey, CNContactThumbnailImageDataKey, CNContactIdentifierKey];
contacVC.delegate = self
self.present(contacVC, animated: true, completion: nil)
}
func contactPicker(_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty) {
if let phone = contactProperty.value as? CNPhoneNumber {
print(phone.stringValue)
}
}
}
let cncontactVC = CNContactViewController()
cncontactVC.allowsActions = false
You need to use instance property allowsActions of CNContactViewController.
From the official docs,
Determines whether to display buttons for actions such as sending a
text message or initiating a FaceTime call.
while creating an object of CNContactViewController,
let contactVC = CNContactViewController()
contactVC.allowsActions = false
There are other useful properties as well ,
shouldShowLinkedContacts
allowsEditing

iOS Swift CNContactPickerViewController search contact and add to selection

I am using iOS 9 and Swift 2.2
I have implemented iOS inbuilt CNContactPickerViewController using CNContactPickerDelegate to get the contact numbers,
In the CNContactPickerViewController Screen, when I click on search field on top and search for a name, I need to add that name to my selection but nothing happens after tapping the contact.
I searched everywhere and dint find any solution to this
Do I need to add anything to my code or is it a iOS 9 bug
#IBAction func AddBtnKlkFnc(sender: AnyObject)
{
let contactPicker = CNContactPickerViewController()
contactPicker.delegate = self
contactPicker.displayedPropertyKeys =
[CNContactPhoneNumbersKey]
self.presentViewController(contactPicker, animated: true, completion: nil)
}
func contactPicker(picker: CNContactPickerViewController, didSelectContacts ContctAryVar: [CNContact])
{
for ContctVar in ContctAryVar
{
let ContctDtlVar = ContctDtlCls()
ContctDtlVar.ManNamVar = CNContactFormatter.stringFromContact(ContctVar, style: .FullName)!
for ContctNumVar: CNLabeledValue in ContctVar.phoneNumbers
{
var MobNumVar = ((ContctNumVar.value as! CNPhoneNumber).valueForKey("digits") as? String)!
if(MobNumVar.Len() > 10)
{
MobNumVar = MobNumVar.GetLstSubSrgFnc(10)
}
ContctDtlVar.MobNumVar = MobNumVar
ContctDtlAryVar.append(ContctDtlVar)
}
}
}
The search results seem to be working in single selection mode only, so make sure you implement
func contactPicker(CNContactPickerViewController, didSelect: CNContact)
only, but not
func contactPicker(CNContactPickerViewController, didSelect: [CNContact])
If you implement both, the version wich takes only one CNContact as argument is ignored and the multi selection mode is used instead.
Use this updated code and
#IBAction func AddBtnKlkFnc(sender: AnyObject)
{
let contactPicker = CNContactPickerViewController()
contactPicker.delegate = self
contactPicker.displayedPropertyKeys =
[CNContactPhoneNumbersKey]
self.presentViewController(contactPicker, animated: true, completion: nil)
}
func contactPicker(picker: CNContactPickerViewController, didSelectContacts ContctAryVar: [CNContact])
{
for ContctVar in ContctAryVar
{
let ContctDtlVar = ContctDtlCls()
ContctDtlVar.ManNamVar = CNContactFormatter.stringFromContact(ContctVar, style: .FullName)!
for ContctNumVar: CNLabeledValue in ContctVar.phoneNumbers
{
var MobNumVar = ((ContctNumVar.value as! CNPhoneNumber).valueForKey("digits") as? String)!
if(MobNumVar.Len() > 10)
{
MobNumVar = MobNumVar.GetLstSubSrgFnc(10)
}
ContctDtlVar.MobNumVar = MobNumVar
ContctDtlAryVar.append(ContctDtlVar)
}
}
delegate.didFetchContacts([contact])
navigationController?.popViewControllerAnimated(true)
}
Here is a swift 4 version
#IBAction func addPhoneContact(_ sender: UIButton) {
let contactPicker = CNContactPickerViewController()
contactPicker.delegate = self
contactPicker.displayedPropertyKeys =
[CNContactPhoneNumbersKey]
self.present(contactPicker, animated: true, completion: nil)
}
extension ViewController: CNContactPickerDelegate {
func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
picker.dismiss(animated: true, completion: nil)
let name = CNContactFormatter.string(from: contact, style: .fullName)
for number in contact.phoneNumbers {
let mobile = number.value.value(forKey: "digits") as? String
if (mobile?.count)! > 7 {
// your code goes here
}
}
}
}
Multi selection and search are mutually exclusive. If you want search to be working you have to go with single selection only and implement only single selection delegate method.

Saving a music from the ipod library - swift

I'm trying to save a music from the iPod library in my app and be able to use it later. I've used the media picker to get the music URL, but I don't know how to save it in my app and play it later. Here is the code that I have used to get the music URL:
#IBAction func music(sender: AnyObject) {
var picker = MPMediaPickerController(mediaTypes: MPMediaType.Music)
picker.delegate = self
picker.allowsPickingMultipleItems = false
picker.prompt = NSLocalizedString("Select one music", comment: "")
self.presentViewController(picker, animated: false, completion: nil)
}
func mediaPicker(mediaPicker: MPMediaPickerController, didPickMediaItems mediaItemCollection: MPMediaItemCollection) {
var url = NSURL()
let items = mediaItemCollection.items
for item in items {
url = item.assetURL!
}
self.dismissViewControllerAnimated(true, completion: nil)
}
func mediaPickerDidCancel(mediaPicker: MPMediaPickerController) {
mediaPicker.dismissViewControllerAnimated(true, completion: nil)
}

Sending SMS from Contacts Fails

I am implementing a seemingly trivial and very popular use case where users select a contact, and send them a precomposed SMS.
However, the SMS ViewController dismisses itself automatically. This is easily reproducible.
How do I fix this?
Here's my code:
import UIKit
import MessageUI
import ContactsUI
class ViewController: UIViewController, MFMessageComposeViewControllerDelegate, CNContactPickerDelegate{
let contactPickerViewController = CNContactPickerViewController()
let messageVC = MFMessageComposeViewController()
override func viewDidLoad() {
super.viewDidLoad()
contactPickerViewController.delegate = self
messageVC.messageComposeDelegate = self
}
func contactPicker(picker: CNContactPickerViewController, didSelectContact contact: CNContact) {
if let phoneNumberValue = contact.phoneNumbers.first?.value as? CNPhoneNumber {
if let phoneNumber = phoneNumberValue.valueForKey("digits") as? String {
// Configure message ViewController
messageVC.recipients = [phoneNumber]
messageVC.body = "Yoyoyo"
picker.presentViewController(messageVC, animated: true, completion: nil)
}
}
}
func messageComposeViewController(controller: MFMessageComposeViewController, didFinishWithResult result: MessageComposeResult) {
self.dismissViewControllerAnimated(true, completion: nil)
}
#IBAction func invite(sender: AnyObject) {
self.presentViewController(self.contactPickerViewController, animated: true, completion: nil)
}
}
The problem is that you are asking your picker to present the message view controller. When contactPicker:picker:didSelectContact: method is called, the picker view controller is automatically being dismissed by the system. This means that the view controller is going away and you are trying to use that view controller to present your next view controller.
What you need to do is have "ViewController" in this case present the message view controller. Below is an example of the portion of your code i changed. You'll notice i have a timer there. This is because if you try to present the messageVC right away, nothing will happen because the contacts view controller isn't done dismissing itself yet.
func contactPicker(picker: CNContactPickerViewController, didSelectContact contact: CNContact) {
if let phoneNumberValue = contact.phoneNumbers.first?.value as? CNPhoneNumber {
if let phoneNumber = phoneNumberValue.valueForKey("digits") as? String {
// Configure message ViewController
messageVC.recipients = [phoneNumber]
messageVC.body = "Yoyoyo"
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.presentViewController(self.messageVC, animated: true, completion: nil)
})
}
}
}

Resources