NSFileManager - Swift - File Browser - ios

I am new at ios development and I am trying to create an app in swift that will list all the files in the directory (all the files are PDF) and the user to be able to open them.
I have googling this for a the past two days and I am super confused. Can anyone suggest a tutorial or steps I would need to get this to work.
I have started with this in my ViewController.swift file:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
class func defaultManager()->NSFileManager{
}
}
I just don't know what to do next, very sad I know. I would appreciate any or all help.
Thanks,
J

let manager = NSFileManager.defaultManager()
var array = manager.contentsOfDirectoryAtPath(_ path: String,
error error: NSErrorPointer) -> [AnyObject]?
Swift 3.0 version
let manager = FileManager.default
let installed_files = try manager.contentsOfDirectory(atPath: "/Applications/")

Here is a more complete example and updated for Swift 2.
Add your files to a Folder (not a Group) in your project. Then use the following code to get a list of file names.
private func getListOfFileNames() -> Array<String> {
let docsPath = NSBundle.mainBundle().resourcePath! + "/DirectoryName"
let fileManager = NSFileManager.defaultManager()
let docsArray: Array<String>
do {
docsArray = try fileManager.contentsOfDirectoryAtPath(docsPath)
} catch {
print(error)
}
return docsArray
}

Maybe I am late to answer for you, but the answer may help others. I've found one library on github. This is a way to get access very easely to browse files. At here is example:
let fileBrowser = FileBrowser()
present(fileBrowser, animated: true, completion: nil)

Related

How to insert user entered data into a local html document

I'm very new to Swift and I'm struggling a bit with a simple task. I have made a simple app which will launch a local HTML file.
I now want to add a text box that appears, asking the user "Enter IP address". Then, that text will be inserted into the HTML file in 3 different places.
Does anyone have any ideas on this? Or know of a good site which might have some tutorials which relate to this idea? Here's my code so far:
import UIKit
import WebKit
class ViewController: UIViewController {
#IBOutlet weak var htmlload: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let htmlpath = Bundle.main.path(forResource: "index", ofType: "html")
let url = URL(fileURLWithPath: htmlpath!)
let request = URLRequest(url: url)
htmlload.load(request)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

How to implement Nuance Speechkit when using CocoaPods in Swift

Between the pod spec and what is currently on S.O. I had a tough time figuring out how to get speech-to-text working using SpeechKit + CocoaPod + Swift. Finally got it working so figured I'd help the next poor soul that comes looking for help! :)
First install the CocoaPod: https://cocoapods.org/pods/SpeechKit
Add #import <SpeechKit/SpeechKit.h> to your bridging header
Login to Nuance's dev portal and create an app: https://developer.nuance.com/
Clean up the demo code so that is is more organized. I just wanted as much of the code to be in one place as possible so you can see a fully working implementation.
Then create a UIViewController and add the following code with the correct credentials:
import UIKit
import SpeechKit
class SpeechKitDemo: UIViewController, SKTransactionDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//!!link this to a corresponding button on the UIViewController in I.B.
#IBAction func tappedButton(sender: AnyObject) {
// All fields are required.
// Your credentials can be found in your Nuance Developers portal, under "Manage My Apps".
let SKSAppKey = "[Get this from the nuance app info page]";
let SKSAppId = "[Get this from the nuance app info page]";
let SKSServerHost = "[Get this from the nuance app info page]";
let SKSServerPort = "[Get this from the nuance app info page]";
let SKSLanguage = "eng-USA";
let SKSServerUrl = "nmsps://\(SKSAppId)#\(SKSServerHost):\(SKSServerPort)"
let session = SKSession(URL: NSURL(string: SKSServerUrl), appToken: SKSAppKey)
//this starts a transaction that listens for voice input
let transaction = session.recognizeWithType(SKTransactionSpeechTypeDictation,
detection: .Short,
language: SKSLanguage,
delegate: self)
print(transaction)
}
//required delegate methods
func transactionDidBeginRecording(transaction: SKTransaction!) { }
func transactionDidFinishRecording(transaction: SKTransaction!) { }
func transaction(transaction: SKTransaction!, didReceiveRecognition recognition: SKRecognition!) {
//Take the best result
let topRecognitionText = recognition.text;
print("Best rec test: \(topRecognitionText)")
//Or iterate through the NBest list
let nBest = recognition.details;
for phrase in (nBest as! [SKRecognizedPhrase]!) {
let text = phrase.text;
let confidence = phrase.confidence;
print("\(confidence): \(text)")
}
}
func transaction(transaction: SKTransaction!, didReceiveServiceResponse response: [NSObject : AnyObject]!) { }
func transaction(transaction: SKTransaction!, didFinishWithSuggestion suggestion: String!) { }
func transaction(transaction: SKTransaction!, didFailWithError error: NSError!, suggestion: String!) { }
}

Attempting to load Webview with PDF, receiving link from Parse

I am attempting to load a lunch menu PDF into a web view for a high school app that I am updating. Currently, it can load a PDF into the web view and display it just fine, but I want to speed up the monthly update process by having my app receive the link through Parse (Which I can update much quicker than updating the link in the app itself with Apple's 7 day review period), and then load the PDF. Currently, with what I have put together, my app will not load the PDF. Here's the entire view:
import UIKit
class AlaCarte_ViewController: UIViewController {
#IBOutlet weak var webviewAlaCarte: UIWebView!
var urlpath = String()
func loadAddressUrl(){
let requestURL = NSURL (string:urlpath)
let request = NSURLRequest(URL: requestURL!)
webviewAlaCarte.loadRequest(request)
alaCarteUpdate()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
clearPDFBackground(self.webviewAlaCarte)
}
func clearPDFBackground(webView: UIWebView) {
var view :UIView?
view = webView as UIView
while view != nil {
if NSStringFromClass(view?.dynamicType) == "UIWebPDFView" {
view?.backgroundColor = UIColor.clearColor()
}
view = view?.subviews.first as! UIView?
}
}
func alaCarteUpdate() {
var query = PFQuery(className: "AlaCarte")
query.getObjectInBackgroundWithId("rT7MpEFySU") {(AlaCarte: PFObject!, error: NSError!)-> Void in
if error == nil && AlaCarte != nil {
println(AlaCarte)
} else {
println(error)
}
let AlaCarteLink = AlaCarte["webaddress"] as! String
self.urlpath = AlaCarteLink
}
}
override func viewDidLoad() {
super.viewDidLoad()
loadAddressUrl()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
The link is stored in my Parse app as "webaddress" and does not contain end quotations. Adding them does not help. Any ideas?
It looks to me like you're not telling the web view to load the URL once it's retrieved from Parse.
Try adding the following lines after self.urlpath = AlaCarteLink in alaCarteUpdate().
let requestURL = NSURL (string:self.urlpath)
let request = NSURLRequest(URL: requestURL!)
self.webviewAlaCarte.loadRequest(request)
I think it would also be a good idea to add a function that specifically loads a url string into your web view, so you can call it from both inside alaCarteUpdate(), and loadAddressUrl(), and avoid the duplicate 3x lines. I've assumed that you're loading the URL in loadAddressURL() so that you can show a local/cached document while retrieving the latest from Parse.

AVFoundation Value of option type 'String?' not unwrapped, App Crashes, won't play sound

I'm trying to play a simple sound when I push a button. xcode is forcing me to use a "!" for my NSURL for the audio file, I followed other tutorials for how to play a sound in swift and for some reason I keep getting this error, why!? Code:
import UIKit
import AVFoundation
class ViewController: UIViewController {
var player = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
let path = NSBundle.mainBundle().pathForResource("buttonSound", ofType: "mp3")
let fileURL = NSURL(fileURLWithPath: path!)
player = AVAudioPlayer(contentsOfURL: fileURL, error: nil)
player.prepareToPlay()
}
#IBAction func button21(sender: AnyObject) {
player.play()
}
}
When I do add the "!", the app will load without crashing, when I press the button the app crashes and the log outputs "fatal error: unexpectedly found nil while unwrapping an Optional value"
Good to see your problem got solved. Just adding to the conversation:
I had the same issue as you and I followed the advice given by other people here, but it didn't get rid of my problem (unexpectedly found nil while unwrapping an Optional value). I'm using Xcode 6.1 and the thing that solved it for me was deleting the file and adding it again except this time, instead of dragging the file in, I did it by right-clicking the project folder and selecting the "Add Files to your_app's_name" option.
import UIKit
import AVFoundation
class ViewController: UIViewController {
var myPlayer = AVAudioPlayer()
var yourSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("alarm2", ofType: "mp3")!)
func prepareYourSound() {
myPlayer = AVAudioPlayer(contentsOfURL: yourSound, error: nil)
myPlayer.prepareToPlay()
}
override func viewDidLoad() {
super.viewDidLoad()
prepareYourSound()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func playMySound(sender: AnyObject) {
myPlayer.play()
}
}
HERE is the project sample link
Sample Project
A bit old now, but I had the same problem recently.
The way I fixed it was to select my file (an mp3, too) and go into the File Inspector and make sure the Target Membership was checked for my project.

Cached Tiles not showing - Mapbox IOS SDK

I am fairly new to iOS programming and am building my app in Swift for iOS8 and also implementing the Mapbox-ios-sdk as I want my user to be able to download offline map areas.
I've been able to download offline map areas in the cache, however it seems the cache is not accessed when I turn of Wifi and cellular data. The Map Tiles are not coming up. Only the Map Tiles that were automatically cached are showing.
I see that the tiles are being downloaded (RMTileCache.db is growing, the RMTileCacheBackgroundDelegate methods didBeginBackgroundCacheWithCount, didBackgroundCacheTile and tileCacheDidFinishBackgroundCache are being called) and, when looking directly in the db file I also see that the correct tiles have been downloaded.
But, when I then turn off Wifi and Cellular data, the map tiles are not loaded on the screen. I've tried several options with adding additional RMDatabase Caches etc, but nothing seems to work. I'm hoping that someone out there ran into the same problem and can help me out.
My code is roughly based on this piece here: http://mapbox.com/mapbox-ios-sdk/#tile_caching__class
Class Level relevant variables:
var tileSource: RMMapboxSource = RMMapboxSource()
#IBOutlet var mapView: RMMapView!
viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
let fullPath: String = NSBundle.mainBundle().pathForResource("mapbox", ofType: "json")!
var errorInFullPath:NSErrorPointer? = NSErrorPointer()
let tileJSON: String? = String(contentsOfFile: fullPath, encoding:NSUTF8StringEncoding, error: errorInFullPath!)
tileSource = RMMapboxSource(tileJSON: tileJSON)
initializeMap()
}
The Map initialization:
func initializeMap() {
mapView = RMMapView(frame: self.view.bounds)
mapView.tileSource = tileSource
tileSource.cacheable = true
mapView.adjustTilesForRetinaDisplay = true
mapView.userInteractionEnabled = true
mapView.zoom = 9
self.view.addSubview(mapView)
mapView.delegate = self
}
The download operation:
func startDownload() {
mapView.tileCache.backgroundCacheDelegate = self
mapView.tileCache.beginBackgroundCacheForTileSource(tileSource, southWest: sw, northEast: ne, minZoom: 1, maxZoom: zoomLevel)
}
sw, ne and zoomLevel have been defined elsewhere in the code and their values are good when I print them out just before the beginBackgroundCacheForTileSource command.
I'm not sure what I'm doing wrong here. Probably something really stupid, but I've been trying to find it for 2 days now. Hope someone can help me out.
Thanks in advance!
OK, so I got it working thanks to the tip of incanus. Turns out it was two problems which made it more difficult to analyze and find the root cause.
1st problem was indeed that I had some layout things going on in viewDidLoad which somehow prevented cashed map tiles to be loaded.
2nd problem was that the area I was downloading was slightly different from the area I thought I was downloading. So I just need to tweak the pixelToCoordinate method of RMMapView which I'm using to get this right.
For those of you interested. I created a separate clean swift file without any layout in it, just to follow up on Incanus' comment. This worked for me!
Thanks to Incanus. Hope someone else will find this useful too.
import UIKit
class ViewOfflineMapAreaViewController: UIViewController, RMMapViewDelegate {
var tileSource: RMMapboxSource = RMMapboxSource()
#IBOutlet var mapView: RMMapView!
override func viewDidLoad() {
super.viewDidLoad()
let fullPath: String = NSBundle.mainBundle().pathForResource("mapbox", ofType: "json")!
var errorInFullPath:NSErrorPointer? = NSErrorPointer()
let tileJSON: String? = String(contentsOfFile: fullPath, encoding:NSUTF8StringEncoding, error: errorInFullPath!)
tileSource = RMMapboxSource(tileJSON: tileJSON)
tileSource.retryCount = 3
initializeMap()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func initializeMap() {
mapView = RMMapView(frame: self.view.bounds)
mapView.tileSource = tileSource
tileSource.cacheable = true
mapView.adjustTilesForRetinaDisplay = true
mapView.userInteractionEnabled = true
mapView.zoom = 9
mapView.delegate = self
//These two lines are just to resize the mapView upon device rotation
mapView.setTranslatesAutoresizingMaskIntoConstraints(true)
mapView.autoresizingMask = UIViewAutoresizing.FlexibleHeight | UIViewAutoresizing.FlexibleWidth
}
override func viewDidAppear(animated: Bool) {
self.view.addSubview(mapView)
}
}
You are saving the TileJSON locally and using it for instantiation, which is needed when you are operating offline. But I think your problem may be in doing layout during -viewDidLoad. Try this in -viewWillAppear: or later and I think you'll see different results.

Resources