my http request does not work - swift

I have update my xcode and i have problem with https requests. I need to get html code. But some sites is get good, some is nil. i think problem with plist file, but presvious version in log say about Clear Http and unsecured loads. The current xcode - no. Why i have catch with some web sites? Yandex.ru - i can get html content. Google.com - i cannot(go to catch block). This problem with different sites. Part of them i can get, second part i cant. Thank you for resolve my problem.
There is my code:
if let url = URL(string: "http://google.com") {
do {
let contents = try String(contentsOf: url)
print(contents)
} catch {
print("catch")
}
} else {
print("else")
}
my plist file in attach:

Rather than catching with a print("catch") you should try to print the error that's being thrown
catch (let e) {
print(e)
}
The error I am seeing is Error Domain=NSCocoaErrorDomain Code=261 "The file couldn’t be opened using text encoding Unicode (UTF-8)." UserInfo={NSURL=http://google.com, NSStringEncoding=4}
I tried
let contents = try String(contentsOf: url, encoding: String.Encoding.utf8)
but that doesn't seem to solve the problem. Depends on how Google is serving up their pages
MOST IMPORTANTLY
This is a blocking call - you should use an async method for loading remote URLs. This method is really for loading local assets from your Bundle. Please look at NSURLRequest https://developer.apple.com/documentation/foundation/nsurlrequest and NSURLSession https://developer.apple.com/documentation/foundation/nsurlsession

I find problem - all this web sites is not UTF-8. I try different and it is work:
var serverString = NSString(data: data!, encoding: String.Encoding.windowsCP1251.rawValue)

Related

How Can I get Image data from specific URI in Swift?

I have a function called downloadImage. I'm trying to get image data and set an imageView. But it prints "no data".
image link: http://commons.wikimedia.org/wiki/Special:FilePath/Flag%20of%20Montenegro.svg
Here is my code:
func downloadImage() {
let uri = "Special:FilePath/Flag%20of%20Montenegro.svg"
let baseURL = URL(string: "http://commons.wikimedia.org/wiki/")!
let imageURL = URL(string: uri, relativeTo: baseURL)!
if let data = try? Data(contentsOf: imageURL){
if let image = UIImage(data: data){
DispatchQueue.main.async {
self.flagImageView.image = image
}
}
else{
print("image cannot be taken")
}
}else{
print("no data")
}
}
Here is console output:
2022-09-03 21:21:56.426579+0300 CountryBook[5242:197393] nil host used in call to
allowsSpecificHTTPSCertificateForHost
2022-09-03 21:21:56.426913+0300 CountryBook[5242:197393] nil host used in call to allowsAnyHTTPSCertificateForHost:
2022-09-03 21:21:56.427580+0300 CountryBook[5242:197905] NSURLConnection finished with error - code -1002
no data
Note:
I Allowed Arbitrary Loads from info.plist by marking it as YES.
Assuming you did allow the usage of http corectly. There is more going on here:
The link you provided redirects to https://upload.wikimedia.org/wikipedia/commons/6/64/Flag_of_Montenegro.svg. Data(contentsOf: is not for this purpose. It is best suited for loading data from a bundle file url and not complex redirecting or cookies or header..... . Use a proper URLSesssion.
Even if you get your data it will not work this way. UIImage doesn´t support SVG format. See this SO question for more info
Remarks:
Just use https. It´s de facto standard. And your link to wikipedia would support it. Falling back to http should be the last resort while developing and never in production.
this is actually due to the fact that apple no longer allows http urls by default, it wants them to be https
When using a https url, you also shouldn't need to allowArbitraryLoads
From what I suspect though, wikipedia is https, so I think you can just change your url to have https like so:
https://commons.wikimedia.org/wiki/Special:FilePath/Flag%20of%20Montenegro.svg

Can you perform file I/O in a REPL on Repl.it when using Swift?

There's an online site here called Repl.it that gives you an in-browser REPL environment for a ton of languages. It's great to prove out code that you post here on SO. (I think you can even include it here actually but I wasn't successful in embedding mine.)
Anyway, when using Swift, I'm wondering if it's possible to perform file read/write persistence up there. I haven't found any articles that say yes, but I have found some that show them talking about how much storage you have, and it is supposed to be the full Swift runtime with all features, so I'm not sure.
This code fails however, saying it can't be performed.
import Foundation
let file = "file.txt" //this is the file. we will write to and read from it
let text = "some text" //just a text
if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
let fileURL = dir.appendingPathComponent(file)
//writing
do {
try text.write(to: fileURL, atomically: false, encoding: .utf8)
}
catch {
print(error)
}
//reading
do {
let text2 = try String(contentsOf: fileURL, encoding: .utf8)
print("Read back in '\(text2)'")
}
catch {/* error handling here */}
}
else{
print("Couldn't get document directory")
}
You can open it here... Swift File Persistence REPL
I admit I'm 90% sure this isn't the right place for this, but since Repl.it does let you play with and execute Swift and this is a question about what Swift is needed to accomplish this, I figured I'd try!

How do I read a file from the filesystem in a Swift command line app?

I'm just starting learning Swift and to teach myself I'm making a simple command line app. It will eventually connect to an online data source but initially I want to load data from a file. I've seen various guides on reading the contents of a file in Swift but none of them seem to work for me. Here is my app so far:
import Foundation
// Set the file path
let path = "/Users⁩/username/workspace⁩/⁨Swift⁩/sis⁩/sis/data.json⁩"
do {
// Get the contents
let contents = try String(contentsOfFile: path, encoding: .utf8)
print(contents)
}
catch let error as NSError {
print("Ooops! Something went wrong: \(error)")
}
Running it outputs:
Ooops! Something went wrong: Error Domain=NSCocoaErrorDomain Code=260 "The file “data.json⁩” couldn’t be opened because there is no such file." UserInfo={NSFilePath=/Users⁩/username/workspace⁩/⁨Swift⁩/sis⁩/sis/data.json⁩, NSUnderlyingError=0x100e19a50 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
However on the terminal:
$ ls -l /Users/username/workspace/Swift/sis/sis/data.json
-rwxrwxrwx# 1 username staff 165563 16 Jan 17:14 /Users/username/workspace/Swift/sis/sis/data.json
(yeah I relaxed the permissions somewhat just in case that was the problem)
The only slightly anomalous thing I noticed (aside from the inaccurate assertion that the file doesn't exist) was that when I copy and past the path from the XCode output into iTerm2 it puts spaces between each path component:
(pasted as an image as copying it and pasting it back into this form seems to hide the spaces - this is probably irrelevant anyway)
Any help figuring this out would be really appreciated!
I copied your code, downloaded a sample json file to my desktop, and renamed it to example_ 1.json (I included a space inside the file name).
import Foundation
// Set the file path
let path = "/Users⁩/username/Desktop/example_ 1.json⁩"
do {
// Get the contents
let contents = try String(contentsOfFile: path, encoding: .utf8)
print(contents)
}
catch let error as NSError {
print("Ooops! Something went wrong: \(error)")
}
It successfully printed the file. It also worked when I defined contents as a NSString.
let contents = try NSString(contentsOfFile: path,
encoding: String.Encoding.ascii.rawValue)
I am using Swift 4.2.1
you can not read if your command line app is sandboxed. what you can do is to add this file in your project and set path of file by looking the full path of file in identity inspector.
let path = "/Users/snx/EmailReplacer/EmailReplacer/shared_domains_staging.json"
do {
let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves)
if let jsonResult = jsonResult as? Dictionary<String, AnyObject> {
print(jsonResult)
}
} catch {
print(error)
}

Swift 4 / Xcode 9.3 / iOS - Catch The file "x" couldn’t be opened because there is no such file with String(contentsOf: url)

Swift 4 / Xcode 9.3 / iOS
I'm using String(contentsOf: url) and in some cases I get an error because the file referenced by the URL doesn't exist. I want to handle that specific error case.
I know I can check to see if the file exists first, but I want to handle the error case instead.
Right now I am doing:
let data = try String(contentsOf: url)
Up until now I've been catching all errors, with something like:
do {
let data = try String(contentsOf: url)
//<other code here>
} catch let error {
fatalError("bad error: \(error)")
}
When the specific file I'm trying to pull from (from the give URL) doesn't exist, I get an error like this:
bad error: Error Domain=NSCocoaErrorDomain Code=260 "The file “whatever.json” couldn’t be opened because there is no such file." UserInfo={NSFilePath=/Users/myname/Library/Developer/CoreSimulator/Devices/6529F22A-5234-49D7-9BB3-B9C71474CC53/data/Containers/Data/Application/005C1F55-07E8-4CF4-86FD-2F00B1144FD4/Documents/whatever.json, NSUnderlyingError=0x608000058180 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
How do I catch this error separately so I can handle it separately from other errors? I've tried CocoaError.fileNoSuchFile and several in the POSIX error domain.
Thanks!
Okay, so I've been fighting this for awhile, and as soon as I posted, I ended up solving it.
the answer is CocoaError.fileReadNoSuchFile. I kept trying CocoaError.fileNoSuchFile.
So here's the answer:
do {
let data = try String(contentsOf: url)
//<other code here>
} catch CocoaError.fileReadNoSuchFile {
print("CAUGHT IT!")
} catch let error {
fatalError("bad error: \(error)")
}
Thanks!

Parsing large XML files fails--ERROR:Error Domain=DDXMLErrorDomain Code=1 "(null)"

I'm parsing XML using KissXML. I can successfully parse small XML but have problem with large XML. Here's my code
let url = URL(fileURLWithPath: xmlPath!)
let xmlData = try! Data(contentsOf: url)
do {
let doc = try DDXMLDocument(data: xmlData, options:0)// This is not working if xml is large (6MB)
let project = try! doc.nodes(forXPath: "//Project") as! [DDXMLElement]
for user in project {
let ProjectName = user.attribute(forName: "ProjectName")!.stringValue
let userTime = user.attribute(forName: "UseTime")!.stringValue
print("ProjectName:\(ProjectName!),userTime:\(userTime!)")
}
}
catch {
print("\(error)") //Get some idea from this error
}
When parsing 12k XML was successful, but 6M XML was a failure. When parsing large XML(6M),doc equal to nil.
I try to use NSXMLParser,the same problem arises,small file can work, big files can't.ERROR:NSXMLParserErrorDomain error 4.
You should not ignore the error using try?, always enclose it in do - catch construct. Use below code and see what error are you getting and then try to resolve it. Don't shoot in the dark, get some idea from the error and if nothing works post your error message in the question.
do {
let doc = try DDXMLDocument(data: xmlData, options:0)
// Your next line of code
}
catch {
print("\(error)") //Get some idea from this error
}