Unable to get Model from Request<VIMVideo>(VimeoNetworking) - swift

I have integrated in a ios app VimeoNetworking , using the code from the git directly because i cannot integrate using cocoapods (not compatible use of use_frameworks! with other pods) for getting private link to some videos (i have a pro account).
I'm able to authenticate and request video info. When the request is returned and assigned to the class (VIMVideo) the object is not loaded correctly.
If i get the response returned returns correctly a dictionary of 30 items with the video info.
I have checked the same code from the VimeoNetworking example code and it's works in the other project (using same credentials, only different one use pod of Vimeo and the other not)
If i compare the two json responses, both have the same data but in a different order. I have the feeling that the problem is with the de-serialization used by AFNetworking (3.1.0)
Previous authentication
let authenticationController = AuthenticationController(client: VimeoClient.defaultClient, appConfiguration: AppConfiguration.defaultConfiguration, configureSessionManagerBlock: nil)
authenticationController.accessToken(token:tkn) { result in
switch result
{
case .success(let account):
print("authenticated successfully: \(account)")
break;
case .failure(let error):
print("failure authenticating: \(error)")
}
}
Video Request
let requestdir: Request<VIMVideo> = Request<VIMVideo>(path: "/videos/XXXXXXXX")
let _ = VimeoClient.defaultClient.request(requestdir) { [weak self] result in
switch result
{
case .success(let response):
//Here videodir have not value, but
var videodir: VIMVideo! = response.model
case .failure(let error):
let title = "Video Request Failed"
let message = "\(requestdir.path) could not be loaded: \(error.localizedDescription)"
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(action)
strongSelf.present(alert, animated: true, completion: nil)
}
}
Console capture (1)
Pod file from VIMEO EXAMPLE (Extract)
def shared_pods
pod 'AFNetworking', '3.1.0'
pod 'SwiftLint', '0.25.1'
pod 'VimeoNetworking', :path => '../VimeoNetworking'
end
Pod file from my project (Extract)
target 'LibroDig' do
pod 'RestKit', '~> 0.27.3'
pod 'JSONModel'
pod 'SDWebImage', '~>3.8'
pod 'AFNetworking', '3.1.0'
end
I expected the VIMVideo load correctly all the properties. I'm unable to find the difference between the 2 implementations.
Thanks in advance

If everything else is the same, you might be running into issues from opting out of using use_frameworks!.
For example, when I remove this from the Podfile used in the VimeoNetworking example project, I'll see this warning:
The Swift pod VimeoNetworking-iOS depends upon AFNetworking-iOS, which do not define modules. To opt into those targets generating module maps (which is necessary to import them from Swift when building as static libraries), you may set use_modular_headers! globally in your Podfile, or specify :modular_headers => true for particular dependencies.
This article explains the need for use_modular_headers! and mentions interoperability with Objective-C. VimeoNetworking relies on model classes defined in Objective-C, and I wonder if mapping to those models is being affected.

Related

Why is my Plaid Link Integration not opening the Link UI

I am attempting to integrate with Plaid, their documentation is a link confusing to follow and their support team informed me they are working on it. I also reached out to them to see if they could help me with my current integration but they informed me they are not able to look at my code because every integration is different.
Per the Plaid documentation I added my ngrok url to the redirect uri section in the dashboard (This works with the Plaid Link demo app: https://github.com/plaid/plaid-link-ios).
Also I added allow arbitrary load to the info plist.
I was able to get their Plaid Link-demo app up and running but when I try to place this code in my project I get the following error:
Thread 12: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
// MARK: Start Plaid Link using a Link token
// For details please see https://plaid.com/docs/#create-link-token
func presentPlaidLinkUsingLinkToken() {
#warning("Replace <#GENERATED_LINK_TOKEN#> below with your link_token")
// In your production application replace the hardcoded linkToken below with code that fetches an link_token
// from your backend server which in turn retrieves it securely from Plaid, for details please refer to
// https://plaid.com/docs/#create-link-token
let linkToken = "TOKEN HERE"
// <!-- SMARTDOWN_PRESENT_LINKTOKEN -->
// With custom configuration using a link_token
var linkConfiguration = LinkTokenConfiguration(token: linkToken) { success in
print("public-token: \(success.publicToken) metadata: \(success.metadata)")
}
linkConfiguration.onExit = { exit in
if let error = exit.error {
print("exit with \(error)\n\(exit.metadata)")
} else {
print("exit with \(exit.metadata)")
}
}
let result = Plaid.create(linkConfiguration)
switch result {
case .failure(let error):
print("Unable to create Plaid handler due to: \(error)")
case .success(let handler):
// UI Update code here
handler.open(presentUsing: .viewController(self))
self.linkHandler = handler
}
// <!-- SMARTDOWN_PRESENT_LINKTOKEN -->
}
#IBAction func refreshButtonAction(_ sender: Any) {
// UI Update code here
self.presentPlaidLinkUsingLinkToken()
}
I tried to place the self.presentPlaidLinkUsingLinkToken() into the following snippet:
DispatchQueue.main.async {
self.presentPlaidLinkUsingLinkToken()
}
Also per the Plaid documentation I added the following method within my App delegate swift file:
// MARK: Continue Plaid Link for iOS to complete an OAuth authentication flow
// <!-- SMARTDOWN_OAUTH_SUPPORT -->
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb, let webpageURL = userActivity.webpageURL else {
return false
}
// Check that the userActivity.webpageURL is the oauthRedirectUri
// configured in the Plaid dashboard.
guard let linkOAuthHandler = window?.rootViewController as? LinkOAuthHandling,
let handler = linkOAuthHandler.linkHandler,
webpageURL.host == linkOAuthHandler.oauthRedirectUri?.host &&
webpageURL.path == linkOAuthHandler.oauthRedirectUri?.path
else {
return false
}
// Continue the Link flow
if let error = handler.continueFrom(redirectUri: webpageURL) {
print("Unable to continue from redirect due to: \(error)")
}
return true
}
// <!-- SMARTDOWN_OAUTH_SUPPORT -->
But the same error occurs. Any suggestions will be appreciated.
In case anyone is having issues with this, I was able to figure it out. It is something incorrect in their cocoapod. Once, I downloaded and dragged the LinkKit Framework everything worked as expected. Also Plaid does not use their own cocoapod in their demo project, they do the manual install. Maybe they are working on this issue.
It's hard to tell without seeing the code in your application calling presentPlaidUsingLinkToken(), but your application is crashing on Thread 12. UIKit is not multi-threaded, so if you are presenting a view controller on a background thread you can expect crashes.
I see you tried a DispatchQueue.main.async, however I suspect you may have another threading issue going on.
Just putting this out there since this is one of few results for this issue: My issue was that I wasn't retaining the Handler object. As a result, the Plaid UI would never appear and no events would fire, leaving me with an endless spinner. Simply maintaining the reference in the class did the trick (as shown in the sample project and mentioned in passing in the documentation).
Kona Farry's solution above works. From Plaid docs:
Create a Handler - A Handler is a one-time use object used to open a Link session. The Handler must be retained for the duration of the Plaid SDK flow.

Kentico Cloud Swift SDK not returning items

I'm testing out the Kentico Cloud Swift SDK to return some 'article' content types (I have created two of them and they are published).
I am using the Boilerplate code as described here:
The result I get is : [Kentico Cloud] Getting items action has succeeded. Received nil items.
My code:
let client = DeliveryClient.init(projectId: <project id>, previewApiKey: <preview key>, secureApiKey: <secure key>, enableDebugLogging: true)
func getArticles(){
// Note: Using "items" as custom query returns all content items,
// but to map them to a single model, a filter is needed.
let customQuery = "items?system.type=article"
// More about strongly-typed models https://github.com/Kentico/cloud-sdk-swift#using-strongly-typed-models
client.getItems(modelType: Article.self, customQuery: customQuery) { (isSuccess, itemsResponse, error) in
if isSuccess {
// We get here and itemsResponse != nil but items == nil
if let articles = itemsResponse?.items {
for article in articles {
}
}
} else {
if let error = error {
print(error)
}
}
}
}
I believe this error message would appear before ObjectMapper is triggered to convert the JSON into Article objects. I could be wrong though.
Anyone have any ideas?
UPDATE
Interestingly, if I request a single article object like so ...
client.getItem(modelType: Article.self, itemName: <codename>) { (isSuccess, itemResponse, error) in
if isSuccess {
if let article = itemResponse?.item {
// Use your item here
}
} else {
if let error = error {
print(error)
}
}
}
... then it works. I get the Article object. It's just asking for all of the articles that fails.
I'm going to investigate the issue later today, however, from your description, it might be caused by the Delivery API item readiness delay - the project was not fully synced with the delivery API yet. After the publishing/unpublishing item or creating/generating the project, there might be a small delay in processing messages by Delivery API which could cause unavailability of item. This delay might be variable - from my experience, it may vary from a couple of seconds to 2-3 minutes. Nevertheless, I'm going to check it just to be sure. I'll keep you updated.
Edit: I'm pretty sure the project was not synced and processed on the Delivery API at the time you were requested the items. The API returned 200, which caused isSuccess in the callback to be true, however, there might have been none or just a subset of items available - I've reproduced this behavior (screenshot below), although it's by design (the content/messages in Event Hub must be processed asynchronously).
I've also suggested the improvement for Kentico Cloud's documentation to mention/explain the possible delay caused by processing events queue messages from Event Hubs.
Just to be sure - could you try it again with your getArticles custom query?
Edit2: Back to your question about the ObjectMapper. This is not an error just a debug message, however, there shouldn't be probably nil but 0 (zero) in the debug message. This message came from:
private func sendGetItemsRequest<T>(url: String, completionHandler: #escaping (Bool, ItemsResponse<T>?, Error?) -> ()) where T: Mappable {
sessionManager.request(url, headers: self.headers).responseObject { (response: DataResponse<ItemsResponse<T>>) in
switch response.result {
case .success:
if let value = response.result.value {
let deliveryItems = value
if self.isDebugLoggingEnabled {
print("[Kentico Cloud] Getting items action has succeeded. Received \(String(describing: deliveryItems.items?.count)) items.")
}
completionHandler(true, deliveryItems, nil)
}
case .failure(let error):
if self.isDebugLoggingEnabled {
print("[Kentico Cloud] Getting items action has failed. Check requested URL: \(url)")
}
completionHandler(false, nil, error)
}
}
}
Ok. This is very weird. After checking the API by requesting an individual item (see the update in the post above), and getting a result (woot). It now seems the original code (unchanged) now works.
I'm wondering if it takes a while for the data to propagate and be available in the API?
Who knows. Weird.

Swift CSVImporter framework with remote URLs

Initial use and testing of the framework. The examples provided and most of the searches from across the internet are using "local" or downloaded CSV files to the device, with (path:).
I would like to pass various remote URLs but there are not many examples, using (url: URL).
So far, I am simply in viewDidLoad() following the same code as provided with the sample playground file, and trying to output to the console.
I have tried to run this in a simulator for the iPhone 8 device. Running Xcode 10.1.
From the documentation, there is an ".onFail" handler, which gets invoked on the sourceURL's I have provided, but I do not know what error objects exist to do any further troubleshooting.
let sourceURL = URL(string: "https://files.datapress.com/leeds/dataset/leeds-city-council-dataset-register/Dataset%20register.csv")
guard let sourceURL2 = URL(string: "https://minio.l3.ckan.io/ckan/ni/resources/2477b63a-b1c4-45cc-a5ee-8e33e5b20b5b/supplies-and-services-contracts---2014.2015-yr.csv?AWSAccessKeyId=aspjTDZu90BQVi&Expires=1546982840&Signature=dLDVWMu%2Fp4RiePIRhntCX6WFMpw%3D") else {
fatalError("URL string error")
}
let importer = CSVImporter<[String]>(url: sourceURL)
importer?.startImportingRecords { $0 }.onFail {
print("fail")
}.onFinish({ importedRecords in
print(importedRecords.count)
})

How to use Octokit in Swift3 ?

I use Octkit for the first time and I used cocoapods to install it, but it does not work as it was explained in the GitHub: https://github.com/nerdishbynature/octokit.swift
So I tried to implement code this way;
let token = GithubAPIManager.sharedInstance.OAuthToken
let config = TokenConfiguration(token)
Octokit(config).me() { response in
switch response {
case .Success(let user):
case .Failure(let error):
}
}
But when I add TokenConfiguration there is an error saying
use of unresolved identifier
And also for the Octkit(config) there is an error. I imported Octokit and Foundation. What is wrong?
Solution is quite simple (had the same issue): in the example the reference to the enum is incorrect, additionally println isn't available in Swift 3 anymore.
.success and .failure need to be lowercase. If you want to print like the example in the readme file use print instead of println.
let token = GithubAPIManager.sharedInstance.OAuthToken
let config = TokenConfiguration(token)
Octokit(config).me() { response in
switch response {
case .success(let user):
case .failure(let error):
}
}

How to share text of a label from iPhone app to facebook?

I have written a simple Xcode project in swift for my iPhone . I am trying to send the text of my label to facebook using facebook share option .
Below is my code
import UIKit
import Social
class ViewController: UIViewController {
#IBOutlet weak var musicDescription: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func faceBookShareButton(sender: UIButton) {
if SLComposeViewController.isAvailableForServiceType(SLServiceTypeFacebook) {
let fbShare:SLComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeFacebook)
let text = musicDescription.text
fbShare.setInitialText(text)
self.presentViewController(fbShare, animated: true, completion: nil)
} else {
let alert = UIAlertController(title: "Accounts", message: "Please login to a Facebook account to share.", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
}
But i am not able to see the text of the label in my facebook timeline. Someone guide me here . Why is the text not posting in facebook ?
Edit:Update
I downloaded FBSDK files and added them to my project . I imported FBSDKShareKit into my ViewController.h file.
Here is my code
#IBAction func faceBookShareButton(sender: UIButton) {
if UIApplication.sharedApplication().canOpenURL(NSURL(string: "fb:")!) {
var content: FBSDKShareLinkContent = FBSDKShareLinkContent()
var Subject: String = String(format: "FBSDKShareKit is an alternative to this issue")
content.contentTitle = "FBSDKShareKit"
content.contentDescription = Subject
var dialog: FBSDKShareDialog = FBSDKShareDialog()
dialog.fromViewController = self
dialog.shareContent = content
dialog.mode = FBSDKShareDialogModeWeb
dialog.show()
}
I am getting an error "Use of unresolved identifier FBSDKShareDialogModeWeb"
.
Anyone help please !
You have to check return value of setInitialText(_:) method.
That function can return false. Apple document describes following.
Return Value
Returns a Boolean value indicating whether the text was successfully set.
Using FBSDKShareKit is not an complete alternative but it helps to show your pre-filled content on the share dialog screen.
For basic check the following link cocoapods.Open your terminal install cocoapods
$ sudo gem install cocoapods
open your project directory,like this eg: cd/desktop/TestSwift,
Then to create pod file in your project after opening your project directory add the following line pod init this will create a podfile inside your project
Open the podfile in TextEdit from finder.to install FBSDK add pod 'FBSDKShareKit' the entire podfile will look like this
platform :ios, '8.0'
use_frameworks!
target 'TestSwift' do
pod 'FBSDKShareKit','~> 4.8.0'
pod 'FBSDKCoreKit','~> 4.8.0'
end
target 'TestSwiftTests' do
end
target 'TestSwiftUITests' do
end
Now in your terminal inside your project directory type pod install add hit enter this will install all the pod's added in your podfile.
Installing FBSDKShareKit (4.8.0)
NOTE: After installing pod in your project .xcworkspace file will be created. Instead of using .xcodeproj you have to use .xcworkspace for further process of your project
Since we are using swift we have to add Bridging Header to over project.it helps in adding Objective-C frame work in swift project.
How to create bridging header: Use Command ⌘ + N the under ios-source choose header file name it as *BridgingHeader.h** select location and then create it.
Then import your pod-file inside the bridging header file it should look like as follows
#ifndef BridgingHeader_h
#define BridgingHeader_h
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKShareKit/FBSDKShareKit.h>
#endif /* BridgingHeader_h */
Now we have successfully created bridging header to make sure your bridging header is added successfully open Targets then select your target open Build Settingtab in search bar type bridging.In search result under Objective-C BridgingHeader you should have your ProjectName/BridgingHeader.h
Now add the code in your button action as follows:
if UIApplication.sharedApplication().canOpenURL(NSURL(string: "fb:")!) {
let content : FBSDKShareLinkContent = FBSDKShareLinkContent()
content.contentURL = NSURL(string: "https://google.com")
content.contentTitle = "Test"
content.contentDescription = "FBSDKShareKit is an alternative to this issue"
content.imageURL = NSURL(string:"https://pixabay.com/static/uploads/photo/2015/10/01/21/39/background-image-967820_960_720.jpg")
let ShareKit: FBSDKShareDialog = FBSDKShareDialog()
ShareKit.fromViewController = self;
ShareKit.shareContent = content
ShareKit.mode = FBSDKShareDialogMode.FeedBrowser
ShareKit.show()
}
Use of unresolved identifier FBSDKShareDialogModeWeb to fix this replace dialog.mode as follows
ShareKit.mode = FBSDKShareDialogMode.FeedBrowser
I'am using .FeedBrowser,because is working fine for me.
FBShareDialogue:
FBTimeline:
Now we got everything in timeline.Title,Description,Image,SiteURL.