Why does swift not recognise my resource? - ios

Swift is telling me my file does not exist and unfortunately I cannot find the directory myself. Am I using the URL for resource method incorrectly or do I just need to find a way of removing the optional brackets? When I refer to this object directly it works but I need to find a way of creating a path my team mates can use as well.
override func setUp()
{
super.setUp()
let bundleURL = NSBundle.mainBundle().URLForResource("meetingexample", withExtension: "ics")
let eventsFile = NSURL(fileURLWithPath: ("\(bundleURL)"))
//let eventsFile = NSURL(fileURLWithPath: docFolderURL.URLByAppendingPathComponent("/meetingexample.ics"))
content = try! String(contentsOfURL: eventsFile, encoding: NSUTF8StringEncoding)
}
Print of bundleURL:
Optional(file:/Users/GB112922/Library/Developer/CoreSimulator/Devices/EF6A2594-6B31-4E38-B46D-2F3AAAF25210/data/Containers/Bundle/Application/35E04003-072F-476E-957E-98C70B792539/CallIn.app/meetingexample.ics)`

You have two issues:
"\(bundleURL)" is wrapping the value of the NSURL in the Optional(...) extra text.
URLForResource is already giving you an NSURL. There's no need to create another NSURL from it.
Just use bundleURL. There is no need for the eventsFile variable.
override func setUp()
{
super.setUp()
let bundleURL = NSBundle.mainBundle().URLForResource("meetingexample", withExtension: "ics")
content = try! String(contentsOfURL: bundleURL, encoding: NSUTF8StringEncoding)
}

Related

Swift: Ask user to input the text file name after each stop button is clicked

I created a stop button that can collect data, which will be saved to the defined path after clicking the stop button. However, if I want to continue collecting after clicking the stop button, the data will be added to the original text file. (This makes senses as I only know how to define one path)
My question is: Would it be possible to ask the user and input a new file name and save as a new text file after each stop so that the data is not added to the original file?
Below is what I have for one defined path and stacking up the data:
#IBAction func stopbuttonTapped(_ btn: UIButton) {
do {
let username:String = user_name.text!
fpsTimer.invalidate() //turn off the timer
let capdata = captureData.map{$0.verticesFormatted}.joined(separator:"") //convert capture data to string
let dir: URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last! as URL
let url = dir.appendingPathComponent("testing.txt") //name the file
try capdata.appendLineToURL(fileURL: url as URL)
let result = try String(contentsOf: url as URL, encoding: String.Encoding.utf8)
}
catch {
print("Could not write to file")
}
}
And the extension I use for string and data:
extension String {
func appendLineToURL(fileURL: URL) throws {
try (self).appendToURL(fileURL: fileURL)
}
func appendToURL(fileURL: URL) throws {
let data = self.data(using: String.Encoding.utf8)!
try data.append(fileURL: fileURL)
}
func trim() -> String
{
return self.trimmingCharacters(in: CharacterSet.whitespaces)
}
}
extension Data {
func append(fileURL: URL) throws {
if let fileHandle = FileHandle(forWritingAtPath: fileURL.path) {
defer {
fileHandle.closeFile()
}
fileHandle.seekToEndOfFile()
fileHandle.write(self)
}
else {
try write(to: fileURL, options: .atomic)
}
}
}
Do I need to set a default file name (maybe texting.txt) and then popped up a user input for saving the text file? (That's where I am not too sure how to integrate to what I already have). I thank you so much for your time and suggestions in advance.
You could generate unique names.
For example:
let url = dir.appendingPathComponent("testing-\(Date.timeIntervalSinceReferenceDate).txt")
or
let url = dir.appendingPathComponent("testing-\(UUID().uuidString).txt")

Text file to array in swift

I'm trying to create a dictionary app on IOS. I have a text file (words_alpha.txt) in my Bundle, and I want to read all the words/lines, and place them into an arrray. String = ["word1", "word2", "word3"]. Here is my current code I got from bit.ly/39IC642
let path = Bundle.main.path(forResource: "words_alpha", ofType: "txt") // file path for file "words_alpha.txt"
let string = try String(contentsOfFile: path!, encoding: String.Encoding.utf8)
I am getting this error: Cannot use instance member 'path' within property initializer; property initializers run before 'self' is available
I am fairly new to using Swift and coding in general, please be detailed with your answers. Thank you!
If you are writing an iOS app, you can move such initialization into viewDidLoad():
var wordArray: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
//...
let url = Bundle.main.url(forResource: "words_alpha", withExtension: "txt")! // file URL for file "words_alpha.txt"
do {
let string = try String(contentsOf: url, encoding: .utf8)
wordArray = string.components(separatedBy: CharacterSet.newlines)
} catch {
print(error)
}
}
If your words_alpha.txt does contain multiple words per line, you may need some other way.

Swift 3 webView local HTML

I need to load local HTML, CSS and JS into an iOS app to make my boss happy. I'm using Xcode 8.3.1 and Swift 3. I have created a new project with a WebView placed in my Main.storyboard
Other StackOverflow resources helped me get this far:
#IBOutlet weak var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let urlpath = Bundle.main.path(forResource: "index", ofType: "html");
let requesturl = URL(string: urlpath!)
let request = URLRequest(url: requesturl!)
webView.mainFrame.load(request)
}
I get this error:
Value of type 'UIWebView' has no member 'mainFrame'
When I remove mainFrame it says I'm missing a mimeType. Can anyone help? I'm obviously a noob to Swift.
mainFrame is from the class WebView which is only for macOS.
Since you are using UIWebView, you need to use webView.loadRequest.
You also have a problem with your URL. Either use URL(fileURLWithPath:) to create the URL from the path string or, better yet, use Bundle.main.url(forResource:withExtension:) and get the URL directly.
You might also want to use WKWebView instead of UIWebView. It has a lot more features and it may be more useful for your needs.
Swift 5
let path = Bundle.main.path(forResource: "temp", ofType: "html")!
//reading
var text = try! String.init(contentsOfFile: path, encoding: String.Encoding.utf8)
text = text.replacingOccurrences(of: "${contents}", with: contents)
// load string
let bundleURL = URL.init(string: path)
webView.loadHTMLString(text, baseURL: bundleURL)
done!

How to put an image in a Realm database?

I'm writing an iOS application using Swift 2 and I would like to save profile picture of an account locally in a Realm database. I can't find any documentation or people talking about that.
Is it possible? And how?
May be is it bad to do that?
You can store images as NSData. Given you have the URL of an image, which you want to store locally, here is a code snippet how that can be achieved.
class MyImageBlob {
var data: NSData?
}
// Working Example
let url = NSURL(string: "http://images.apple.com/v/home/cb/images/home_evergreen_hero_iphone_medium.jpg")!
if let imgData = NSData(contentsOfURL: url) {
var myblob = MyImageBlob()
myblob.data = imgData
let realm = try! Realm()
try! realm.write {
realm.add(myblob)
}
}
May be it is a bad idea to do that?
The rule is simple:
If the images are small in size, the number of images is small and they are rarely changed, you can stick with storing them in the database.
If there is a bunch images, you are better off writing them directly to the file system and just storing the path of the image in the database.
Here is how that can be done:
class MyImageStorage{
var imagePath: NSString?
}
let url = NSURL(string: "http://images.apple.com/v/home/cb/images/home_evergreen_hero_iphone_medium.jpg")!
if let imgData = NSData(contentsOfURL: url) {
// Storing image in documents folder (Swift 2.0+)
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
let writePath = documentsPath?.stringByAppendingPathComponent("myimage.jpg")
imgData.writeToFile(writePath, atomically: true)
var mystorage = MyImageStorage()
mystorage.imagePath = writePath
let realm = try! Realm()
try! realm.write {
realm.add(mystorage)
}
}
Please note: Both code samples are not reliable methods for downloading images since there are many pitfalls. In real world apps / in production, I'd suggest to use a library intended for this purpose like AFNetworking or AlamofireImage.
ProblemSlover's solution updated for Swift 2.2:
Important Note: the only change is that now stringByAppendingPathComponent has been removed as of Swift 2.1, so you will get an error saying:
stringByAppendingPathComponent is unavailable: use URLByAppendingPathComponent on NSURL instead.
Please keep in mind that while it may be annoying, it has been removed for a reason and you should follow apple's recommendation to use NSURL instead. BUT if you wish to proceed with this solution, the fix for Swift 2.1+ is to explicitly cast documentsPath to NSString:
class MyImageStorage{
var imagePath: NSString?
}
let url = NSURL(string: "http://images.apple.com/v/home/cb/images/home_evergreen_hero_iphone_medium.jpg")!
if let imgData = NSData(contentsOfURL: url) {
//Explicitly cast to NSString
let documentsPath = (NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString)
let writePath = documentsPath.stringByAppendingPathComponent("myimage.jpg")
imgData.writeToFile(writePath, atomically: true)
var mystorage = MyImageStorage()
mystorage.imagePath = writePath
let realm = try! Realm()
try! realm.write {
realm.add(mystorage)
}
}

Where to place a .txt file and read from it in a IOS project

i want to put a .txt file in my Xcode Swift Iphone project.
First, i simply drag&dropped it from my desktop to the Supporting Files Folder from the project. Isn't there a Folder like on Android "assets", so i can place my files anywhere i want?
The file in my example is called README.txt which has a bunch of lines and paragraphs.
Simple enough, now I want to print the content of the README.txt file to a view.
How do i do the read function and what path should I insert, if my file is in the project /SupportFiles/README.txt?
Thanks alot!
if let path = Bundle.main.path(forResource: "README", ofType: "txt") {
do {
textView.text = try String(contentsOfFile: path, encoding: .utf8)
} catch let error {
// Handle error here
}
}
Just drop the file anywhere into the project browser and make sure it is added to the right target.
Just to expand on the answer, you can also place them in a folder and use:
+ pathForResource:ofType:inDirectory:.
I would recommend to use NSFileManager and drop your file anywhere in your project :
if let path = NSBundle.mainBundle().pathForResource(name, ofType: "txt"){
let fm = NSFileManager()
let exists = fm.fileExistsAtPath(path)
if(exists){
let c = fm.contentsAtPath(path)
let cString = NSString(data: c!, encoding: NSUTF8StringEncoding)
ret = cString as! String
}
}
Swift 4 (thanks to #Pierre-Yves Guillemet for original)
As long as the file is in your project (and has a .txt) this will work (in this example, I assume "MyFile.txt" is a file that is in my project):
static func LoadFileAsString() -> ()
{
if let path = Bundle.main.path(forResource: "MyFile", ofType: "txt")
{
let fm = FileManager()
let exists = fm.fileExists(atPath: path)
if(exists){
let content = fm.contents(atPath: path)
let contentAsString = String(data: content!, encoding: String.Encoding.utf8)
}
}
}
In Swift 3
guard let path = Bundle.main.path(forResource: "README", ofType: "txt") else {
return
}
textView.text = try? String(contentsOfFile: path, encoding: String.Encoding.utf8)
If you define path's type and put ! end of the line, you won't get any warning.
let path:String = NSBundle.mainBundle().pathForResource("README", ofType: "txt")!
textView.text = String(contentsOfFile: path,
encoding: NSUTF8StringEncoding,
error: nil)
There's a Assets.xcassets for images and files.
And here's how to read it from assets.
if let data = NSDataAsset(name: "AssetName")?.data {
textView.text = String(data: data, encoding: .utf8)
}

Resources