Swift property wrappers initilaization error - ios

I am trying to use PropertWrapper for email validation. But when i try to initialize the eamilId varaible with empty string i am getting error : Incorrect argument label in call (have 'wrappedValue:', expected 'emailId:')
Here is the code of My view controller
class ViewController: UIViewController {
var name: String = ""
#EmailWrapper var emailId: String = ""
override func viewDidLoad() {
super.viewDidLoad()
name = "User Name"
emailId = "user123#gmail.com"
updateUserDetails()
}
func updateUserDetails() {
if name.isEmpty || emailId.isEmpty {
print("Please enter valid Name and emailId")
}
else {
print("User data updated successfully")
}
}
}
And the code for my property wrapper is
#propertyWrapper
struct EmailWrapper {
private var value = ""
var wrappedValue: String {
set {
value = newValue
}
get {
return isValidEmail(value) ? value : ""
}
}
init(emailId: String) {
self.value = emailId
}
private func isValidEmail(_ email: String) -> Bool {
let emailRegEx = "[A-Z0-9a-z._%+-]+#[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
let emailPred = NSPredicate(format:"SELF MATCHES %#", emailRegEx)
return emailPred.evaluate(with: email)
}
}
How can I initialize the emailId with default value (String()) in ViewController while using the EmailWrapper

When you apply a property wrapper:
#EmailWrapper var emailId: String = ""
the Swift compiler actually generates a call to the initialiser to the initialiser of the property wrapper like this:
EmailWrapper(wrappedValue: "")
However, EmailWrapper doesn't have such an initialiser. Its only initialiser has the argument label emailId: instead.
To fix this, you just need to change the argument label of the initialiser:
init(wrappedValue: String) {
self.value = wrappedValue
}

Related

Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) in project

I just started Swift and I am having problems.
I want pagination, and I coded this.
model:
struct MoreListAppand {
var MoreNoticeListModel : [MoreNoticeListModel] = []
mutating func addTask(task: MoreNoticeListModel){
MoreNoticeListModel.append(task)
}
}
struct MoreNoticeListModel {
var pageInfo : PageInfoFragmentModel? = nil
var totalCount : Int = 0
var edges: [NoticeInfoModel] = []
mutating func map(MoreNoticeListModel item: NoticeList){
self.pageInfo = nil
let pageData = item.pageInfo
var pageModel = PageInfoFragmentModel()
pageModel.map(item: pageData.fragments.pageInfoFragment)
self.pageInfo = pageModel
self.totalCount = item.totalCount
print("NoticeList totalCount == ", self.totalCount)
self.edges.removeAll()
for edge in item.edges! {
var edgeModel = NoticeInfoModel()
edgeModel.map(NoticeInfoModel:(edge?.fragments.edgesInfoFragment)!)
self.edges.append(edgeModel)
}
}
}
struct PageInfoFragmentModel {
// var hasNextPage : Bool << If I do not comment, an error will appear.(Missing argument for parameter 'hasNextPage' in call)
// var hasPreviousPage : Bool
var startCursor : String = ""
var endCursor : String = ""
mutating func map(item:PageInfoFragment) {
// self.hasNextPage = item.hasNextPage
// self.hasPreviousPage = item.hasPreviousPage
self.startCursor = item.startCursor
self.endCursor = item.endCursor
}
}
struct NoticeInfoModel {
var cursor : String = ""
var id : String = ""
var type: noticeType = .URGENT
var title: String = ""
var createdAt: String = ""
mutating func map(NoticeInfoModel item: EdgesInfoFragment){
self.cursor = item.cursor
self.id = item.node.id
self.type = noticeType(rawValue: item.node.type.rawValue)!
self.title = item.node.title
self.createdAt = item.node.createdAt
print("NoticeList title == ", self.title)
print("NoticeList type == ", self.type)
}
}
and
#objc func myAction(_ sender : AnyObject) {
//sever connect
MoreAPI.shared.getNoticeList(first: 10, last: 0, offset: 0, after: "MjAxNy0xMi0wNVQxNzo1MDozMVo=", before: ""){
[unowned self] (noticeItemLists) in
self.noticeAddListDataModel?.addTask(task: noticeItemLists)
let indexPath:IndexPath = IndexPath(row:((self.noticeAddListDataModel?.MoreNoticeListModel.count)!), section:0) << this is error line
self.noticeListTable.reloadData()
}
}
self.noticeAddListDataModeldefined here
class MoreNoticeViewController: UIViewController {
var noticeAddListDataModel : MoreNoticeListModel? = nil
}
why PageInfoFragmentModel want "hasNextPage" parameter argument..?
I got error
"let indexPath:IndexPath = IndexPath(row:((self.noticeAddListDataModel?.MoreNoticeListModel.count)!), section:0)" line.
I do not know why I get this error....
The error Missing argument for parameter 'hasNextPage' in call states that you have a variable defined in the struct and not initialized. Since it is not initialized, you have to pass its value in the constructor call,i.e. where you are calling PageInfoFragmentModel(), you have to call PageInfoFragmentModel(hasNextPage: ). This constructor is defined by default by swift, if no constructor is defined. So to remove the bug, either you give it a value or make it an optional or pass its value in initialization. Read this : https://docs.swift.org/swift-book/LanguageGuide/Initialization.html for more info.
Follow naming convention, which is for variables camelCase.
struct MoreListAppand {
var MoreNoticeListModel : [MoreNoticeListModel] = []
mutating func addTask(task: MoreNoticeListModel){
MoreNoticeListModel.append(task)
}
}
here var var MoreNoticeListModel is Struct name, change it to var moreNoticeListModel.
1. why PageInfoFragmentModel want "hasNextPage" parameter argument..?
That is a model written by someone who added that variable that is why it is there, we won't be able to tell about that. If there is no use of those variables comment them.
2.
noticeAddListDataModel doesn't have any reference to MoreNoticeListModel instead it is of same type, you can't get count property from a model.
Maybe this is what you need ? self.noticeAddListDataModel?.totalCount or self.noticeAddListDataModel?.edges.count.

String initializer for optional primitive types: Int? Double? Float? etc

Is it possible to have an extension for all of the above types without specifying each type individually?
For example, here is such extension for Double:
extension String {
init?(_ value: Double?) {
if let nonOpt = value {
self.init(nonOpt)
} else {
return nil
}
}
}
let nonOpt: Double = 1
let opt: Double? = 1
let string = String(opt)
print(string)
I'd like to allow string initialization with optional type if it is possible to initialize string with the original type.
Do you mean something like this
extension String {
init?<T : CustomStringConvertible>(_ value : T?) {
guard let value = value else { return nil }
self.init(describing: value)
}
}
or
extension String {
init?<T : LosslessStringConvertible>(_ value : T?) {
guard let value = value else { return nil }
self.init(value)
}
}
Rather than declaring an custom initializer, just use map to map the value to a String as such:
let optDouble: Double? = nil
let optionalDoubleString = opt.map { String($0) }
let optInt: Int? = nil
let optionalIntString = opt.map { String($0) }

UserDefaults saving array of dictionaries

I'm trying to save dictionary into UserDefaults And then I want to fetch data or delete.
class userDefaultsManager {
static func getAllUsers()->[UserModel]{
if let all = UserDefaults.standard.array(forKey: "usersKey") as? [Dictionary<String,Any>] {
return all.map{UserModel.init(dictionary: $0)}
}
return []
}
static func insertUser(name:String, email:String)->Bool {
let newUserModel = UserModel.init(name: name, email: email)
var all = getAllUser()
all.append(newUserModel)
UserDefaults.standard.set(all.map{$0.dictionary}, forKey: "usersKey")
return UserDefaults.standard.synchronize()
}
static func deleteUser(email:String)->Bool {
var all = getAllUser()
let index = all.index{$0.email == email}
if index != nil {
all.remove(at: index!)
UserDefaults.standard.set(all.map{$0.dictionary}, forKey: "usersKey")
UserDefaults.standard.synchronize()
return true
} else {
return false
}
}
}
class UserModel:NSObject{
var name: String!
var email: String!
init(name:String, email:String) {
self. name = name
self. email = email
super.init()
}
init(dictionary:[String:Any]) {
self.name = ""
self.email = ""
super.init()
self.setValuesForKeys(dictionary)
}
var dictionary:[String:Any] {
return self.dictionaryWithValues(forKeys: ["name","email"]) //Error here
}
}
The code working on swift 3 but I got error with swift 4 on var dictionary:[String:Any]
here is the error:
implicit Objective-C entrypoint -[Myapp.UserModel name] is
deprecated and will be removed in Swift 4
Please any help to fix this will be appreciated.
Your classes inherited from NSObject, and using objc KVC, it was fine for Swift3, because Swift3 assumed all NSObject subclasses as #objc by default, in Swift4 you need to declare your accessors #objc to make them available for obj-c KVC operations.
https://forums.developer.apple.com/thread/81789

Social network app gives error on a return line

I was finalizing my social media application and I am consistently having the same error regarding the "username" of my user during the launch process of the application (app is running, user is logged in, and the next view controller fails to come up and it crashes giving EXC_BAD_INSTRUCTION).
I was thinking it might be adata base problem as I had that with the the profile picture, however, the user name is in the database registered as a user with its email and password.
The code of the section the error is in:
import Foundation
import Firebase
import FirebaseDatabase
class Post {
private var _username: String!
private var _userImg: String!
private var _postImg: String!
private var _likes: Int!
private var _postKey: String!
private var _postRef: DatabaseReference!
var username: String
{
return _username
}
var userImg: String
{
return _userImg
}
var postImg: String {
get {
return _postImg
} set {
_postImg = newValue
}
}
var likes: Int {
return _likes
}
var postKey: String {
return _postKey
}
init(imgURl: String, likes: Int, username: String, userImg: String) {
_likes = likes
_postImg = imgURl
_username = username
_userImg = userImg
}
init(postKey: String, postData: Dictionary<String, AnyObject>){
_postKey = postKey
if let username = postData["username"] as? String {
_username = username
}
if let userImg = postData["userImg"] as? String {
_userImg = userImg
}
if let postImg = postData["imageUrl"] as? String{
_postImg = postImg
}
if let likes = postData["likes"] as? Int {
_likes = likes
}
_postRef = Database.database().reference().child("posts").child(_postKey)
}
func adjustLikes(addLikes: Bool) {
if addLikes {
_likes = likes + 1
} else {
_likes = likes - 1
}
_postRef.child("likes").setValue(_likes)
}
}
the line where the error occurs:
return _username
I am just really puzzled what the issue could be. I have looked at all the IBOutlets, as well as removing and adding new users. I would appreciate any help.
In the init(postKey:postData:) constructor it's not guaranteed that the _username property will be set. However, the public username property is of a non-optional type String. My assumption is that the username getter tries to forcefully unwrap a nil value.
Your username variable is a computed read only property which is returning value from variable _username:String!(Forced unwrapped value means can not be nil else crash ) .You need to be sure that your variable is not nil.
example when _username is not nil-:
class Foo{
var _username:String = "tushar"
var username: String
{
return _username
}
}
var object = Foo()
print(object.username)
Example when your variable can get nil value-:
class Foo{
var _username:String!
var username: String
{
print(_username)
return _username
}
}
var object = Foo()
print(object.username)
If variable has no value in it that's a crash

iOS - Swift and Parse error regarding Optionals within Subclass

I have implemented a Parse subclass called Filler.swiftthat contains five variables that are held in the Parse backend.
Whilst trying to save data to the Parse backend using this subclass I get the error: fatal error: unexpectedly found nil while unwrapping an Optional value.
This is the code that brings about the error (on the self.object.username = username line):
if let username = PFUser.currentUser()?.username {
// set username equal to current user
self.object.username = username
}else{
println("PFUser.currentUser()?.username contained a nil value.")
}
I've figured out that it's something to do with how I'm handling optional variables in my subclass but the Parse documentation isn't clear on exactly how to do this. Here's my code for the subclass:
class Fillup : PFObject, PFSubclassing {
var amount : String? {
get {
return self["amount"] as? String
}
set{
self["amount"] = newValue
}
}
var cost : String? {
get {
return self["cost"] as? String
}
set{
self["cost"] = newValue
}
}
var date : NSDate {
get {
return self["date"] as! NSDate
}
set{
self["date"] = newValue
}
}
var username: String? {
get{
return self["username"] as? String
}
set {
self["username"] = newValue
}
}
var id : Int?{
get {
return self["id"] as? Int
}
}
override class func initialize() {
var onceToken : dispatch_once_t = 0;
dispatch_once(&onceToken) {
self.registerSubclass()
}
}
class func parseClassName() -> String {
return "Fillup"
}
}
Any help would be really appreciated.
Did you try adding a ? like so:
self.object?.username = username

Resources