swift convenience initializer call other convenience initializer inherit from superclass - ios

class AreaSectorLineOverlay: MKPolyline {
var id: String!
var nickName: String!
var locationName: String!
convenience init(coordinates coords: UnsafePointer<CLLocationCoordinate2D>, count: Int, id: String, nickName: String, locationName: String) {
self.init(coordinates: coords, count: count)
self.id = id
self.nickName = nickName
self.locationName = locationName
}
}
Why the code is wrong? error is ('self' used before self.init call) and at last of the function 'init(coordinates coords: UnsafePointer, count: Int, id: String, nickName: String, locationName: String)' the error is (Self.init isn't called on all paths before returning from initializer)
class A {
var a1: String!
init() {
}
convenience init(a1: String) {
self.init()
self.a1 = a1
}
}
class B: A {
var b1: String!
convenience init(a1: String, b1: String) {
self.init(a1: a1)
self.b1 = b1
}
}
let b = B(a1: "a1Test", b1: "b1Test")
print(b.a1, b.b1)
There is no error like this,and print result is (a1Test b1Test)

Related

Property 'self.readCount' not initialized at super.init call

I have the following class
// LearningItem
class LearningItem : NSObject {
var id: String
var title: String
var subtitle: String?
var image: String
var uploadDate: Int
init(id: String, title: String, image: String, uploadDate: Int) {
self.id = id
self.title = title
self.image = image
self.uploadDate = uploadDate
}
I have another class
// Book.swift
class Book: LearningItem {
var publishDate: String?
var author: String?
var mediaUrl: String?
var video : String?
var tags: [String]?
var lists: [String: AnyObject]?
var readCount: Int
var categories: [String]?
var courses: [String]?
var amazonBuyUrl: String?
var starCount: Int
var read: Bool?
var completed = [String : Int]()
var stars = [String : Int]()
var completedDate : Int?
var desc: String
var epub: String
var authorDesc: String
init(id: String, title: String, desc: String, authorDesc: String, image: String, epub: String, readCount: Int, uploadDate: Int, starCount: Int) {
super.init(id: id, title: title, image: image, uploadDate: uploadDate)
self.id = id
self.desc = desc
self.authorDesc = authorDesc
self.title = title
self.epub = epub
self.image = image
self.readCount = readCount
self.uploadDate = uploadDate
self.starCount = starCount
}
I get the error "Property 'self.readCount' not initialized at super.init call"
where I call "super.init(id: id, title: title, image: image, uploadDate: uploadDate)" in Book.swift
Class initialisation not finished until it's designated initializers
not finished with initializing all properties
and after that you can call super class's designated initializers
Designated initializers are the primary initializers for a class. A designated initializer fully initializes all properties introduced by that class and calls an appropriate superclass initializer to continue the initialization process up the superclass chain.
SO
Class initialization in Swift is a two-phase process. In the first phase, each stored property is assigned an initial value by the class that introduced it. Once the initial state for every stored property has been determined, the second phase begins, and each class is given the opportunity to customize its stored properties further before the new instance is considered ready for use.
apple docs https://docs.swift.org/swift-book/LanguageGuide/Initialization.html
so
class Book: LearningItem {
var publishDate: String?
var author: String?
var mediaUrl: String?
var video : String?
var tags: [String]?
var lists: [String: AnyObject]?
var readCount: Int
var categories: [String]?
var courses: [String]?
var amazonBuyUrl: String?
var starCount: Int
var read: Bool?
var completed = [String : Int]()
var stars = [String : Int]()
var completedDate : Int?
var desc: String
var epub: String
var authorDesc: String
init(id: String, title: String, desc: String, authorDesc: String, image: String, epub: String, readCount: Int, uploadDate: Int, starCount: Int) {
self.readCount = readCount
self.starCount = starCount
self.desc = desc
self.epub = epub
self.authorDesc = authorDesc
super.init(id: id, title: title, image: image, uploadDate: uploadDate)
}
}

How to fetch a nested array inside an array with Alamofire (Swift)

how one can fetch a JSON file in the following format:
https://developers.themoviedb.org/3/people/get-popular-people
Alamofire is used to fetch the data from online database.
I don't know exactly how to format the JSON file received so the nested array can have the elements saved in an instance MovieModel(poster: UIImage,
name: String,
rating: Double,
year: String,
posterLink: String,
id: Int)
ERROR: Fatal error: NSArray element failed to match the Swift Array Element type
My code looks like:
class MovieModel {
private var _poster: UIImage!
private var _background: UIImage!
private var _name: String! // original_title
private var _overview: String! // overview
private var _rating: Double! // vote_average
private var _year: String!
private var _posterLink: String!
private var _backgroundLink: String!
private var _genres: [Int]!
private var _id: Int!
init(poster: UIImage,
name: String,
rating: Double,
year: String,
posterLink: String,
id: Int){
_poster = poster
_name = name
_rating = rating
_year = year
_posterLink = posterLink
_id = id
getPosterImage()
}
}
class ActorModel {
private var _poster : UIImage!
private var _birthday : String?
private var _known_for_department : String?
private var _deathday : String?
private var _id : Int!
private var _known_for : [MovieModel]?
private var _name : String!
private var _also_known_as : [String]!
private var _gender : Int!
private var _biography : String?
private var _popularity : Double?
private var _place_of_birth : String?
private var _profile_path : String?
private var _adult : Bool!
private var _imdb_id : String!
private var _homepage : String!
init(poster : UIImage, id : Int, known_for: [MovieModel], name: String, popularity : Double, profile_path : String) {
_poster = poster
_id = id
_known_for = known_for
_name = name
_popularity = popularity
_profile_path = profile_path
getPosterImage()
}
}
func getPopularActors(){
let url = BASE_URL + "/person/popular?" + API_KEY + LANG + "&page=1"
self.actorList = []
Alamofire.request(url).responseJSON {response in
if let result = response.result.value as? Dictionary<String,Any> {
if let list = result["results"] as? [Dictionary<String,Any>] {
for i in list {
self.actorList.append(ActorModel(
poster: UIImage(),
id: i["id"] as! Int,
known_for: i["known_for"] as! [MovieModel],
name: i["name"] as! String,
popularity: i["popularity"] as! Double,
profile_path: "\(self.IMAGE_URL)\(i["profile_path"] as! String)"
))
}
if let del = self.actorDelegate {
del.transferActors(data: self.actorList)
}
}
}
}
}
You should really use Decodable for this. But building on your current solution:
for i in list {
var movieModels = [MovieModel]()
if let knownForArray = i["_known_for"] as? [[String: Any]] {
for knownFor in knownForArray {
movieModels.append(MovieModel(
poster: UIImage(),
name: knownFor["name"] as! String,
rating: knownFor["rating"] as! Double,
... //And so on
))
}
}
self.actorList.append(ActorModel(
poster: UIImage(),
id: i["id"] as! Int,
known_for: movieModels,
name: i["name"] as! String,
popularity: i["popularity"] as! Double,
profile_path: "\(self.IMAGE_URL)\(i["profile_path"] as! String)"
))
}

Initializer for conditional binding must have Optional type, not 'Date'

Xcode is yelling error
But I don't know what happen. I've been searching and I think it might be something about casting and optional. The first one gives Initializer for conditional binding must have Optional type, not 'Date' and the second and third gives Initializer for conditional binding must have Optional type, not 'Double'
for article in (topic.articleArrays ?? nil)!{
if let articleId = article.id,
let articleHeadline = article.headline,
let articleSummary = article.summary,
let articleCity = article.city,
let articleState = article.state,
let articleDateretrieved = article.dateRetrieved,
let articlePublisher = article.publisher,
let articleLatitude = article.latitude,
let articleLongitude = article.longitude,
let articleRawBaseUrl = article.rawBaseUrl,
let articleRawUrl = article.rawUrl {
editedArticles?.append(NewsArticle(id: articleId, headline: articleHeadline, publisher: articlePublisher, summary: articleSummary, rawUrl: articleRawUrl, rawBaseUrl: articleRawBaseUrl, retrieved_date: articleDateretrieved, city: articleCity, state: articleState, latitude: articleLatitude, longitude: articleLongitude))
}
}
The struct for ediedArticles is NewsArticle which I've listed below
struct NewsArticle {
var id: String
var headline: String
var publisher: String
var summary: String
var rawUrl: String
var rawBaseUrl: String
var retrieved_date: Date
var city: String
var state: String
var latitude: Double
var longitude: Double
init(id: String, headline: String, publisher: String, summary: String, rawUrl: String, rawBaseUrl: String, retrieved_date: Date, city: String, state: String, latitude: Double, longitude: Double) {
self.id = id
self.headline = headline
self.publisher = publisher
self.summary = summary
self.rawUrl = rawUrl
self.rawBaseUrl = rawBaseUrl
self.retrieved_date = retrieved_date
self.city = city
self.state = state
self.latitude = latitude
self.longitude = longitude
}
}
topic.articlesArray have different data structure type which is SavedArticle (CoreData)
var articleArrays: [SavedArticle]? {
return self.articles?.allObjects as? [SavedArticle]
}
and have SavedArticle-CoreDataClass
var dateRetrieved: Date {
get {
return retrieved_date as Date
}
set(newDate) {
retrieved_date = newDate as NSDate
}
}
// TODO: Figured it out how to stored corrdinates in [Double]
convenience init?(id: String, headline: String, publisher: String, summary: String, retrieved_date: Date, city: String, state: String, latitude: Double, longitude: Double) {
guard let context = NaberCoreDataHandler.sharedInstance.managedContext else { return nil }
self.init(entity: SavedArticle.entity(), insertInto: context)
self.id = id
self.headline = headline
self.publisher = publisher
self.summary = summary
self.dateRetrieved = retrieved_date
self.city = city
self.state = state
self.latitude = latitude
self.longitude = longitude
}
with a SavedArticle-CoreDataProperties of following
#NSManaged public var city: String?
#NSManaged public var headline: String?
#NSManaged public var id: String?
#NSManaged public var publisher: String?
#NSManaged public var rawBaseUrl: String?
#NSManaged public var rawUrl: String?
#NSManaged public var retrieved_date: NSDate
#NSManaged public var state: String?
#NSManaged public var summary: String?
#NSManaged public var latitude: Double
#NSManaged public var longitude: Double
#NSManaged public var topics: SavedTopic?
It would be awesome if someone can help me figured it out what's the problem. I've beent rying for the whole day and nothing helps. Thank you! :)
if let (and guard let) can only be used to unwrap optional values. You can either assign those values with regular let statements on a separate line, or just pass them into the function directly since they don't need to be unwrapped.
article.dateRetrieved, article.latitude, and article.longitude are not Optionals. They are not declared with ? after their type names, so they can never be nil. There is therefore no need -- and in fact it is an error -- to try to unwrap them with an "if let" statement.
Remove the three lines of code that the compiler is complaining about.
When you create the NewsArticle and append it to editedArticles, you can pass those properties of article directly to the constructor of NewsArticle.

subclass PFObject and override init

I wanted to create custom PFObject class, but it gives me a very confusing error "Property self.photo not initialized at super.init call"
here is code of my custom class :
import Foundation
import Parse
class Wish: PFObject, PFSubclassing {
var id: String?
var name: String?
var descriptionWish: String?
var photo: UIImage
var photoThumbnail: UIImage
var amount: Double?
var amountDonated: Int?
static func parseClassName() -> String {
return "Wish"
}
override init() {
super.init()
}
convenience init(id: String?, name: String?, descriptionWish: String?, photo: UIImage, photoThumbnail: UIImage, amount: Double?, amountDonated: Int?) {
self.init()
self.id = id
self.name = name
self.descriptionWish = descriptionWish
self.photo = photo
self.photoThumbnail = photoThumbnail
self.amount = amount
self.amountDonated = amountDonated
}
}
Any ideas how to make a custom initializer for this class ?
I want to call my wish class like this:
Wish(id: "123", name: "xxx", descriptionWish: "Lorem ipsum", photo: photoImage, photoThumbnail: photoImageThumbnail, amount: 22.20, amountDonated: 10)
and cast PFObject like this
let wish = myPfObject as Wish
Any help is appreciated!!!
Try updating your subclass to the following. Notice the NSManaged keywords for the Parse properties you've added to your Wish subclass and the removal of super.init()
You will probably also want to look into replacing the UIImage properties with the Parse-provided PFFile properties. You can easily store and load images using PFImageView included in the ParseUI framework.
import Foundation
import Parse
class Wish: PFObject, PFSubclassing {
// MARK: - Parse Core Wish Properties
#NSManaged var id: String?
#NSManaged var name: String?
#NSManaged var descriptionWish: String?
#NSManaged var photo: UIImage
#NSManaged var photoThumbnail: UIImage
#NSManaged var amount: Double?
#NSManaged var amountDonated: Int?
// MARK: - Lifecycle
override class func initialize() {
struct Static {
static var onceToken : dispatch_once_t = 0;
}
dispatch_once(&Static.onceToken) {
self.registerSubclass()
}
}
static func parseClassName() -> String {
return "Wish"
}
convenience init(id: String?, name: String?, descriptionWish: String?, photo: UIImage, photoThumbnail: UIImage, amount: Double?, amountDonated: Int?) {
self.init()
self.id = id
self.name = name
self.descriptionWish = descriptionWish
self.photo = photo
self.photoThumbnail = photoThumbnail
self.amount = amount
self.amountDonated = amountDonated
}
}

In Swift, how can I quickly set my instance variables?

public class User {
var id: Int
var fb_id: String?
var first_name: String?
var last_name: String?
var age: Int?
var distance: Int?
var login_at_pretty: String?
var login_at: Int?
var profile: Profile?
init(id: Int, fb_id: String?, first_name: String?, last_name: String?, age: Int?, distance: Int?, login_at_pretty: String?, login_at: Int?, profile: Profile?){
self.id = id
if let fb_id = fb_id {
self.fb_id = fb_id
}
if let first_name = first_name {
self.first_name = first_name
}
if let last_name = last_name {
self.last_name = last_name
}
if let age = age {
self.age = age
}
if let distance = distance {
self.distance = distance
}
if let login_at_pretty = login_at_pretty {
self.login_at_pretty = login_at_pretty
}
if let login_at = login_at {
self.login_at = login_at
}
if let profile = profile {
self.profile = profile
}
}
}
Is this the quickest way to do it? I feel like I'm over typing.
For your class, you're doing a lot of if-let statements that don't provide anything useful. ie:
if let fb_id = fb_id {
self.fb_id = fb_id
}
fb_id and self.fb_id are optionals, so the binding isn't necessary. Just do:
self.fb_id = fb_id
On that note however, if you're not planning on subclassing, using a struct would provide a memberwise initializer automagically:
public struct User {
var id: Int
var fb_id: String?
var first_name: String?
var last_name: String?
var age: Int?
var distance: Int?
var login_at_pretty: String?
var login_at: Int?
var profile: Profile?
}
Check out Memberwise Initializers for Structure Types in the swift docs

Resources