How to stream music on app using the API Jukebox with swift? - ios

I want to stream music to my app using this library I found online called Jukebox. Heres a link to their page: https://github.com/teodorpatras/Jukebox
import UIKit
import Jukebox
class ViewController: UIViewController {
var jukebox = Jukebox()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.jukebox = Jukebox(delegate: self, items: [ JukeboxItem(URL: NSURL(string: "http://mixtapemonkey.com/mixtapes/zip/491/Chance%20The%20Rapper%20-%2010Day%20Official%20Final/03%20Nostalgia.mp3")!)
])
}
I get an error where it says 'Jukebox(delegate: self' stating that I cannot convert the value of type 'ViewController' to expected argument type 'JukeboxDelegate?'
#IBAction func Play(sender: UIButton) {
self.jukebox.play()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
where am i going wrong? Thanks

My guess is that you've failed to inherit from the Jukebox delegate in your class declaration. Should be something like this:
class ViewController: UIViewController, JukeboxDelegate {
var jukebox = Jukebox()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.jukebox = Jukebox(delegate: self, items: [ JukeboxItem(URL: NSURL(string: "http://mixtapemonkey.com/mixtapes/zip/491/Chance%20The%20Rapper%20-%2010Day%20Official%20Final/03%20Nostalgia.mp3")!)
])
}
}
Since these delegate methods aren't optional, you'll also have to make your ViewController conform to the delegate by including the delegate methods, listed below.
Defines the five possible states that Jukebox can be in.
public protocol JukeboxDelegate : class {
func jukeboxStateDidChange(jukebox : Jukebox)
func jukeboxPlaybackProgressDidChange(jukebox : Jukebox)
func jukeboxDidLoadItem(jukebox : Jukebox, item : JukeboxItem)
}
The library seems to be written in Swift, and unless you put some extra effort into it, delegate methods can't be optional which is why you're getting the error about your VC not conforming to the methods. You at least have to have the method signatures in your class, and it's up to you whether you want anything to happen when they're called.

i don't know Jukebox - but something doesn't work with your ViewController. Your ViewController is a class not a class instance. You need to first create an instance of this controller.
Maybe something in this direction helps .. but im not good in Swift, too.
let VCJukeBox = UIViewController()?
VCJukeBox.jukebox = Jukebox(delegate: self, items: [ JukeboxItem(URL: NSURL(string: "yoururl.mp3")!)
])
Im not good in swift, too - but maybe this helps somehow.

Related

Instance member 'webView' cannot be used on type 'MyWebView(UIview)'

I am creating one SDK to get the url from user and load. So ai m creating my own class with WKWebview. But i am getting few issues about Instance member 'webView' cannot be used on type 'MyWebView(UIview)'
Code :
import Foundation
import WebKit
public class MyWebView: UIView, WKNavigationDelegate {
// initialize the view
var webView: WKWebView!
// load the view
private func loadView() {
webView = WKWebView()
webView.navigationDelegate = self
}
// get the url and load the page
public static func loadUrl(Url: String) {
MyWebView.webView.load(URLRequest(url: URL(string: Url)!))
}
}
In my loadUrl, what ever user sending i need to use that url and load the url. Same in my view controller will look like :
import UIKit
class ViewController: UIViewController {
var webView: MyWebView!
override func loadView() {
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
Any help would be great.
Your loadUrl function should not be static, since it needs access to an instance property, webView. Making the function non-static solves the issue.
Also a couple of minor improvements: don't force unwrap the URL init, since with an incorrect input that will crash. Use optional binding to safely unwrap it instead. I'd also suggest renaming the input argument label on loadUrl, since there's no point in having to right out loadUrl(Url:) every time you call the func, loadUrl( reads more naturally.
public func loadUrl(_ urlString: String) {
guard let url = URL(string: urlString) else { return }
webView.load(URLRequest(url: url))
}

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.

Swift: How do unit test UIWebView loading?

My app has a basic webview controller to perform some operations. This view in the storyboard is not much besides a wrapper around a UIWebView. The controller itself has various public functions that can be called to load pages in the webview, like so:
class WebViewController: UIViewController, UIWebViewDelegate {
// MARK: Properties
#IBOutlet var webView: UIWebView!
// MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
webView.delegate = self
loadHomePage()
}
// MARK: Public
public func loadHomePage() {
navigateWebView(to: HOME_PAGE)
}
public func loadSettingsPage() {
navigateWebView(to: SETTINGS_PAGE)
}
public func loadSignOutPage() {
navigateWebView(to: SIGN_OUT_PAGE)
}
// MARK: Private
private func navigateWebView(to url: String) {
let request = URLRequest(url: URL(string: url)!)
webView.loadRequest(request)
}
I'm trying to write unit tests that verify that the proper URL is sent to the loadRequest function of the webview. Note that I don't actually care about loading the URL; this is just a unit test, so all I really want to test is that loadSettingsPage sends a URLRequest with the SETTINGS_PAGE URL to the webview to load, for example.
I tried something like this, with no success:
_ = webViewController.view // Calls viewDidLoad()
XCTAssertEqual(webViewController.webView.request?.url?.absoluteString, HOME_PAGE)
The value of the first part of the assertEqual was nil.
I assume I need to mock out the webView somehow but I'm not sure how to go about that. Any suggestions?
As a follow-up, I'd also like to be able to test when things like webView.reload() and webview.goBack() are called, so any pointers there would be appreciated as well. Thanks!

Custom Address Search iOS mapkit

Learning swift 2/ Xcode 7 and creating a app iOS 9 where I can enter a custom address. I have mapkit working and can search regular address. I have my current location working. Instead of entering an address: "Number,Street, city, zip code", I want the user to enter: PR33.1 for example, and that would show the user that location. I have the long and lats for the custom address's, I've read many things on geocoding and annotations but nothing that would let me accomplish what I need. Can this be done? jSon file maybe.. I'm really new at this...
thanks
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var textField: UITextField!
let arbitraryString: [String:String] =
["161 RL2": "23908709138882,-106.7433588579297",
"40.9 RL112":"32.393144,-106.727762"]
#IBAction func enterButtonTapped(sender: AnyObject) {
if let textField = arbitraryString["161 RL2"] {
print(" \(textField).")
} else {
print("That is not in the dictionary.")
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Swift class conforming to Objective-C protocol

In Objective-C I have the the following protocol:
#protocol GCKDeviceScannerListener <NSObject>
#optional
- (void)deviceDidComeOnline:(GCKDevice *)device;
- (void)deviceDidGoOffline:(GCKDevice *)device;
- (void)deviceDidChange:(GCKDevice *)device;
#end
When trying to conform to this protocol in Swift Xcode 6.1 autocompletes it like this:
class ViewController: UIViewController, GCKDeviceScannerListener {
override func viewDidLoad() {
super.viewDidLoad()
var deviceScanner = GCKDeviceScanner();
deviceScanner.addListener(self);
deviceScanner.startScan();
println("scanning");
}
func deviceDidComeOnline(device: GCKDevice!) {
println("deviceDidComeOnline()");
}
func deviceDidGoOffline(device: GCKDevice!) {
println("deviceDidGoOffline()");
}
func deviceDidChange(device: GCKDevice!) {
println("deviceDidChange()");
}
}
The code compiles and seemingly runs ok on the simulator. However, none of the listener functions are ever triggered. Everything works 100% of the time when running the demo project from Google written in Objective-C only. Because of the last part I'm assuming that the there aren't any problems with the network or hardware or anything like that.
It could be that I have missed something important from https://developers.google.com/cast/docs/ios_sender, but I would like to know if the Swift code itself is correct according to the protocol. As the protocol only has optional functions it's hard to know if it's right.
I have no experience with this library, but I think you should keep the reference to GCKDeviceScanner.
Try:
class ViewController: UIViewController, GCKDeviceScannerListener {
var deviceScanner = GCKDeviceScanner()
override func viewDidLoad() {
super.viewDidLoad()
deviceScanner.addListener(self)
deviceScanner.startScan()
println("scanning")
}
Apple's documentation on Protocols is long and complex.
It's easiest to think of optional protocol methods like Optional closures, and you can use it with optional chaining.
#objc class Something {
var delegate: GCKDeviceScannerListener?
func someCallback() {
delegate?.deviceDidComeOnline?(device)
}
}

Resources