How to overwrite strings within an if-loop in Swift - string

I have a few variables that I create within code for a view controller (basically, I'm just checking the values of segmented controls), but when I try to write into the string within the loops (shown below), nothing is written, and all strings remain "nil."
var textTypeVideo:String?
var textMultipleAgents:String?
var textAdditionalRooms:String?
var textMultipleVideos:String?
var textTurnaround:String?
Here are the functions that check to see where the segmented controls are:
#IBAction func typeOfVideoAction(sender: AnyObject) {
if typeOfVideoControl.selectedSegmentIndex == 0 {
textTypeVideo = "Standard Home Video"
} else {
textTypeVideo = "Standard CV Video"
}
}
#IBAction func mulitpleAgentScenesAction(sender: AnyObject) {
if multipleAgentScenesControl.selectedSegmentIndex == 0 {
textMultipleAgents = "Multiple Agent Scenes Desired"
} else {
textMultipleAgents = "No Multiple Agent Scenes"
}
}
#IBAction func additionalRoomsAction(sender: AnyObject) {
if additionalRoomsFeaturesControl.selectedSegmentIndex == 0 {
textAdditionalRooms = "Additional Rooms & Features Desired"
} else {
textAdditionalRooms = "No Additional Rooms & Features"
}
}
#IBAction func multipleVideosAction(sender: AnyObject) {
if multipleVideoCopiesControl.selectedSegmentIndex == 0 {
textMultipleVideos = "Second Video Copy Requested"
} else {
textMultipleVideos = "No Second Video Copy"
}
}
#IBAction func turnaroundAction(sender: AnyObject) {
if turnaroundControl.selectedSegmentIndex == 0 {
textTurnaround = "No Quick Turnaround"
} else if turnaroundControl.selectedSegmentIndex == 1 {
textTurnaround = "24 Hour Turnaround Desired"
} else if turnaroundControl.selectedSegmentIndex == 2 {
textTurnaround = "2 Business Day Turnaround Desired"
} else if turnaroundControl.selectedSegmentIndex == 3 {
textTurnaround = "3 Business Day Turnaround Desired"
} else {
textTurnaround = "5 Business Day Turnaround Desired"
}
}
Finally, this is what I want to fill in and print in an email:
let messageBody = "\(textTypeVideo) and \(textMultipleAgents) and \(textAdditionalRooms) and \(textMultipleVideos) and \(textTurnaround)"
mailComposerVC.setMessageBody(messageBody, isHTML: false)
Any help is greatly appreciated! I just can't seem to fill in the top variables with what they're supposed to be, based on the segmented controls! Thanks.

Related

Problem with getEmail() Google sheet, not working for other persons?

I have a problem with getting email.
I have checked a lot of threads but I have not found the solution.
So I am the leader of the group. I am using Google Sheets for the Checklist.
I would like to simplify for every person so that it would be easier and no reason not to fulfill checklists.
basically: every time there is a checkbox clicked, automatic put in of date and email. But email works only for me. I have tried with a friend's account and I can not get it working.
is this Security Politics? Can i change it somehow?
I also updated the appsscript.json
{
"oauthScopes":
[
"https://www.googleapis.com/auth/spreadsheets.readonly",
"https://www.googleapis.com/auth/userinfo.email"
],
"timeZone": "Europe/Paris",
"dependencies": {
},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8"
}
the script.
function onEdit(e) {
if(e.value != "TRUE" ) return;
e.source.getActiveSheet().getRange(e.range.rowStart,e.range.columnStart+2).setValue(new Date());
var text = e.user.getEmail();
if (text == "xxx1#gmail.com")
{
text = "xxx1";
}
else if (text == "Pxxx2#gmail.com")
{
text = "Pxxx2";
}
else if (text == "Kxxx2#gmail.com")
{
text = "Kxxx2";
}
else if (text == "kxxx1#gmail.com")
{
text = "Kxxx1";
}
else if (text == "jxxx1#gmail.com")
{
text = "Jxxx1";
}
else if (text == "jxxx2#gmail.com")
{
text = "Jxxx2";
}
else if (text == "")
{
text = "ID not found";
}
else
{
text = e.user.getEmail();
}
e.source.getActiveSheet().getRange(e.range.rowStart,e.range.columnStart+4).setValue(text);
}

Publish background context Core Data changes in a SwiftUI view without blocking the UI

After running a background-context core data task, Xcode displays the following purple runtime warning when the updates are published in a SwiftUI view:
"[SwiftUI] Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates."
Besides the ContentView.swift code below, I also added container.viewContext.automaticallyMergesChangesFromParent = true to init in the default Persistence.swift code.
How can I publish the background changes on the main thread to fix the warning? (iOS 14, Swift 5)
Edit: I've changed the code below, in response to the first answer, to clarify that I'm looking for a solution that doesn't block the UI when a lot of changes are saved.
struct PersistenceHelper {
private let context: NSManagedObjectContext
init(context: NSManagedObjectContext = PersistenceController.shared.container.viewContext) {
self.context = context
}
public func fetchItem() -> [Item] {
do {
let request: NSFetchRequest<Item> = Item.fetchRequest()
var items = try self.context.fetch(request)
if items.isEmpty { // Create items if none exist
for _ in 0 ..< 250_000 {
let item = Item(context: context)
item.timestamp = Date()
item.data = "a"
}
try! context.save()
items = try self.context.fetch(request)
}
return items
} catch { assert(false) }
}
public func updateItemTimestamp(completionHandler: #escaping () -> ()) {
PersistenceController.shared.container.performBackgroundTask({ backgroundContext in
let start = Date(), request: NSFetchRequest<Item> = Item.fetchRequest()
do {
let items = try backgroundContext.fetch(request)
for item in items {
item.timestamp = Date()
item.data = item.data == "a" ? "b" : "a"
}
try backgroundContext.save() // Purple warning appears here
let interval = Double(Date().timeIntervalSince(start) * 1000) // Artificial two-second delay so cover view has time to appear
if interval < 2000 { sleep(UInt32((2000 - interval) / 1000)) }
completionHandler()
} catch { assert(false) }
})
}
}
// A cover view with an animation that shouldn't be blocked when saving the background context changes
struct CoverView: View {
#State private var toggle = true
var body: some View {
Circle()
.offset(x: toggle ? -15 : 15, y: 0)
.frame(width: 10, height: 10)
.animation(Animation.easeInOut(duration: 0.25).repeatForever(autoreverses: true))
.onAppear { toggle.toggle() }
}
}
struct ContentView: View {
#State private var items: [Item] = []
#State private var showingCoverView = false
#State private var refresh = UUID()
let persistence = PersistenceHelper()
let formatter = DateFormatter()
var didSave = NotificationCenter.default
.publisher(for: .NSManagedObjectContextDidSave)
// .receive(on: DispatchQuene.main) // Doesn't help
var body: some View {
ScrollView {
LazyVStack {
Button("Update Timestamp") {
showingCoverView = true
persistence.updateItemTimestamp(completionHandler: { showingCoverView = false })
}
ForEach(items, id: \.self) { item in
Text(formatter.string(from: item.timestamp!) + " " + (item.data ?? ""))
}
}
}
.id(refresh)
.onAppear {
formatter.dateFormat = "HH:mm:ss"
items = persistence.fetchItem()
}
.onReceive(didSave) { _ in
items = persistence.fetchItem()
}
.fullScreenCover(isPresented: $showingCoverView) {
CoverView().onDisappear { refresh = UUID() }
}
}
}
Since you are performing a background task, you are on a background thread - rather than the main thread.
To switch to the main thread, change the line producing the runtime warning to the following:
DispatchQueue.main.async {
try backgroundContext.save()
}
You should use Combine and observe changes to your background context and update State values for your UI to react.
#State private var coreDataAttribute = ""
var body: some View {
Text(coreDataAttribute)
.onReceive(
CoreDataManager.shared.moc.publisher(for: \.hasChanges)
.subscribe(on: DispatchQueue.global())
.receive(on: DispatchQueue.global())
.map{_ in CoreDataManager.shared.fetchCoreDataValue()}
.filter{$0 != coreDataAttribute}
.receive(on: DispatchQueue.main))
{ value in
coreDataAttribute = value
}
}

Video couldn't be played properly under iOS12

I'm using AVAssetResourceLoader to load data and AVPlayerViewController to play.
It works properly under iOS10, 11 but not work any more under iOS12.
When playing, the process bar is moving forward, but the video only plays 1 sec, and stuck till end.
Here's my AVAssetResourceLoader code:
class MediaResourceLoader: NSObject, AVAssetResourceLoaderDelegate {
func resourceLoader(
_ resourceLoader: AVAssetResourceLoader,
shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest
) -> Bool {
loadingRequest.contentInformationRequest?.contentType = kUTTypeMPEG4 as String
loadingRequest.contentInformationRequest?.contentLength = Int64(self.data.count)
loadingRequest.contentInformationRequest?.isByteRangeAccessSupported = true
guard let request = loadingRequest.dataRequest else { return false }
if request.requestsAllDataToEndOfResource {
request.respond(with: data)
} else if Int(request.requestedOffset) <= request.requestedLength {
let subData = self.data.subdata(in: Int(request.requestedOffset)..<request.requestedLength)
request.respond(with: subData)
}
loadingRequest.finishLoading()
return true
}
}

Commands not all working in J2ME app

Part of my j2me project involves use of the filesystem, so I'm starting with a simple file browser. The current issue I'm facing is the implementation of the command processor. To wit:
<CODE>
public void commandAction(Command c, Displayable d) {
if (c.getLabel().equals("Exit")) {
notifyDestroyed();
}
// File retrieval code (or call to it) to go here later.
if (c.getLabel().equals("Enter")) {
current_name = getRidOfTrailingSlash(current_name)
+ "/" + mainscreen.getString(mainscreen.getSelectedIndex());
// + "/" + "MemoryCard/";
System.exit(0);
if (! setName(current_name)) {
dirlist = rootlist;
current_name = "/";
}
showDirs();
}
if (c.getLabel().equals("Up Dir")) {
if (current_name.equals("/")) return;
current_name = getRidOfTrailingSlash(current_name);
if (setName(current_name)) current_name = current_fc.getPath();
else current_name = "/";
if (current_name.equals("/")) dirlist = rootlist;
else {
try {
dirlist = current_fc.list();
} catch (IOException ioe) {}
}
showDirs();
}
if (c.getLabel().equals("Create")) {
System.exit(1);
// Create code to be added later
}
if (c.getLabel().equals("Delete")) {
System.exit(2);
// Delete code to be added later
}
} // End of command actions
</CODE>
I am working on debugging the code for "Enter", and plan to write the code for "Create" and "Delete" at a later date. So for now I have them exit to an expected Security exception.
The code that sets up the commands is as follows:
<CODE>
public String getRidOfTrailingSlash(String s) {
if (s.equals("/")) return "";
int len = s.length();
String end = s.substring(len - 1);
if (end.equals("/")) s = s.substring(len - 2);
return s;
}
public List makeFileList(Enumeration names, String[] cmds) {
int i,s,cmdtype;
String c;
List l = new List(current_name, List.EXCLUSIVE);
while (names.hasMoreElements()) {
c = (String) names.nextElement();
l.append(c, null);
}
s = cmds.length;
for (i=0; i<s; i++) {
c = cmds[i];
if (c.equalsIgnoreCase("Exit")) {
cmdtype = Command.EXIT;
} else
if (c.equalsIgnoreCase("Up Dir")) {
cmdtype = Command.BACK;
} else {
cmdtype = Command.BACK;
}
// I've also tried using ITEM, OK, and one or two other
// command types for the default. Same effect.
l.addCommand(new Command(c, cmdtype, 1));
}
return l;
}
private void showDirs() {
String commands[] = { "Enter", "Up Dir", "Create", "Delete", "Exit" };
mainscreen = makeFileList(dirlist, commands);
mainscreen.setCommandListener(this);
Display.getDisplay(this).setCurrent(mainscreen);
}
</CODE>
My current issue is that the commands are not all being executed. "Exit" and "Up Dir" are working properly. However, the other three commands don't function at all in the Emulator. They show up in the menus, but selecting them does absolutely nothing when they should be routing the program flow through the System.exit() calls. If I select any of these any number of times, "Up Dir" and "Exit" still work afterward. Furthermore, the select function in the file list doesn't do anything either.
On the phone that I'm writing this for (An LG Rumor Reflex), the select function (checking and unchecking items in the list) works, as do the commands "Create", "Delete", "Up Dir", and "Exit". However, the "Enter" command doesn't even appear in the menu!
What am I doing wrong, and why the different behavior on the phone versus the Emulator?

Converting from UITextField to Int failure

I cannot convert the UITextField to an Int, although I have taken a look at the instructions on the internet. I'm a beginner with Swift 2. Can anyone help?
import UIKit
class ViewController: UIViewController {
#IBOutlet var age: UITextField!
#IBOutlet var resultLabel: UILabel!
#IBAction func findAge(_ sender: AnyObject) {
// Changed "enteredAge = age" to "enteredAge = age!"
var age = Int = Int(age.text)
var enteredAge = Int(age)
if enteredAge != nil {
var catYears = enteredAge! * 7
resultLabel.text = "Your cat is \(catYears) in cat years"
} else {
resultLabel.text = "Please enter a number in the box"
}
}
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.
}
}
Entered age use age.text again as in age variable
As I see in your code you are redeclaring the age textfield , I am editing you IBAction . I have not run this code , but I think It will work for you . Just copy paste in your code any check it .
#IBAction func findAge(_ sender: AnyObject) {
var ageToInt = Int(self.age.text!)!
if ageToInt != nil {
var catYears = ageToInt! * 7
resultLabel.text = "Your cat is \(catYears) in cat years"
} else {
resultLabel.text = "Please enter a number in the box"
}
}
Good luck!

Resources