Help us understand the problem. What is going on with this article?


More than 1 year has passed since last update.

普段はUnity C#でスマホゲームを作っていますが、今回やりたい事がその範囲で対応できなかったので、iOS/AndroidでPluginを書くことにしました。




using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;

 * 音楽再生.
 * */
public class MusicPlay : MonoBehaviour {

    #if UNITY_IOS
    [DllImport ("__Internal")]
    public static extern void MusicOpen_();

    public musicPicker musicPicker_;

    void Awake(){
        #if UNITY_ANDROID
        musicPicker_ = gameObject.AddComponent<musicPicker> ();

    public void openMedia(){
    #elif UNITY_IOS
        Debug.Log(">>> MusicOpen_ call");


UnityC# -> Obj-C -> Swift の呼び出しが可能と解り、以下のようなコードになりました。MusicOpen_以外はSwiftです。
# import <Foundation/Foundation.h>
# import <XXX-Swift.h> // XCodeが作成するヘッダ。扱いについては別の良記事が参考に
extern "C" {
    void MusicOpen_()
        NSLog(@">>> MusicOpen_");
        [ViewBind initTableView] ;
import Foundation
import MediaPlayer
import UIKit

open class ViewBind : NSObject, audiosend{

    static var audioPlayer: AVAudioPlayer! = nil
    static var view: ViewController! = nil

    static func initTableView(){
        let unityViewController = UnityGetGLViewController()

        view = ViewController()

        let nav = UINavigationController(rootViewController: view)

        // 画面遷移.
        //unityViewController?.present(nav, animated: true, completion: (() -> Void) { SendMe() })
        unityViewController?.present(nav, animated: true, completion: nil)
    func SendMe( ){

    func audioSendMethod( audio: AVAudioPlayer)
        ViewBind.audioPlayer = audio

import UIKit
import MediaPlayer
import AVFoundation

//ViewBind と ViewControllerを audiosend を介して、delegate呼び出し可能にします
@objc protocol audiosend {
    func audioSendMethod( audio: AVAudioPlayer)

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var myTableView: UITableView!
    var albums: [SongInfo] = []
    var songQuery: SongQuery = SongQuery()
    var audio: AVAudioPlayer! = nil

    weak var delegate: audiosend?

    override func viewDidLoad() {


        albums = songQuery.get()
        if(albums.count == 0){
            self.dismiss(animated: true, completion: nil)

        let barHeight: CGFloat = UIApplication.shared.statusBarFrame.size.height
        let displayWidth: CGFloat = self.view.frame.width
        let displayHeight: CGFloat = self.view.frame.height

        myTableView = UITableView(frame: CGRect(x: 0, y: barHeight, width: displayWidth, height: displayHeight))

        self.title = "Songs"

        self.myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
        self.myTableView.delegate = self
        self.myTableView.dataSource = self
        print(">>> viewDidLoad")
    override func didReceiveMemoryWarning() {
     // sectionの数を返す
    func numberOfSectionsInTableView( in tableView: UITableView! ) -> Int {
        return albums.count

    // 各sectionのitem数を返す
    func tableView( _ tableView: UITableView, numberOfRowsInSection section: Int ) -> Int  {
        return albums.count

    func tableView( _ tableView: UITableView, cellForRowAt indexPath : IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath as IndexPath)
        cell.textLabel!.text = albums[indexPath.row].songTitle
        return cell;

    // sectionのタイトル
    func tableView( _ tableView: UITableView, titleForHeaderInSection section: Int ) -> String? {
        return ""

    // 選択した音楽を再生
    func tableView( _ tableView: UITableView, didSelectRowAt indexPath:IndexPath ) {

        // soundIdからMediaItemを取得
        let songId: NSNumber = albums[indexPath.row].songId
        let item: MPMediaItem = songQuery.getItem( songId )

        let url: URL = item.value( forProperty: MPMediaItemPropertyAssetURL ) as! URL

        self.title = albums[indexPath.row].songTitle

            audio = try AVAudioPlayer(contentsOf: url)
            audio.numberOfLoops = -1
        self.delegate?.audioSendMethod(audio: audio)
        self.dismiss(animated: true, completion: nil)
import Foundation
import MediaPlayer

// 曲情報
struct SongInfo {

    var albumTitle: String
    var artistName: String
    var songTitle:  String
    var songId   :  NSNumber

// アルバム情報
struct AlbumInfo {
    var albumTitle: String
    var songs: [SongInfo]

class SongQuery {

    // iPhoneに入ってる曲を全部返す
    func get() -> [SongInfo] {

        // アルバム情報から曲を取り出す
        let songsQuery: MPMediaQuery = MPMediaQuery.songs()
        songsQuery.addFilterPredicate(MPMediaPropertyPredicate(value: false, forProperty: MPMediaItemPropertyIsCloudItem))
        if #available(iOS 9.2, *) {
            songsQuery.addFilterPredicate(MPMediaPropertyPredicate(value: false, forProperty: MPMediaItemPropertyHasProtectedAsset))
        } else {
            // Fallback on earlier versions

        if(songsQuery.collections?.isEmpty == true){
            print(">>> songsQuery.collections empty")
            print(">>> songsQuery.collections \(String(describing: songsQuery.collections?.count))")
        let songsItems: [MPMediaItem] = songsQuery.items! as [MPMediaItem]
        var songs: [SongInfo] = []
        for song in songsItems {
                let songInfo: SongInfo = SongInfo(
                    albumTitle: song.value( forProperty: MPMediaItemPropertyAlbumTitle ) as! String,
                    artistName: song.value( forProperty: MPMediaItemPropertyArtist ) as! String,
                    songTitle:  song.value( forProperty: MPMediaItemPropertyTitle ) as! String,
                    songId:     song.value( forProperty: MPMediaItemPropertyPersistentID ) as! NSNumber
                print(">>> \(songInfo.songTitle)")
                songs.append( songInfo )
        return songs

    // songIdからMediaItemを取り出す
    func getItem( _ songId: NSNumber ) -> MPMediaItem {

        let property: MPMediaPropertyPredicate = MPMediaPropertyPredicate( value: songId, forProperty: MPMediaItemPropertyPersistentID )

        let query: MPMediaQuery = MPMediaQuery()
        query.addFilterPredicate( property )

        var items: [MPMediaItem] = query.items!

        return items[items.count - 1]





Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away