Swift: read string based on provided user info - ios

On Xcode (Swift) I want to load data stored on the app based on information provided by the user.
For example, the user gives the input of "Xcode":
var userInput = "Xcode"
With this information, I want to display the a stored string with the exact same name that is already on the app:
let Xcode = "Xcode is a development tool."
This is what I get when I print:
print ("Print: ", userInput) -> Print: Xcode
But I want to print the result from the string value stored from the app instead. The result I'm looking for is this:
print ("Print: ", userInput) -> Print: Xcode is a development tool.
I have to associate the input to the string stored, how can I do this without manually associating thousands of words to the strings I want to show? What is the best approach to get this result?
Thanks!
My approach where I have to do one by one is this:
switch userInput {
case Xcode: // This is the info provided by the user.
userInput = Xcode // This is the string stored on the app.
break
}
But once I have thousands of strings this approach is terrible, but works:
print ("Print: ", userInput) -> Print: Xcode is a development tool.

You have to define a data model for your information. If you have too much data, I suggest to create a JSON file where each key is the userInput with the associated value. Then you can parse the JSON file into a dictionary where you can easily retrieve the key-related value.
At this point you can define your own print method that prints the value associated with the key passed as parameter simply using object(forKey:) method.

I can't exactly understand your question. But what I've understood is to do this with Dictionary data type. Here is the sample code for this.
var str = "Hello, playground"
var responseMessages : [String : String] = ["" : ""]
if responseMessages[str] == nil
{
responseMessages[str] = str;
}
print(responseMessages[str]) // Output : Optional("Hello, playground")
You know better to remove optional keyword from string values by casting them to String data type.

Related

Cannot assign value of type 'Dictionary<String?, String?>.Keys' to type 'String'

Here I have a database, which I want to easily use for my table view. However, I can't reach the properties, because I don't know how to assign from a dictionary to a string. It tells me:
Cannot assign value of type 'Dictionary.Keys' to
type 'String'
import Foundation
struct Test {
var title: String
var tagPreview: Tagpreview
}
struct Tagpreview {
var tag: [String?:String?]
}
var cases = [
Test(title: "title1", tagPreview: Tagpreview(tag: ["tag1": "preview1"])),
Test(title: "title2", tagPreview: Tagpreview(tag: ["tag2": nil])),
Test(title: "title3", tagPreview: Tagpreview(tag: [nil: nil])),
Test(title: "title4", tagPreview: Tagpreview(tag: ["tag4": "preview4", "tag5": nil]))
]
I want to use the keys and the values from the dictionary in the second struct to populate the text labels later in a cell:
cell.titleLabel?.text = cases[indexPath.row].tag.preview.keys //ERROR
cell.textLabel?.text = cases[indexPath.row].tag.preview.values//ERROR
There is something about dictionaries that I can't find anywhere as well as a comprehensive solution for this issue.
Now, if you know another way how to populate them easily, I'd much appreciate that! Thank you a lot in advance and have a good day!
The error you are receiving is due to Dictionary.keys returning a collection of the Type you selected as key. In your case the call cases[indexPath.row].tag.preview.keys returns a Collection of String? (similar to [String?])
Now if you wish to access a specific value from this collection, you should be able to do so like this:
let someText = cases[indexPath.row].tagPreview.tag.keys.map{ $0 }[someIndex]
Note that the use of map(). It merely converts the Strings collection to an Array of Strings, whose index is Int, thus making it easier to access the individual elements (otherwise you'd need abit more general/cumbersome iteration API of Collection).
Just side comment, it seems a bit difficult to extract data and map it directly to the view, if you intend to use such mapping many places it may pay out to have some intermediate data types which are easier to use when presenting; it really depends on your preference and the overall problem.

How do I set the name a child in Firebase to user input from a text field?

Here's how I want my data tree to look in Firebase:
users:
--Travis:
------travisData:
--Stephanie:
------stephanieData:
My problem is that I can't seem to name a child using user input from a textfield.
Here's the code I have so far:
ref = Database.database().reference()
let username = String(emailTextField.text!)
//ref.child("users").setValue(["username": username])
ref.child("users").setValue(["\(username)": calendar])
The commented out line creates a child named "username" with the textfield.text as its content. But how can I create a child whose name is the textfield.text, with other data as its content? I've tried multiple combinations of using .child and .setValue, but everything keeps throwing me an error when I try to use the username variable instead of a plain string.
Here's the error I get:
Your problem is that Firebase doesn't accept the "." symbol in their user names. You would get the same problem even if you typed a string of letters with a "." such as "adfojnajsdnfjs.fjknasd" instead of "username".
I think you're looking for:
ref.child("users").child(username).setValue(calendar)
Although that depends on the value of calendar.
At the very least this should work:
ref.child("users").child(username).setValue(true)
And give you the following JSON:
"users": {
"Travis": true
}
To write a more complex structure, you can for example do:
ref.child("users").child(username).child("name").setValue(username)
Which results in:
"users": {
"Travis": {
name: "Travis"
}
}
As your require, I think this code will help you
ref.child("users").child("\(inputUsername)").updateChildValues(["travidDataKey": userData])
And
result image
users:
Travid2:
travidDataKey:"Travid Data"

ios application Localization

How can I set ios application supported languages?
e.g I use NSDate to get current day. If the device language is other than my supported languages NSDateFormatter returns "day" in device's language but I want to get in English if I don't support that language.
I know there is a way to get day in specific language using NSLocal but I don't want to do that way because I need to convert other strings as well.
The Apple documentation covers this pretty clearly. I know all you need is the word "day", but the following will help you include any word for any language if you do as follows:
1) You need to place all of the words (Strings) in your application into a single .swift file. Each word should be returned in a function that converts this string into the localized string per the device's NSLocal set in the device settings:
struct Localization {
static let all: String = {
return getLocalized("All")
}()
static let allMedia: String = {
return getLocalized("All Media")
}()
static let back: String = {
return getLocalized("Back")
}()
// ...and do this for each string
}
2) This file should also contain a static function that will convert the string:
static func getLocalized(_ string: String) -> String {
return NSLocalizedString(string, comment: "")
}
Here, the NSLocalizedString( method will do all of the heavy lifting for you. If will look into the .XLIFF file (we will get to that) in your project and grab the correct string per the device NSLocale. This method also includes a "comment" to tell the language translator what to do with the "string" parameter you passed along with it.
3) Reviewing all of the strings that you placed in your .swift file, you need to include each of those into an .XLIFF file. This is the file that a language expert will need to go over and include the proper translated word per string in the .XLIFF. As I stated before, this is the file that once included inside your project, the NSLocalizedString( method will search this file and grab the correct translated string for you.
And that's it!

F# non-literal printf format strings - how to make them passable as parameters?

I would like to use non-literal strings for the "format" parameter of a logging type function, as shown here:
// You need to make c:\testDir or something similar to run this.....
//
let csvFile = #"c:\testDir\foo.csv"
open System.IO
let writer file (s:string) =
use streamWriter = new StreamWriter(file, true)
streamWriter.WriteLine(s)
// s
let log format = Printf.ksprintf (writer csvFile) format
let oneString format = (Printf.StringFormat<string->string> format)
let format = oneString "(this does not %s)"
//log format "important string"
log "this works %s" "important string"
My first attempt used a literal string, and the above fragment should work fine for you if you create the directory it needs or similar.
After discovering that you can't just "let bind" a format string, I then learned about Printf.StringFormatand more details about Printf.ksprintf, but I am obviously missing something, because I can't get them to work together with my small example.
If you comment out the last line and reinstate its predecessor, you will see a compiler error.
Making the function writer return a string almost helped (uncomment its last line), but that then makes log return a string (which means every call now needs an ignore).
I would like to know how to have my format strings dynamically settable within the type checked F# printf world!
Update
I added the parameter format to log to avoid a value restriction error that happens if log is not later called as it is in my example. I also change fmt to format in oneString.
Update
This is a different question from this one. That question does not show a function argument being passed to Printf.StringFormat (a minor difference), and it does not have the part about Printf.ksprintf not taking a continuation function that returns unit.
I thought I had found a solution with:
let oneString format = (Printf.StringFormat<string->string,unit> format)
this compiles, but there is a runtime error. (The change is the ,unit)

UILexicon iOS 8 is not working as expected

I am using UILexicon for the suggestions in custom keyboard. Following is code:
-(void) keyTapped:(UIButton*)button {
[self requestSupplementaryLexiconWithCompletion:^(UILexicon *lexicon){
// self.lexicon = lexicon;
NSLog(#"%#",lexicon.entries);
for (UILexiconEntry* entry in lexicon.entries) {
NSLog(#"%#=%#",entry.userInput,entry.documentText);
}
int i=0;
}];
}
But it is returning always same array of entries. Can anyone suggest me how to use it. I will mark correct your answer if it works. Thanks.
It's working but you should implement your own function to compare the UILexiconEntry list with the entered string as stated by apple :
UILexiconEntry
A lexicon entry specifies a read-only term pair, available within a UILexicon object, for use by a custom keyboard.
You can employ a lexicon entry by matching user input against the entry’s userInput value, and then inserting into the current text input object the corresponding documentText value. For example, if the user typed the string “iphone”, the lexicon entry with that exact, case-sensitive string in the userInput property has the string “iPhone” in the corresponding documentText property.
In some cases, the documentText string is in a different text script than the userInput string.

Resources