How to get two data from FMDB and return a String combined two of them in swift? - swift3

I have two records in my database, 'FirstName and LastName and I wanna get two of them then return a FullName, showing FullNames in tableView. Using Swift3 and Xcode8.2.1, FMDB
here's the func of getFullName
func getFullName() -> String{
StudentDataBase.getInstance()
sharedInstance.database!.open()
let result : FMResultSet! = sharedInstance.database!.executeQuery("SELECT FirstName, LastName FROM Student_info", withArgumentsIn: nil)
let fullName = (result?.string(forColumn: "FirstName"))! + " " + (result?.string(forColumn: "LastName"))!
return fullName
}
sharedInstance is a global one, StudentDataBase is s singleton class:
class StudentDataBase : NSObject {
var database: FMDatabase? = nil
var pathToDB: String!
class func getInstance() -> StudentDataBase{
if((sharedInstance.database) == nil)
{
sharedInstance.database = FMDatabase(path: Utility.getPath("data.db"))
}
return sharedInstance
}
and my Student.swift goes like this:
import UIKit
//the model class to fetch the data from data.db
class Student : NSObject {
var studentID: String = String()
var fstName: String = String()
var lstName: String = String()
var phoneNum: String = String()
}
I got a thread goes like this enter image description here
Thank you so much if anyone can help
After editing the Query into
let result : FMResultSet! = sharedInstance.database!.executeQuery("SELECT ifnull(FirstName,'') as FirstName, ifnull(LastName,'') as LastName FROM Student_info", withArgumentsIn: nil)
There's another error in combining them into one String:
enter image description here

You are getting this crash because either you are getting nil for FirstName or LastName, and you can use ifnull with your select query and return empty string if it is nil. So change your query like this way.
let result : FMResultSet! = sharedInstance.database!.executeQuery("SELECT ifnull(FirstName,'') as FirstName, ifnull(LastName,'') as LastName FROM Student_info", withArgumentsIn: nil)
Note: You haven't added WHERE clause with query so that this will give you all the records form Student_info table also it is batter if you check result.next() to confirm result contains records or not.

Related

how to filter list object by using stream map filter in java

i want to filter a list of student in java. I have a student class in kotlin like this.
class Student(
var id: String? = null,
var firstName: String? = null,
var lastName: String? = null
) {
constructor(entity: StudentCourse?): this() {
if (entity != null) {
this.id = entity.id.id
this.name = entity.name
}
}
}
class StudentCourse (#EmbeddedId open var id: StudentCourseId) {
constructor() : this(StudentCourseId())
open var name: Boolean? = null
}
#Embeddable
open class StudentCourseId: Serializable {
open var id: String? = null
open var deptName: String? = null
}
this is the list i want to filter :
var students: List<Student> = listOf(
Student("14adbv45", "dan", "GEG"),
Student("96adbv42","Bob", "Bowyer"),
Student("30adbv45","Emily", "Eden")
)
I do this
List<students> studentListContainsFirstNameBob = students.stream()
.map(StudentCourse)
.filter(e -> e.getFirstName.equals("Bob"))
.flatMap(List::stream);
but it doesn't work.
How can i do it please
There are multiple issues in your code.
For example in this part:
constructor(entity: StudentCourse?): this() {
if (entity != null) {
this.id = entity.id.id
this.name = entity.name
}
}
The entity.name refers to StudentCourse#name, but this property is actually of Boolean type, so comparing it to String doe snot make much sense. You have also doubled .id which is incorrect.
Next thing, I am not sure what this snipped should do, was the intention to link a student with given course? If so, you would probably like to add a list of students to a course, or a list of courses to a student (which sounds more correct).
Finally, when it comes to filtering a list, you can get students with first name Bob in this way:
var studentListContainsFirstNameBob: List<Student> = students
.filter { it.firstName.equals("Bob") }
.toList()
Mind the it variable refers to the element from the list, it could also be written:
var studentListContainsFirstNameBob: List<Student> = students
.filter { student -> student.firstName.equals("Bob") }
.toList()

How to get the KeyValue from QueryString and return string in specific string format

I am a newbie and need help.
I need to create a baseString from the below QueryString.
This baseString will look something like this in the end:
&ap=裕廊坊 心邻坊&oq=c# nunit mac&q=c# nunit mac
QueryString :
HTTPS://www.sky.com/api/v1/rest/level2/in-in/?q=c%23+nunit+mac&oq=c%23+nunit+mac&ap=裕坊%20邻坊
Problem:
How to get the KeyValue from the above QueryString
1) By getting all the components separated by "&" like below
--Keyvalue from the Query String:
q=c%23+nunit+mac&oq
oq=c%23+nunit+mac
ap=裕坊%20邻坊
I would use struct as I need to call the static func:
struct BaseString {
static func createBaseString(authPrefix,signMethod,urlPath,nonce, timestamp,delimeter="&", bool sort= true, bool quote = false) -> String? {
var dict = [String:String]()
let url = NSURL(string: urlPath)
var keyValues = url.query?.componentsSeparatedByString("&")
//-(1)- adding keyValue into Dictinary
dict.??
//-- how to add the data below?
//- after (1) : Add other key value into same Dictionary
dict Add(authPrefix + "_timestamp", timestamp);
dict.Add(authPrefix + "_nonce", nonce);
dict.Add(authPrefix + "_signature_method", signMethod);
dict.Add(authPrefix + "_version", "1.0");
var return_format:String
if quote == true{
//-- create a baseString
sort the Dictionary
return_format = "&" + url + "&" +Dictionary.ToString()
(format: String = "q ="V1" " the value with double quote)
}else{
//-- create a baseString
sort the Dictionary
return_format = Dictionary.ToString()
(format:Strig = " q=v2")
}
var baseString = return_format
return baseString
}
}
Thanks. your help is much appreciated.
You can get Key-Value dictionary from your URL's query items with the help of URLQueryItem class, like this
let urlString = "https://www.sky.com/api/v1/rest/level2/in-in/?q=c%23+nunit+mac&oq=c%23+nunit+mac&ap=裕坊%20邻坊"
let encodedUrlString = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
let items = URLComponents(string: encodedUrlString)?.queryItems
var keyValues: [String: String] = [:]
items?.forEach{
item in
keyValues[item.name] = item.value
}
print(keyValues)
//["q": "c%23+nunit+mac", "ap": "裕坊%20邻坊", "oq": "c%23+nunit+mac"]
Hope this will help you.
If you need to obtain Query substring from your url string, you need to create URL from it and get query.
guard let url = URL(string: encodedUrlString) else {
fatalError()
}
let queryString = url.query!
print(queryString.removingPercentEncoding)
//q=c%23+nunit+mac&oq=c%23+nunit+mac&ap=裕坊%20邻坊
If you need to add new components to your query,
var components = URLComponents(string: encodedUrlString)
let item = URLQueryItem(name: "NEWVKEY", value: "NEWVALUE")
components?.queryItems?.append(item)
let url = components?.url
let resultString = url?.absoluteString
//or
let resultString2 = url?.absoluteString.removingPercentEncoding
The idea is to use URL processing abilities of Swift standard library. Please check the documentation of URL, URLComponents, URLQueryItem structs. Don't write string processing code, manipulate URLs instead.
https://developer.apple.com/documentation/foundation/url
https://developer.apple.com/documentation/foundation/urlcomponents
https://developer.apple.com/documentation/foundation/urlqueryitem

Swift: Finding an Object Property via regex

Target: The following function shall iterate over an array of objects and check a specific property of all objects. This property is a string and shall be matched with a user input via regex. If there's a match the object shall be added to an array which will further be passed to another function.
Problem: I don't know how to set up regex in Swift 3. I'm rather new in Swift at all, so an easily understandable solution would be very helpful :)
How it currently looks like:
func searchItems() -> [Item] {
var matches: [Item] = []
if let input = readLine() {
for item in Storage.storage.items { //items is a list of objects
if let query = //regex with query and item.name goes here {
matches.append(item)
}
}
return matches
} else {
print("Please type in what you're looking for.")
return searchItems()
}
}
This is what Item looks like (snippet):
class Item: CustomStringConvertible {
var name: String = ""
var amount: Int = 0
var price: Float = 0.00
var tags: [String] = []
var description: String {
if self.amount > 0 {
return "\(self.name) (\(self.amount) pcs. in storage) - \(price) €"
} else {
return "\(self.name) (SOLD OUT!!!) - \(price) €"
}
}
init(name: String, price: Float, amount: Int = 0) {
self.name = name
self.price = price
self.amount = amount
}
}
extension Item: Equatable {
static func ==(lhs: Item, rhs: Item) -> Bool {
return lhs.name == rhs.name
}
}
Solved. I just edited this post to get a badge :D
For the purpose of letting the answer to be generic and clear, I will assume that the Item model is:
struct Item {
var email = ""
}
Consider that the output should be a filtered array of items that contains items with only valid email.
For such a functionality, you should use NSRegularExpression:
The NSRegularExpression class is used to represent and apply regular
expressions to Unicode strings. An instance of this class is an
immutable representation of a compiled regular expression pattern and
various option flags.
According to the following function:
func isMatches(_ regex: String, _ string: String) -> Bool {
do {
let regex = try NSRegularExpression(pattern: regex)
let matches = regex.matches(in: string, range: NSRange(location: 0, length: string.characters.count))
return matches.count != 0
} catch {
print("Something went wrong! Error: \(error.localizedDescription)")
}
return false
}
You can decide if the given string does matches the given regex.
Back to the example, consider that you have the following array of Item Model:
let items = [Item(email: "invalid email"),
Item(email: "email#email.com"),
Item(email: "Hello!"),
Item(email: "example#example.net")]
You can get the filtered array by using filter(_:) method:
Returns an array containing, in order, the elements of the sequence
that satisfy the given predicate.
as follows:
let emailRegex = "[A-Z0-9a-z._%+-]+#[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
let emailItems = items.filter {
isMatches(emailRegex, $0.email)
}
print(emailItems) // [Item(email: "email#email.com"), Item(email: "example#example.net")]
Hope this helped.
You can do the same with filter function
let matches = Storage.storage.items.filter({ $0.yourStringPropertyHere == input })

Parse JSON string to Model Object type Array

I got Encrypted data from API hit by below method
URLSession.shared.dataTask(with: url!)
converted data into JSON but still it is encrypted
var json = try(JSONSerialization.jsonObject(with: data!, options: .allowFragments))
converted it into string
let arr:String = json as! String
decrypted it
let jsonText = arr.fromBase64()//extension method, given end of question
now it is in Json Formate as below (this is only 1 record, there are more than 1 records in Json string)
{
"CompanyAlt_Key": 1,
"Company_Name": "XYZ LTD",
"TableName": "CompanyList"
},
I have a model of same type
public class CompanyList {
public var companyAlt_Key : Int?
public var company_Name : String?
public var tableName : String?
}
here is fromBase64 method
func fromBase64() -> String {
let data = NSData.init(base64Encoded: self, options: []) ?? NSData()
return String(data: data as Data, encoding: String.Encoding.utf8) ?? ""
}
I am facing problem to get the Json String into an array of type CompanyList class
Help would be appreciate
You'll need to convert your jsonString to data first:
let jsonData = jsonString.data(using: .utf8)!
The convert the data to an array
let array = JSONSerialization.jsonObject(with: jsonData, options: nil) as? [[String: Any]]
Then iterate through the array…
let companies = array?.map {
return CompanyList(dictionary: $0)
}
Implement an init method for your CompanyList, passing in a dictionary for each record in your response…
public class CompanyList {
public var companyAlt_Key : Int?
public var company_Name : String?
public var tableName : String?
init(dictionary: [String: Any]) {
companyAlt_Key = dictionary["companyAlt_Key"] as? Int
company_Name = dictionary["company_Name"] as? String
tableName = dictionary["tableName"] as? String
}
}
You can also use this to validate the data. If the fields in your class are non-optional, you can use an optional init as follows…
public class CompanyList {
public var companyAlt_Key : Int
public var company_Name : String
public var tableName : String
init?(dictionary: [String: Any]) {
guard let companyAlt_Key = dictionary["companyAlt_Key"] as? Int,
let company_Name = dictionary["company_Name"] as? String,
let tableName = dictionary["tableName"] as? String else {
return nil
}
self.companyAlt_Key = companyAlt_Key
self.company_Name = company_Name
self.tableName = tableName
}
}
If you're using an optional init, use flatMap to ensure you don't have any optional elements in your array…
let companies = array?.flatMap {
return CompanyList(dictionary: $0)
}

flatMap and `Ambiguous reference to member` error

Consider the following code:
typealias PersonRecord = [String : AnyObject]
struct Person {
let name: String
let age: Int
public init(name: String, age: Int) {
self.name = name
self.age = age
}
}
extension Person {
init?(record : PersonRecord) {
guard let name = record["name"] as? String,
let age = record["age"] as? Int else {
return nil
}
self.name = name
self.age = age
}
}
Now I want to create an array of Persons from an array of Records:
let records = // load file from bundle
let persons = records.flatMap(Person.init)
But I get the following error:
error: ambiguous reference to member 'init(name:age:)'
If I move the failable initializer out of the extension, I still get the same error.
What am I missing here, is this not a correct usage of flatMap?
EDIT - solved:
Found the error: the code that read in the records file from disk, returned the wrong type. Once I fixed that, the error went away.
For this to work
let persons = records.flatMap(Person.init)
the param passed to the flatMap closure must be the same type received by Person.init, so it must be PersonRecord.
Then records must be a list of PersonRecord, something like this
let records: [PersonRecord] = []
Now it works
let persons = records.flatMap(Person.init)
Most of the times the Ambiguous reference to member in a map or flatMap is because the return type isn't specified
array.flatMap({ (item) -> ObjectToReturn? in })