Cannot Find Pdf File being created in Swift XCode - ios

Iv used the following Code from Tom to create a Pdf File and
PDF Generation Swift
im having the same problem finding the document I created using Tom's code. Iv search my Mac HD and still no document and the programme does not crash. And when i look at the log it shows it has been stored at the following path
pdfPathWithFileName String "/Users/cleota/Library/Developer/CoreSimulator/Devices/B72A97D0-339E-4E79-AED6-4991D3B7C4B7/data/Containers/Data/Application/7A7789C4-27C5-45FB-8604-E36865609764/Documents/Ezy Essay Test.pdf"
but when I go there these folders(Library/Developer/CoreSimulator/Devices)are not there where it says it has been stored. Thoughts please?
#IBAction func createPdfDocument(sender: AnyObject) {
let fileName: String = "Taumaoe.pdf"
let path:NSArray = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentDirectory: AnyObject = path.objectAtIndex(0)
let pdfPathWithFileName = documentDirectory.stringByAppendingPathComponent(fileName as String)
print(pdfPathWithFileName)
generatePdf(pdfPathWithFileName)
}
func generatePdf(filepath: String){
UIGraphicsBeginPDFContextToFile(filepath, CGRectZero, nil)
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 850, 1100), nil)
drawBackground()
}
func drawBackground(){
var context:CGContextRef = UIGraphicsGetCurrentContext()!
// var rect:CGRect = CGRectMake(0, 0, CGSize.height, CGSize.width)
//CGContextSetFillColorWithColor(context, UIColor.greenColor().CGColor)
//CGContextFillRect(context, rect)
var testView = UIView (frame: CGRectMake(0,0,850,1100))
testView.backgroundColor = UIColor.yellowColor()
var label = UILabel (frame: CGRectMake(10,10,100,20))
label.textColor = UIColor.redColor()
label.backgroundColor = UIColor.lightGrayColor()
label.text = "I'am a test label"
testView.addSubview(label)
testView.layer.renderInContext(context)
UIGraphicsEndPDFContext()
//Title of 1st option of MainController
let sexyKeyWordscontroller = UIAlertController(title: "Ezy Essay Saved!", message: "Well done! Your Ezy Essay Pdf document has been saved at the following path: ", preferredStyle: UIAlertControllerStyle.Alert)
let closeButton : UIAlertAction = UIAlertAction(title: "Close",
style: UIAlertActionStyle.Cancel,
handler: {
(alert: UIAlertAction!) in sexyKeyWordscontroller.dismissViewControllerAnimated(true,
completion: nil)
})
sexyKeyWordscontroller.addAction(closeButton)
self.presentViewController(sexyKeyWordscontroller, animated: true, completion: nil)
}
Thanks

If you print out pdfPathWithFileName in the button event you will get the file path. When you have the file path open a finder window and in the file menu click: Go > Go to folder
The path that you have printed out will look something like this:
/Users/USERNAME/Library/Developer/CoreSimulator/Devices/...
Copy this into the Go to folder from the path
~/Library/Developer/CoreSimulator/Devices/...
And of course skip the last "/xp.pdf" in the path if you only want to open the location of the folder and not the file itself.

Related

How to use C library in Xcode Project?

The library is written in C https://github.com/jmcnamara/libxlsxwriter
The pod file that I am using is
pod 'libxlsxwriter', '0.3.1'
I import the header into the Bridging Header
#import <libxlsxwriter/xlsxwriter.h>
I am getting this
'libxlsxwriter/xlsxwriter.h' file not found
It is actually quite simple, yet poorly documented (IMHO):
Install the library with CocoaPods:
Add pod 'libxlsxwriter', '~> 0.9' to your pod file.
Run pod install
You do not need a Swift-Bridging-Header, simply use the library like so:
import UIKit
import xlsxwriter
...
override func viewDidLoad() {
super.viewDidLoad()
createExcelFile()
}
override func viewWillAppear(_ animated: Bool) {
}
/*#objc*/ func createExcelFile(){
// Create a new workbook.
let documentDirectory = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor:nil, create:false)
let fileURL = documentDirectory.appendingPathComponent("demo.xlsx")
//Ditch first 6 characters, because they are of the form file://
let workbook = workbook_new((fileURL.absoluteString.dropFirst(6) as NSString).fileSystemRepresentation)
// Add a worksheet with a user defined sheet name.
let worksheet1 = workbook_add_worksheet(workbook, "Demo")
// Add a worksheet with Excel's default sheet name: Sheet2.
let worksheet2 = workbook_add_worksheet(workbook, nil)
// Add some cell formats.
let myformat1 = workbook_add_format(workbook)
let myformat2 = workbook_add_format(workbook)
// Set the bold property for the first format.
format_set_bold(myformat1)
// Set a number format for the second format.
format_set_num_format(myformat2, "$#,##0.00")
// Widen the first column to make the text clearer.
worksheet_set_column(worksheet1, 0, 0, 20, nil)
// Write some unformatted data.
worksheet_write_string(worksheet1, 0, 0, "Peach", nil)
worksheet_write_string(worksheet1, 1, 0, "Plum", nil)
// Write formatted data.
worksheet_write_string(worksheet1, 2, 0, "Pear", myformat1)
// Formats can be reused.
worksheet_write_string(worksheet1, 3, 0, "Persimmon", myformat1)
// Write some numbers.
worksheet_write_number(worksheet1, 5, 0, 123, nil)
worksheet_write_number(worksheet1, 6, 0, 4567.555, myformat2)
// Write to the second worksheet.
worksheet_write_string(worksheet2, 0, 0, "Some text", myformat1)
// Close the workbook, save the file and free any memory
workbook_close(workbook)
loadingSpinner.stopAnimating()
self.shareExcelFile(filepath: fileURL)
}
func shareExcelFile(filepath: URL){
//Share the newly created file
var filesToShare = [Any]()
filesToShare.append(filepath)
let activityViewController = UIActivityViewController(activityItems: filesToShare, applicationActivities: [])
activityViewController.popoverPresentationController?.sourceView = self.view
activityViewController.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.maxX, y: self.view.bounds.minY, width: 0, height: 0)
activityViewController.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.init(rawValue: 0)
self.present(activityViewController, animated: true)
activityViewController.completionWithItemsHandler = { activity, completed, items, error in
if !completed {
// handle task not completed
return
}
self.dismiss(animated: false, completion: nil)
}
}
}
This should create an example .xlsx file, save it to the ~Documents directory and share it.
I did not test the code, so expect needing to change some bits.
I will setup a demo repository, once I get the time to do it...

View is not displayed

I have an alert box that takes user input and starts a download task. After the user clicks "Ok," I want the screen to show a UIView that I added an ActivityIndicator to while the download occurs. The download occurs successfully and the function correctly opens up the next controller, however, the custom view nor activity indicator are ever displayed. Here's my code:
private func getKeyFromAlert() {
let alert = UIAlertController(title: "Enter Key", message: "Enter your text key below. If you want to scan it instead, click \"Scan Key.\" ", preferredStyle: .alert)
alert.addTextField { (textField) in
let attribString = NSAttributedString(string: "Enter your app code here")
textField.attributedPlaceholder = attribString
}
let scanAction = UIAlertAction(title: "Scan Key", style: .default) { _ in
self.openSettingsForApp()
}
let okAction = UIAlertAction(title: "OK", style: .default) { _ in
let textField = alert.textFields![0]
if let text = textField.text {
let encoded = text.toBase64()
let status = APIKeychain.storeToken(encoded)
if !status {
self.displayAlertForBadKeychain(useCamera: false)
} else {
self.addLoader()
self.dismissSetup()
}
} else {
let _ = APIKeychain.storeToken("")
self.addLoader()
self.dismissSetup()
}
}
alert.addAction(scanAction)
alert.addAction(okAction)
show(alert, sender: nil)
}
The function in question that I use to display the UIView is addLoader()
The code for addLoader is:
private func addLoader() {
let frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height)
let loaderView = UIView(frame: frame)
loaderView.alpha = 1.0
loaderView.backgroundColor = UIColor.white
let activitySpinner: UIActivityIndicatorView = UIActivityIndicatorView(frame: loaderView.frame)
activitySpinner.center = loaderView.center
activitySpinner.hidesWhenStopped = false
activitySpinner.style = .whiteLarge
activitySpinner.startAnimating()
loaderView.addSubview(activitySpinner)
self.view.addSubview(loaderView)
self.view.layoutIfNeeded()
}
I've tried several iterations of setNeedsDisplay and setNeedsLayout without luck. I've also tried explicitly declaring this in a DispatchQueue.main.async without any affect as well.
EDIT
I added the code below for dismissSetup()
private func dismissSetup() {
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
DispatchQueue.global(qos: .background).async {
if self.updateDatabase {
//This will start the download process
let _ = WebDataFetcher(dataStack: self.dataStack)
}
dispatchGroup.leave()
}
dispatchGroup.wait()
let mainSB = UIStoryboard(name: "UserInputs", bundle: nil)
let mainVC = mainSB.instantiateViewController(withIdentifier: "userInputs")
appDelegate.window?.rootViewController = mainVC
}

Swift - Warning when editing text fields and tapping buttons

I have a scroll view that adds UI elements programmatically, but a button that I've added seems to have a delay in response once tapped both in a simulator and on an iPhone 7 Plus I use to test on it. I'm not sure as to why. I also am getting warning messages each time a text field is edited as well. How do I resolve these issues? Below our the warning messages and some of my code.
Thank you for helping!
Button warning in log:
2017-04-20 14:49:35.087232-0500 HAEForMe[889:369946] Warning: Attempt to present <UIAlertController: 0x102642b00> on <AppName.UserSetupViewController: 0x10303dc00> which is already presenting <UIAlertController: 0x10243b9b0>
Textfield warning in log:
2017-04-20 16:00:56.105536-0500 HAEForMe[52504:6463817] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /Users/andrewzimmerman/Library/Developer/CoreSimulator/Devices/476B95C5-691C-43D0-98D8-EAC400F6A41A/data/Containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
2017-04-20 16:00:56.106290-0500 AppName[52504:6463817] [MC]
Code:
//Begin UITextField Initialization
var inputFields = [UITextField]()
let textField = UITextField() // This continues until there are 10.
/*
AddFields - Adds UITextFields to the inputFields array.
*/
private func addFields()
{
inputFields.append(textField) // Done for all 10 fields.
}
/*
ViewDidLoad - Runs stated code when the view loads.
*/
override func viewDidLoad() {
super.viewDidLoad()
prepareScrollView() //If view is touched, keyboard is dismissed.
addFields() //Adds some UITextFields to an array.
managePages() //Adds images, textfields, and button to ScrollView
addDoneButtonOnKeyboard() //Adds a tool bar with the done button
}
/*
ManagePages - Adds all items required for Scroll View [Some code
is removed as it is irrelevant]
*/
private func managePages()
{
self.sideScrollView.frame = CGRect(x:0, y:0, width:self.view.frame.width, height:self.view.frame.height)
let scrollViewWidth:CGFloat = self.sideScrollView.frame.width
let scrollViewHeight:CGFloat = self.sideScrollView.frame.height
//*!*!* EFFICIENCY IN QUESTION *!*!*
for (index,element) in inputFields.enumerated()
{
if(index == 0)
{
//Sets properties of UITextField
}
else if(index == 1)
{
//Sets properties of UITextField
}
// The else if statements continue on until index is 9
}
let getStartedButton = UIButton(frame: CGRect(x:((scrollViewWidth*5) + scrollViewWidth/2)-125, y: scrollViewHeight-175, width: 250, height: 99))
getStartedButton.setImage(UIImage(named: "GetStartedButton"), for: UIControlState.normal)
getStartedButton.addTarget(self, action: #selector(finishSetup), for: .touchUpInside)
//*!*!* EFFICIENCY IN QUESTION *!*!*
for fieldName in inputFields
{
self.sideScrollView.addSubview(fieldName)
}
self.sideScrollView.addSubview(getStartedButton)
self.sideScrollView.contentSize = CGSize(width:self.sideScrollView.frame.width * 6, height:self.sideScrollView.frame.height)
self.sideScrollView.delegate = self
}
/*
FinishSetup - Checks all fields for input, ensure they aren't blank
and uses them
*/
func finishSetup(sender: UIButton!) {
print("Finished setup button tapped, attempting to finalize setup.")
var firstName: String = ""
var lastName: String = ""
var dateOfBirthValue: String = ""
var dateFormatter: DateFormatter
var date: Date = Date()
var age:Double = 0.0
var weight: Double = 0.0
var height: String = ""
var factType: String = "" //Name Changed
var valueType: Int = 0 //Name Changed
for (index,fieldName) in inputFields.enumerated()
{
if(fieldName.text != " " && fieldName.text != "" && fieldName.text != nil)
{
/*
Goes through each field in the array via each and every index
and then uses if statements to pull the text value for use in
a database later on.
*/
}
else
{
//*!*!* EFFICIENCY IN QUESTION *!*!*
print("Presenting blank field alert.")
let alertController = UIAlertController(title: "Uh Oh!", message: "Looks like you left something blank, please make sure that you've filled every field out and try again.", preferredStyle: UIAlertControllerStyle.alert)
let okayAction = UIAlertAction(title: "Okay", style: UIAlertActionStyle.default) {
(result: UIAlertAction) -> Void in
print("User reacted to blank field alert.")
}
alertController.addAction(okayAction)
self.present(alertController, animated: true, completion: nil)
return
}
}
}

why does Bundle.main.path(forResource: fileName, ofType: "txt") always return nil?

I want to read a text file line by line and display it on an iOS screen using the example shown here.
Making textView.text optional was the only way I could get readDataFromFile to run. When I click load the function runs but always returns nil. I assume this means the file is not found.
For testing purposes I created the text file in Xcode. I also tried saving it on the desktop as well as in the project folder. Either way it was readable from the project navigator. I also tried creating the file using TextEdit because the app ultimately needs to read text files created outside Xcode.
I’d be grateful if someone can explain why the text file is never found, whether there is something else I need to do in order for the project to find it or if the read function returns nil for some other reason due to the way I have implemented it. Thanks.
EDIT (2)
Thanks for the feedback. In response, I’ve made four minor code changes that allow the text file contents to be written to textView. Changes include: removing the file extension from the filename, adding an array of file names, returning String instead of String? from readDataFromFile and rewriting UITextView in code. This has solved problems I am aware of.
Here's the revised code
import UIKit
class ViewController: UIViewController {
var textView = UITextView()
var arrayOfStrings: [String]?
var fileNameWithExtension = "textFile.txt"
let arrayOfFileNames = ["textFile1.txt", "textFile2.txt", "textFile3.txt", "textFile4.txt", "textFile5.txt"]
var fileName = String()
override func viewDidLoad() {
super.viewDidLoad()
// remove comment in the next statement to test files named in ArrayOfFileNames
// fileNameWithExtension = arrayOfFileNames[4]
fileName = fileNameWithExtension.replacingOccurrences(of: ".txt", with: "")
createTextView()
createButton()
}
func readDataFromFile(fileName: String) -> String {
if let path = Bundle.main.path(forResource: fileName, ofType: nil) {
print(fileName)
do {
let data = try String(contentsOfFile: path, encoding: String.Encoding.utf8)
arrayOfStrings = data.components(separatedBy: .newlines)
textView.text = arrayOfStrings?.joined(separator: "\n")
} catch {
textView.text = "file contents could not be loaded"
}
} else {
print(Bundle.main.path(forResource: fileName, ofType: "txt") as Any)
textView.text = "\(fileName) could not be found"
}
return textView.text
}
func createButton () {
let button = UIButton();
button.setTitle(String("Load"), for: .normal)
button.setTitleColor(UIColor.blue, for: .normal)
button.frame = CGRect(x: 100, y: 10, width: 200, height: 100)
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
self.view.addSubview(button)
}
func buttonAction(myButton: UIButton) {
textView.text = readDataFromFile(fileName: fileName)
print(textView.text as Any)
}
func createTextView () {
textView = UITextView(frame: CGRect(x: 20.0, y: 75.0, width: 340.0, height: 400.0))
textView.textAlignment = NSTextAlignment.left
textView.textColor = UIColor.blue
textView.backgroundColor = UIColor.white
self.view.addSubview(textView)
}
}
EDIT (1)
The file is visible in the project navigator. I will assume that means it is in the bundle.
Here is my original code
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var textView: UITextView?
var arrayOfStrings: [String]?
var fileName = "textFile.txt"
override func viewDidLoad() {
super.viewDidLoad()
createButton()
}
func readDataFromFile(fileName: String) -> String? {
if let path = Bundle.main.path(forResource: fileName, ofType: "txt") {
print(fileName)
do {
let data = try String(contentsOfFile: path, encoding: String.Encoding.utf8)
arrayOfStrings = data.components(separatedBy: .newlines)
print(arrayOfStrings as Any)
textView?.text = arrayOfStrings?.joined(separator: "/n")
return textView?.text
} catch {
textView?.text = "file contents could not be loaded"
return textView?.text
}
} else {
print(Bundle.main.path(forResource: fileName, ofType: "txt") as Any)
textView?.text = "\(fileName) could not be found"
return nil
}
}
func createButton () {
let button = UIButton();
button.setTitle(String("Load"), for: .normal)
button.setTitleColor(UIColor.blue, for: .normal)
button.frame = CGRect(x: 100, y: 15, width: 200, height: 100)
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
self.view.addSubview(button)
}
func buttonAction(myButton: UIButton) {
print("works")
textView?.text = readDataFromFile(fileName: fileName)
print(textView?.text as Any)
}
textFile.txt
Line 1
Line 2
Line 3
Line 4
Line 5
1) You have mistake in this line:
var fileName = "textFile.txt"
should be:
var fileName = "textFile"
2) Check is your file connected to target:
You should consider adding class bundle owner like this:
Bundle(for: ViewController.self).path(forResource: "fileName", ofType: "txt")
This was implemented from swift 2.0 if I was right.

Can't get results from ConsentDocument by identifier. ResearchKit

Here is what I want to do: use results from ConsentDocument for view it in ViewController using identifier of step. But signature is always nil. So, how can I get fisrt and last name from Consent Document?
override func viewDidLoad() {
super.viewDidLoad()
let signatureResult = ORKConsentSignatureResult(identifier: "ConsentReviewStep")
let signature = signatureResult.signature
let label = UILabel(frame: CGRectMake(0, 0, 200, 21))
label.center = CGPointMake(160, 284)
label.textAlignment = NSTextAlignment.Center
label.text = signature?.givenName
self.view.addSubview(label)}
Here I'm creating step, where user gave me givenName(first name) and familyName(last name). This step named reviewConsentStep.
#IBAction func joinButtonTapped(sender: UIButton) {
let consentDocument = ConsentDocument()
let consentStep = ORKVisualConsentStep(identifier: "VisualConsentStep", document: consentDocument)
let healthDataStep = HealthDataStep(identifier: "Health")
let signature = consentDocument.signatures!.first!
let reviewConsentStep = ORKConsentReviewStep(identifier: "ConsentReviewStep", signature: signature, inDocument: consentDocument)
reviewConsentStep.text = "Review the consent form."
reviewConsentStep.reasonForConsent = "Consent to join the Developer Health Research Study."
let passcodeStep = ORKPasscodeStep(identifier: "Passcode")
passcodeStep.text = "Now you will create a passcode to identify yourself to the app and protect access to information you've entered."
let completionStep = ORKCompletionStep(identifier: "CompletionStep")
completionStep.title = "Welcome aboard."
completionStep.text = "Thank you for joining this study."
let orderedTask = ORKOrderedTask(identifier: "Join", steps: [consentStep, reviewConsentStep, healthDataStep, passcodeStep, completionStep])
let taskViewController = ORKTaskViewController(task: orderedTask, taskRunUUID: nil)
taskViewController.delegate = self
presentViewController(taskViewController, animated: true, completion: nil)
}
}

Resources