Playing video with youtube-ios-player-helper - ios

I have been trying to have my app stream videos from YouTube, learning from the AppCoda tutorial and so far I have successfully connected to its JSON database, and downloaded the info from the video I need. However, when I feed it to the YouTube player library, it gives me an error:
Error Domain=NSCocoaErrorDomain Code=258 "The file name is invalid."
I checked against the AppCoda example and it seems that my app is working very similarly. I am even printing the videoID before calling the function to make sure that it is correct.
func getVideos(pID: String, completion: (result:String)->()) {
Alamofire.request(.GET, videosURL).validate().responseJSON { response in
switch response.result {
case .Success:
if let value = response.result.value {
let json = JSON(value)
var videoID: [String] = []
for var i=0; i<json["items"].count; i++ {
let newID = json["items"][i]["snippet"]["resourceId"]["videoId"].stringValue
videoID.append(newID)
defaults.setObject(videoID, forKey: "\(pID)videoID")
}
completion(result: "done")
}
case .Failure(let error):
print(error)
completion(result: "done")
}
}
}
print(videoID) //Returns: 7zAxweqsSfo
playerView.loadWithVideoId(videoID)
}

The latest version of the YouTube iOS Helper Library does not include the YTPlayerView-iframe-player.html file needed by the player. See this GitHub issue for related discussion.
The solution is to manually add the YTPlayerView-iframe-player.html to your project, or point Cocoapods at the master branch:
pod 'youtube-ios-player-helper', :git=>'https://github.com/youtube/youtube-ios-player-helper', :commit=>'head'

Related

WorldPay AccessCheckoutSDK IOS "generateSession" gives "Identity is invalid" error

I am trying to integrate WorldPay's "AccessCheckoutSDK" in my IOS Application using Swift by following
https://developer.worldpay.com/docs/access-worldpay/checkout/ios/card-only
while generating session it give me "Identity is invalid" error .
Here is the code i tried
func initializedSDK() -> AccessCheckoutClient? {
let accessCheckoutClient = try?
AccessCheckoutClientBuilder().accessBaseUrl(WORLDPAY_BASE_URL)
.merchantId(WORLDPAY_MERCHANT_ID)
.build()
return accessCheckoutClient
}
func createCardDetails(CardNumber : String , CardExpiry : String , CardCVC : String) -> CardDetails? {
let cardDetails = try? CardDetailsBuilder().pan(CardNumber)
.expiryDate(CardExpiry)
.cvc(CardCVC)
.build()
return cardDetails
}
func CreateSession(CardNumber : String , CardExpiry : String , CardCVC : String) {
guard let accessCheckoutClient = initializedSDK() else {
// not going here so accessCheckoutClient is initialized
return
}
guard let cardDetails = createCardDetails(CardNumber: CardNumber, CardExpiry: CardExpiry, CardCVC: CardCVC) else {
// Not going here , so card details are valid
return
}
try? accessCheckoutClient.generateSessions(cardDetails: cardDetails, sessionTypes: [SessionType.card , .cvc ]) { result in
DispatchQueue.main.async {
switch result {
case .success(let sessions):
// The session is returned in a Dictionary[SessionType:String]
//not going here
let cardSession = sessions[SessionType.card]
let cvcSession = sessions[SessionType.cvc]
case .failure(let error):
// The error returned is of type AccessCheckoutError
print("error \(error)")
// It is going here and prints this error below
}
}
}
}
I am getting this error
AccessCheckoutError(errorName: "bodyDoesNotMatchSchema", message: "bodyDoesNotMatchSchema : The json body provided does not match the expected schema", validationErrors: [AccessCheckoutSDK.AccessCheckoutError.AccessCheckoutValidationError(errorName: "fieldHasInvalidValue", message: "Identity is invalid", jsonPath: "$.identity")])
WORLDPAY_BASE_URL = "https://try.access.worldpay.com/"
Note : I am using worldPay in testMode and didn't activated live mode yet and made sure that WORLDPAY_MERCHANT_ID is correct.
After all the research on worldPay , i decide to mail to worldPay support, After a brief chat with them and after they went through my worldPay account, this was their final reply :
"Your account status, "basic", "free tier" does not permit you to have access to this endpoint."
I decided to answer my own question so that if anyone have the same problem while integrating WorldPay with test Account, This would help them. I still think WorldPay developer can handle this scenario better by returning this exact string straightforward in the api response instead of throwing a 500 server error.
I welcome other answers and information on this post as well. If you have something informative about worldPay integration to IOS, please feel free to comment or answer this question.

How to get current user's playlist from Spotify

I am trying to implement Spotify integration with current user's playlist to display it in my tableview. I have integrated with login and access token everything works fine. I have gone through stack overflow link:- How to get the list of songs using Spotify in Swift3 iOS? but didn't work for me.
Then to get print for canonicalUsername as below, its showing nil value
SPTUser.requestCurrentUser(withAccessToken:(SPTAuth.defaultInstance().session.accessToken)!) { (error, data) in
guard let user = data as? SPTUser else { print("Couldn't cast as SPTUser"); return }
let userId = user.canonicalUsername
})
I have even tried this link Spotify iOS SDK Swift display all (!) playlists (20+) due to beginner may be it also didn't work for me. Is there any way to get Spotify's current user-id? How could I show the current user's playlist in my table view?
Just go through online tutorial in youtube :- https://www.youtube.com/watch?v=KLsP7oThgHU&t=1s for latest version in 2019.
Download full source code with Spotify Integration + search options + default Spotify url and fetch current user's playlist and play in our native iOS App
Source:- https://github.com/azeemohd786/Spotify-Demo
Based on your question the solution to get print canonicalUsername or current user's id try as below,
SPTUser.requestCurrentUser(withAccessToken: session.accessToken) { (error, data) in
guard let user = data as? SPTUser else { print("Couldn't cast as SPTUser"); return }
let userID = user.canonicalUserName
print(userID!)
}
Then to get current user's playlist and play in ur device, first call the SPT Delegate in your view controller like and then function call,
class PlayVC: UIViewController, SPTAudioStreamingDelegate, SPTAudioStreamingPlaybackDelegate {
func audioStreamingDidLogin(_ audioStreaming: SPTAudioStreamingController) {
let playListRequest = try! SPTPlaylistList.createRequestForGettingPlaylists(forUser: session.canonicalUsername, withAccessToken: session.accessToken)
Alamofire.request(playListRequest)
.response { response in
let list = try! SPTPlaylistList(from: response.data, with: response.response)
for playList in list.items {
if let playlist = playList as? SPTPartialPlaylist {
print( playlist.name! ) // playlist name
print( playlist.uri!) // playlist uri
// self.tableView.reloadData()// if u want to display playlist name and other stuffs like so..
SPTAudioStreamingController.sharedInstance().playSpotifyURI("\(playlist.uri!)", startingWith: 0, startingWithPosition: 10) { error in
if error != nil {
print("*** failed to play: \(error)")
return
}
}
}}}
}
}

RxMoya request using mvvm model always crashes in observer.onError(error)

Following is my code for signing up
self.signedUp = signUpButtonTap.withLatestFrom(userAndPassword).flatMapLatest{
input -> Observable<Response> in
return Observable.create { observer in
let userData = Creator()
userData?.username = input.0
userData?.password = input.1
provider.request(.signIn(userData!)).filter(statusCode: 200).subscribe{ event -> Void in
switch event {
case .next(let response):
observer.onNext(response)
case .error(let error):
let moyaError: MoyaError? = error as? MoyaError
let response: Response? = moyaError?.response
let statusCode: Int? = response?.statusCode
observer.onError(error)
default:
break
}
}
return Disposables.create()
}
}
Following is the binding in the View
self.viewModel.signedUp.bind{response in
self.displayPopUpForSuccessfulLogin()
}
When there is a successful response its works fine.
But when the request times out or I get any other status code than 200, I get the following error "fatalError(lastMessage)" and the app crashes.
When I replace observer.onError(error) with observer.onNext(response) in the case .error it works for response codes other than 200 , but crashes again when the request times out.
I have gone through this link Handling Network error in combination with binding to tableView (Moya, RxSwift, RxCocoa)
Can anyone help me out with what is wrong. I am completely new to RxSwift . Any help will be appreciated. Thank you
If provider.request(.signIn(userData!)) // ... returns results on some background thread, results would be bound to UI elements from a background thread which could cause non-deterministic crashes.
It should be
provider.request(.signIn(userData!))
.observeOn(MainScheduler.instance) // ...
according to RxSwift github tips: Drive

How to edit the file in swiftyDropbox?

In my project, I uploaded all my text files to the Dropbox. Here, I need to directly edit the uploaded file in Dropbox using swift. Is it possible to edit files in Dropbox?
(OR) Is it possible to overwrite the same fileName in Dropbox?
Solution moved from #SathishKumarGurunathan's question post.
I found the answer and I will share here.
_ = client?.files.upload(path: path, mode: .overwrite, autorename: false, clientModified: nil, mute: false, input: Description).response { response, error in
if let response = response {
print("The upload response is \(response)")
} else if let error = error {
print("The upload error is \(error)")
}
}
.progress { progressData in
print("The progress Data is \(progressData)")
}

Unable save large file to S3 using Parse server

I tried to save to S3 bucket using Parse Server, and it can be saved correctly when the file is small, such as 864.2KB. However, when the file is large, say 5MB, it complaints with a message saying: "The data couldn’t be read because it isn’t in the correct format"
I'm using the following code to save the the video file to the S3
func saveVideo(withVideoURL url: URL){
let post = PFObject(className: "Post")
post["caption"] = "Out of the game for 6 months, but back with vengeance. Meet your 2017 AO Men's champion"
do{
let data = try Data(contentsOf: url)
print(data)
post["media"] = PFFile(data: data)
post.saveInBackground { (success, error) in
if success{
print("video saved")
}else{
print("failed")
if error != nil{
print(error!.localizedDescription)
}else{
print("erorr is nil")
}
}
}
}catch let error as NSError{
print("can't read")
print(error.localizedDescription)
}
}
Besides, even when the small video file is indeed being saved to the S3, it contains an extension .bin instead of, for example .mp4. I wonder what's happening here
The url end up looking something like this
https://s3-us-west-1.amazonaws.com/sampleApp/19d5bce20f8b55te1b1b8f370212533e5_file.bin
You need to stipulate the content type. You can do so like this:
post["media"] = PFFile(data: data, contentType: "video/mp4")
The below settings in your parse-server index file will help you:
var bodyParser = require('body-parser');
app.use(bodyParser.json({limit: '20mb'}));
app.use(bodyParser.urlencoded({limit: '20mb', extended: true}));
If you are using elastic beanstalk, you have to have a file named files.config inside the folder .ebextensions, with the below content.
files:
/etc/nginx/conf.d/proxy.conf:
content: |
client_max_body_size 20M;
This fixed the issue for me.

Resources