Can not convert url to html using kanna in swift - swift

using Kanna to parse html from url.tried swfitsoup but same problem.
func getContentFromHtml(urlString : String) -> String{
let url = URL(string: urlString)!
var result = ""
do {
let doc = try HTML(url: url, encoding: .utf8)
for description in doc.xpath("//meta[#property=\"og:description\"]") {
if let contentDescription = description["content"] {
result = contentDescription
}
}
} catch let error {
print(error.localizedDescription)
}
return result
}
I'm getting 34 urls from google rss(https://news.google.com/rss?hl=ko&gl=KR&ceid=KR:ko) through loop and pass to this method.
but with some urls , it doesn't convert url to html with error code
for example, https://news.google.com/__i/rss/rd/articles/CBMiMWh0dHBzOi8vd3d3Lnl0bi5jby5rci9fbG4vMDEwM18yMDIwMDMyNTIxNTk0Mzg0NzXSAUNodHRwczovL20ueXRuLmNvLmtyL25ld3Nfdmlldy5hbXAucGhwP3BhcmFtPTAxMDNfMjAyMDAzMjUyMTU5NDM4NDc1?oc=5
this url from rss is getting error.
The operation couldn’t be completed. (Kanna.ParseError error 1.)
or EncodingMismatch
but these urls are fine to access.
How can I fix it?

Related

Get top of remote file in Swift

There is a line in multiple files via the Internet. I want to avoid download the entire file. Each file may be long or short. The required line is usually about line 15 - always different, but always within the first 500 bytes.
Is there a way I can get just the top part of a remote file?
I can then use a regex pattern to find the required line.
Although I know how to download a file in a temp. location and copy it to a proper location, I think that process is too much and wasteful.
This is an example:
class func load(url: URL, to localUrl: URL, completion: #escaping () -> ()) {
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = try! URLRequest(url: url, method: .get)
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
// Success
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Success: \(statusCode)")
}
do {
try FileManager.default.copyItem(at: tempLocalUrl, to: localUrl)
completion()
} catch (let writeError) {
print("error writing file \(localUrl) : \(writeError)")
}
} else {
print("Failure: %#", error?.localizedDescription);
}
}
task.resume()
}
PS. It would also be helpful if you could include a method to find a line beginning with, say "abc=xyz", where I want "xyz".
To only download partial content, you need a server that supports sending ranges. To test this, make a HEAD request and check if the server responds with an Accept-Range: bytes header. If so, you can request partial content by adding a header like Range: bytes=0-499 to your GET requests to only receive the initial 500 bytes.

File couldn’t be opened because you don’t have permission to view it error

I have Googled and poked around Stack Overflow and can't seem to find a solution for this. I have:
let fileURL = URL( string: "file:///Users/me/file.txt" )
var rawDataString: String
var errorString: String?
do {
rawDataString = try String( contentsOf: fileURL!, encoding: String.Encoding.utf8 )
} catch let error as NSError {
errorString = error.description
print( errorString! )
return
}
and it's erroring out with
Error Domain=NSCocoaErrorDomain Code=257 "The file “file.txt” couldn’t
be opened because you don’t have permission to view it."
Permissions are read for all users:
$ ls -al file.txt
-rw-r--r--# 1 me staff 348306 Dec 13 2016 file.txt
Any ideas would be most welcome.
Anyone coming across this thread, #LeoDabus pointed me to where to turn off sandbox, which worked:
He also cleaned up my code a bit:
let fileURL = URL( fileURLWithPath: "/Users/me/file.txt" )
var rawDataString: String
var errorString: String?
do {
rawDataString = try String( contentsOf: fileURL, encoding: .utf8 )
} catch let error as NSError {
errorString = error.description
rawDataString = ""
return
}
(For iOS)
Sadly #Dribbler´s answer didn't work for me because I didn't have App Sandbox enabled and it still didn't work. In my case I used the UIDocumentPickerViewController and I was unable to access the file.
Adding url.startAccessingSecurityScopedResource() before working with the file resolved the issue for me.
Here is an example of the didPickDocumentsAt delegate function from a UIDocumentPickerViewController:
guard let url = urls.first else {
return
}
guard url.startAccessingSecurityScopedResource() else { // Notice this line right here
return
}
do {
let data = try Data(contentsOf: url)
} catch let error {
print(error.localizedDescription)
}
After adding that line it worked for me.
I actually was not able to get the preferred answers above to work for me in swift playground.
Another solution is just to create a command line app in Xcode. Then paste the above and it should work fine.

Upload Image to Amazon S3 Using Swift3

After looking around at different threads such as these (Swift - AWS S3 Upload Image from Photo Library and download it), and (Upload image AWS S3 bucket in swift), I got pretty close to getting an image upload to work but can't figure out what I'm doing wrong?
I get the following error below in my console.
Error: Error Domain=com.amazonaws.AWSS3TransferUtilityErrorDomain Code=1 "(null)" UserInfo={Server=AmazonS3, Transfer-Encoding=Identity, Connection=close, Content-Type=application/xml, Date=Tue, 13 Dec 2016 05:58:32 GMT, x-amz-request-id=2A76DF0FE33476C5, x-amz-id-2=QWZgOETbWQfddlqKmm0w3Z9HFGM2x1DWnrFjukiajTsIXfbSt9W0orTkoZeNXH/bI1xfc3mxI4Q=, x-amz-bucket-region=us-west-1}
My code is below:
let myIdentityPoolId = "us-west-2:dca2beb4-etcetcetc...."
let credentialsProvider:AWSCognitoCredentialsProvider = AWSCognitoCredentialsProvider(regionType: AWSRegionType.usWest2, identityPoolId: myIdentityPoolId)
let configuration = AWSServiceConfiguration(region: AWSRegionType.usWest2, credentialsProvider: credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
I then call to upload my image with a function I made below
func uploadImage(filename:String){
print("AWS Upload Image Attempt...")
//defining bucket and upload file name
let S3BucketName: String = "distribution-tech-mobile"
let filepath = "\(AppDelegate.appDelegate.applicationDocumentsDirectory())/\(filename)"
let imageURL = URL(fileURLWithPath: filepath)
let S3UploadKeyName = filename //TODO: Change this later
let uploadRequest = AWSS3TransferManagerUploadRequest()
uploadRequest?.bucket = S3BucketName
uploadRequest?.key = filename
uploadRequest?.contentType = "image/jpeg"
uploadRequest?.body = imageURL
uploadRequest?.serverSideEncryption = AWSS3ServerSideEncryption.awsKms
uploadRequest?.uploadProgress = { (bytesSent, totalBytesSent, totalBytesExpectedToSend) -> Void in
DispatchQueue.main.async(execute: {
self.amountUploaded = totalBytesSent // To show the updating data status in label.
self.fileSize = totalBytesExpectedToSend
print("\(totalBytesSent)/\(totalBytesExpectedToSend)")
})
}
self.uploadCompletionHandler = { (task, error) -> Void in
DispatchQueue.main.async(execute: {
if ((error) != nil){
print("Failed with error")
print("Error: \(error!)");
}
else{
print("Sucess")
}
})
}
let transferUtility = AWSS3TransferUtility.default()
let expression = AWSS3TransferUtilityUploadExpression()
transferUtility.uploadFile(imageURL, bucket: S3BucketName, key: S3UploadKeyName, contentType: "image/jpeg", expression: expression, completionHander: uploadCompletionHandler).continue({ (task) -> AnyObject! in
if let error = task.error {
print("Error: \(error.localizedDescription)")
}
if let exception = task.exception {
print("Exception: \(exception.description)")
}
if let _ = task.result {
print("Upload Starting!")
}
return nil;
})
}
I get the console message "Upload Starting" and then a message "Failed with error" (which comes from my completion handler), followed by the error I assume from Amazon.
Any thoughts on what I'm doing wrong?
Okay I found the answer, but I have a different problem now that I'll post in another question regarding showing upload progress.
The answer was my bucket was created in the incorrect region. I created my credentials in Oregon, which is Us-West-2, and I created the bucket in Northern California by accident the first time. This apparently created the error.

xcode error 'consecutive statements on a line must be separated by' when creating endpoint URL for REST API datatask

I am a beginner, trying to code a POST datarequest to post a vote to the 'rating' field of a Drupalnode (so that users can rate movies). I have followed online guides, carefully copying the syntax, but in Xcode am receiving this error for for this line:
let movieEndpoint: String = https://www.examplesitename.com/film1
The red error message is "consecutive statements on a line must be separated by a ';'
The error highlights the ':' after https, and suggests "fix it" with an ';' but changing it to https;www.examplesitename.com/film1 then brings up another red error 'expected expression' (and doesn't seem correct as it is a URL)
For context, below is my code, (which I hope will work to post my data request but haven't been able to check yet)
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config)
let movieEndpoint: String = https://www.sitename.com/film1
guard let movieURL = NSURL(string: movieEndpoint) else {
print("Error: cannot create URL")
return
}
let movieUrlRequest = NSMutableURLRequest(URL: movieURL)
movieUrlRequest.HTTPMethod = "POST"
let task = session.dataTaskWithRequest(movieUrlRequest, completionHandler:{ _, _, _ in })
let newRating = ["rating": 50, "userId": 1,]
let jsonRating: NSData
do {
jsonRating = try NSJSONSerialization.dataWithJSONObject(newRating, options: [])
movieUrlRequest.HTTPBody = jsonRating
} catch {
print("Error: cannot create JSON from todo")
return
}
movieUrlRequest.HTTPBody = jsonRating
task.resume()
}
Thank you for any help you can give me.
The proper way to declare a String in Swift is to add " " around the string.
Fix your code like this:
let movieEndpoint: String = "https://www.sitename.com/film1"

Is it ok to use tid-kijyun Swift-HTML-Parser to parse a real world html file from webpage

So the thing is, I am new to programming, and Swift in particular. I completed some courses and now want to build something really simple: an app that gets the news from website and pushes it to a Table View.
Right now I am stuck on error:
Optional(Error Domain=HTMLParserdomain Code=1 "The operation couldn’t be completed. (HTMLParserdomain error 1.)")
The code I wrote is really simple. It's the example from the tid-kijyun repo plus some code to get content of the HTML (func perFormConnectionToGrabUrlContent)
func perFormConnectionToGrabUrlContent(# url: String) -> NSString {
let url = NSURL(string: url)
let request = NSURLRequest(URL: url!)
var htmlContentTemp: NSString = ""
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {
(response, data, error) in
htmlContentTemp = NSString(data: data, encoding: NSUTF8StringEncoding)!
println(htmlContentTemp)
}
return htmlContentTemp
}
let html = perFormConnectionToGrabUrlContent(url: "http://www.google.com")
println(html)
var err: NSError?
var parser = HTMLParser(html: html, error: &err)
if err != nil {
println(err)
exit(1)
}
var bodyNode = parser.body
if let inputNodes = bodyNode?.findChildTags("a") {
for node in inputNodes {
println(node.contents)
}
}
if let inputNodes = bodyNode?.findChildTags("a") {
for node in inputNodes {
println(node.contents)
println(node.getAttributeNamed("href"))
}
}
So the question still is, should I change something in code and it should really work like a charm, or should I better go access the database of website I am trying to reach and run some datebase queries or something like that instead?