Failing to use MPMediaPickerController - ios

I am trying to use MPMediaPickerController for the first time, in an iOS application.
Here is the relevant code:
......
import MediaPlayer
class ViewController: UIViewController,...,MPMediaPickerControllerDelegate {
......
var mediPic_VC:MPMediaPickerController!
......
#objc func fireMediaPicker() {
if mediPic_VC == nil {
mediPic_VC = MPMediaPickerController(mediaTypes: .anyAudio)
//mediPic_VC = MPMediaPickerController(mediaTypes: .music)
mediPic_VC.delegate = self
}
self.present(mediPic_VC, animated: true, completion: nil)
}
......
// MPMediaPickerControllerDelegate protocol implementation.
func mediaPicker(_ mediaPicker: MPMediaPickerController,
didPickMediaItems mediaItemCollection: MPMediaItemCollection) {
print(#function)
}
func mediaPickerDidCancel(_ mediaPicker: MPMediaPickerController) {
print(#function)
}
// End of MPMediaPickerControllerDelegate protocol implementation.
......
}
As one can see I have a function (fireMediaPicker) to bring up the MPMediaPickerController.
But when I run it, the app shows nothing more than a white screen and the debugging console displays the message:
mediaPickerDidCancel(_:)
proving that the function mediaPickerDidCancel of the MPMediaPickerControllerDelegate protocol has been called.
Instead of the white screen I was expecting to see a list of audio items to choose from.
Beside, I have no idea why mediaPickerDidCancel is called.
What did I miss in the way I am trying to use MPMediaPickerController?

Add these to your plist:
<key>NSAppleMusicUsageDescription</key>
<string>your own string</string>

Related

CNContactViewControllerDelegate not called when contact property selected/edited on iOS

The delegate for CNContactviewController is not called when properties get edited or selected.
When editing a new contact, the contactViewController(_ viewController: CNContactViewController, shouldPerformDefaultActionFor property: CNContactProperty) function is supposed to be called, but it's not.
How do you get notified when the user edits/selects a contact property?
Steps to reproduce:
Copy the view controller below.
Edit/select a contact
property.
Expected behavior:
"yo" is printed every time you edit/select a property.
Actual behavior:
Nothing.
import Foundation
import Contacts
import ContactsUI
class ContactViewController: UIViewController, CNContactViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
createContact()
}
func createContact() {
let contactController = CNContactViewController(forNewContact: nil)
contactController.delegate = self
contactController.allowsEditing = true
contactController.allowsActions = true
contactController.displayedPropertyKeys = [CNContactPostalAddressesKey, CNContactPhoneNumbersKey, CNContactGivenNameKey]
contactController.view.layoutIfNeeded()
present(contactController, animated:true)
}
// =============================================================================================================
// MARK: CNContactViewControllerDelegate Functions
// =============================================================================================================
func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?) {
viewController.dismiss(animated: true, completion: nil)
print("hi")
}
func contactViewController(_ viewController: CNContactViewController, shouldPerformDefaultActionFor property: CNContactProperty) -> Bool {
print("yo")
return true
}
// =============================================================================================================
// MARK: UIViewController Functions
// =============================================================================================================
override var prefersStatusBarHidden: Bool {
return true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
There are three initializers for making a CNContactViewController:
Existing contact: init(for:)
New contact: init(forNewContact:)
Unknown contact: init(forUnknownContact:)
The first and third forms call the delegate method contactViewController(_:shouldPerformDefaultActionFor:). The second form does not. That's the one you are using.
With the second flavor, the only event you get is contactViewController(_:didCompleteWith:), and at that point the new contact has already been saved into the database.
When editing a new contact, the contactViewController(_ viewController: CNContactViewController, shouldPerformDefaultActionFor property: CNContactProperty) function is supposed to be called
No, it isn't. That's just an idea you made up.
Expected behavior: "yo" is printed every time you edit/select a property.
Then stop expecting that.
How do you get notified when the user edits/selects a contact property?
You don't.
When you use a framework like Cocoa, you don't get to make up any expectations you like. Your expectations need to be based on what the framework actually does. You might wish that CNContactViewController and its delegate messages worked as you describe, and that might make a very good enhancement request to Apple. But it is not how it works in fact, so expecting it to do so won't do you any good.

Sinch is not supporting video call in swift

here is my code. I covert this code from objective c to swift from the sinch test` Giving the Objective-C part might be interesting to help but it's not supporting video call. when i accept the call audio is working fine. but video is not sending to the other device. please help me out if any one has the sample code for swift then send or try to fix it with this code.. thanks
// MARK: - Load
override func viewDidLoad() {
super.viewDidLoad()
if call?.direction == SINCallDirection.incoming {
self.callStateLabel.text = ""
self.showButtons(EButtonsBar.kButtonsAnswerDecline)
//audioController().startPlayingSoundFile(path(forSound: "incoming.wav"), loop: true)
} else {
self.callStateLabel.text = "calling..."
self.showButtons(EButtonsBar.kButtonsHangup)
}
if (call?.details.isVideoOffered)! {
localVideoView.addSubview(videoController().localView())
localVideoFullscreenGestureRecognizer.require(toFail: switchCameraGestureRecognizer)
videoController().localView().addGestureRecognizer(localVideoFullscreenGestureRecognizer)
videoController().remoteView().addGestureRecognizer(remoteVideoFullscreenGestureRecognizer)
}
}
#IBAction func accept(sender: AnyObject) {
call?.answer()
}
#IBAction func decline(sender: AnyObject) {
call?.hangup()
dismiss(animated: true, completion: nil)
}
#IBAction func hangup(sender: AnyObject) {
call?.hangup()
dismiss(animated: true, completion: nil)
}
func audioController() -> SINAudioController{
return Global.client.audioController()
}
func videoController() -> SINVideoController {
return Global.client.videoController()
}
Add 2 Views in your view controller. One is for local video view and another one is for remote video video. Set it outlets to view controller. I have a working audio call example and i just add this things to my call view controller.
func videoController() -> SINVideoController {
return appDeletgate.client.videoController()
}
In viewdidload check for if video is offered by call.
if call.details.isVideoOffered {
localVideoView.addSubview(videoController().localView())
//localVideoFullscreenGestureRecognizer.require(toFail: switchCameraGestureRecognizer)
//videoController().localView().addGestureRecognizer(localVideoFullscreenGestureRecognizer)
//videoController().remoteView().addGestureRecognizer(remoteVideoFullscreenGestureRecognizer)
}
Add this method to add remote video in view.
func callDidAddVideoTrack(_ call: SINCall?) {
remoteVideoView.addSubview(videoController().remoteView())
}
Also make sure you add this 2 keys into info.plist
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) need to access your camera for video call.</string>
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) uses the Microphone for calling</string>
And this is finally how i call it.
let call: SINCall? = self.callClient().callUserVideo(withId: recipientName) //self.callClient().callUser(withId: recipientName)
let callVC = mainStoryBoard.instantiateViewController(withIdentifier: "CallVC") as! CallVC
callVC.call = call
self.navigationController?.pushViewController(callVC, animated: true)

XCode8 Swift3 - Problems with open contact list and retrieve data by click

Currently I'm developing my first iOS App and I'm a little slow and rude about the code (it's so weird and different from java) and, if this was the only problem, with the new update, Xcode is making my code insane. I think I solved most of the issues but...
Before, on one of the screens, the app opened a the address book and let the user click on one; when the clicked was done, the contact list close and data from that contact was retrieved to the controller. Now, if the user click on a contact, more info is displayed but any information come out of the console log.
I try everything I find on net and I'm not sure why is not working.
Before, I use Addressbook (or something like that) but I already tried with CNContact.
This is the Button code
#IBAction func addNewContactOnClick(_ sender: AnyObject) {
let peoplePicker = CNContactPickerViewController()
peoplePicker.delegate = self
self.present(peoplePicker, animated: true, completion: nil)
}
CNContactPickerDelegate methods
func contactPicker(picker: CNContactPickerViewController, didSelectContacts contacts: [CNContact]){
contacts.forEach { contact in
for number in contact.phoneNumbers {
let phoneNumber = number.value as! CNPhoneNumber
print("number is = \(phoneNumber)")
}
}
}
func contactPickerDidCancel(picker: CNContactPickerViewController) {
print("Cancel Contact Picker")
}
Methods of CNContactPickerDelegate is changed in Swift 3 like below.
func contactPicker(_ picker: CNContactPickerViewController, didSelect contacts: [CNContact]) {
//your code
}
func contactPickerDidCancel(_ picker: CNContactPickerViewController) {
//your code
}
For other methods of CNContactPickerDelegate check Apple Documentation.

Picking a song and play from Music app library - Swift 2.0

I just took a basic Swift 2.0 course. I am trying to make an app to select a song from iOS's Music app library and play it. I came across this link which shows how to make media item picker.
import UIKit
import MediaPlayer
class ViewController: UIViewController {
#IBOutlet weak var pickSong: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let mediaPicker = MPMediaPickerController(mediaTypes: .Music)
// mediaPicker.delegate = self
// mediaPicker.prompt = "Select song (Icloud songs must be downloaded to use)"
mediaPicker.allowsPickingMultipleItems = false
mediaPicker.showsCloudItems = false
presentViewController(mediaPicker, animated: true, completion: {})
}
mediaPicker.delegate = self line shows
Cannot assign value of type 'ViewController' to type
'MPMediaPickerControllerDelegate?'
error message. When I blocked it, the app works and allow me to browse songs perfectly.
Question 1: I would like to know what is the use of this line?
Question 2: How to play a song that I picked using this code?
I searched here and other websites for how to play songs. I found people are using
player.play() to play music. I tried that and failed.
ViewController needs to conform to the 'MPMediaPickerControllerDelegate':
//Let other classes know ViewController is a MPMediaPickerControllerDelegate
class ViewController: UIViewController, MPMediaPickerControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let mediaPicker = MPMediaPickerController(mediaTypes: .Music)
mediaPicker.delegate = self
presentViewController(mediaPicker, animated: true, completion: {})
}
Add these methods to conform to MPMediaPickerControllerDelegate:
func mediaPicker(mediaPicker: MPMediaPickerController, didPickMediaItems mediaItemCollection: MPMediaItemCollection) {
//User selected a/an item(s).
for mpMediaItem in mediaItemCollection.items {
print("Add \(mpMediaItem) to a playlist, prep the player, etc.")
}
}
func mediaPickerDidCancel(mediaPicker: MPMediaPickerController) {
print("User selected Cancel tell me what to do")
}
The purpose of
'mediaPicker.delegate = self'
is to setup ViewController to respond to the functions added above. If you don't set the delegate the mediaPicker will still present, but your ViewController won't know the user made an action.
Whenever you set a delegate, make sure the class conforms to the delegate methods. If you don't know the methods, search through Apple's Developer docs for that delegate (ie search for 'MPMediaPickerControllerDelegate') and you'll see all the delegate methods you can add.

While am I getting an error while setting up GKMatchmakerViewControllerDelegate in Swift?

I would like like to set up the matchmaking viewController of my game. To do so, I add the GKMatchmakerViewControllerDelegate delegate to my main UIViewController called Home, so that it looks like:
class Home: UIViewController, GKGameCenterControllerDelegate, GKMatchmakerViewControllerDelegate {
To load up the matchmaking interface I am using this code:
func openMatchmaker() {
var gcViewController: GKMatchmakerViewController = GKMatchmakerViewController(rootViewController: self)
gcViewController.matchmakerDelegate = self
gcViewController.hosted = false
gcViewController.matchRequest.minPlayers = 2
gcViewController.matchRequest.maxPlayers = 2
gcViewController.matchRequest.defaultNumberOfPlayers = 2
self.showViewController(gcViewController, sender: self)
self.navigationController?.pushViewController(gcViewController, animated: true)
}
Though, I receive the following error next class Home: ... to when I try to run the code. The error message says:
Type 'Home' does not conform to protocol `GKMatchmakerViewControllerDelegate`.
Why is that happening?
Most of the time when you get that error is because you have not implemented the required functions of the particular protocol. You can see them by command clicking on that protocol. Add the following methods:
func matchmakerViewController(viewController: GKMatchmakerViewController!,
didFailWithError error: NSError!) {
}
func matchmakerViewController(viewController: GKMatchmakerViewController!,
didFindHostedPlayers players: [AnyObject]!) {
}
func matchmakerViewControllerWasCancelled(viewController: GKMatchmakerViewController!) {
}
func matchmakerViewController(viewController: GKMatchmakerViewController!,
hostedPlayerDidAccept player: GKPlayer!) {
}
The second function in the approved answer was updated in latest SDK:
func matchmakerViewController(viewController: GKMatchmakerViewController, didFindHostedPlayers players: [GKPlayer]) {
...
}

Resources