Application crashed while downloading SVGImage using SDWebImageSVGCoder - ios

I'm using SVG image in my project which is coming from API, as I know there's no direct method to use,load or download SVG image directly into iOS Swift app So I'm using third party library which is SDWebImageSVGCoder. But I'm facing two issues, First app is crashing while download specific image and second it's written in Objective-C. I'm not good in Objective-C so I tried alot to understand about the issue and I also tried some other libraries but they also not helping. I need help because I'm stuck there and app is crashing everytime and I have no clue. Thanks
Here's my code
import SDWebImageSVGCoder
#main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let SVGCoder = SDImageSVGCoder.shared
SDImageCodersManager.shared.addCoder(SVGCoder)
return true
}
}
import UIKit
import SDWebImageSVGCoder
struct Bank:Decodable {
var icon: String?
var name: String?
}
class ViewController: UIViewController {
var banks: [Bank] = [Bank(icon: "https://identity.moneyhub.co.uk/bank-icons/virgin", name: "Virgin Money")]
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
setupTableView()
}
func setupTableView() {
self.tableView.delegate = self
self.tableView.dataSource = self
}
}
//MARK: - TABLEVIEW DELEGATE DATASOURCE
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return banks.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: BankTableViewCell.identifier, for: indexPath) as! BankTableViewCell
cell.configure(self.banks[indexPath.row])
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 62
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
}
class BankTableViewCell: UITableViewCell {
#IBOutlet weak var bankNameLabel: UILabel!
#IBOutlet weak var bankLogoImageView: UIImageView!
class var identifier: String {
return "BankTableViewCell"
}
func configure(_ bank: Bank) {
self.bankNameLabel.text = bank.name
guard let url = URL(string: bank.icon ?? "") else {return}
bankLogoImageView.sd_imageIndicator = SDWebImageActivityIndicator.gray
bankLogoImageView.sd_setImage(with: url)
}
}
I want to find out why this library is crashing I posted question on pod Github but they're not responding. Kindly give me any suggestion, solution or alternative library which I can use and solve my problem. Thanks

You are using an outdated library that is not supported anymore. To resolve the crash you will need to use SDWebImageSVGNativeCoder. It can be downloaded here:
https://github.com/SDWebImage/SDWebImageSVGNativeCoder

Related

ios swift tableview not showing custom cells

I am trying to create a table view with custom cells from Storyboard layout in an iOS app.
But for some reason the table cells are not being shown. When I tried to set debug breakpoints I found that the debugger is reaching this function
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
but it never reaches this function -
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
Here is my viewcontroller code -
extension NavigationViewController: UITableViewDataSource, UITableViewDelegate, SideMenuControllerDelegate {
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SideMenuTableItem", for: indexPath as IndexPath) as! SideMenuTableItem
cell.setItemData(items[indexPath.row])
return cell
}
public func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func setupTableViews() {
menuTable.register(SideMenuTableItem.self, forCellReuseIdentifier: "SideMenuTableItem")
}
}
class SideMenuTableItem: UITableViewCell {
#IBOutlet weak var menuImage: UIImageView!
#IBOutlet weak var menuLabel: UILabel!
var data: MenuItem?
override func awakeFromNib() {
super.awakeFromNib()
}
func setItemData(_ item: MenuItem) {
data = item
menuLabel.text = data?.title
if data?.icon_res != nil {
menuImage.image = UIImage(named: (data?.icon_res)!)
}
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
I have checked in the storyboard that I have set the reusable identifier to the table prototype cell and also connected the datasource and the delegate properties to the tableview
and I am calling the setupTableViews() method inside my viewDidLoad() function after creating the items array
But still I am not able to get the cells to appear in my view at all.
Can anyone suggest what am I missing here or what's wrong with my code, or how can I further debug this issue
import UIKit
import SideMenuSwift
class NavigationViewController: UIViewController {
#IBOutlet weak var navigationContainer: UIView!
#IBOutlet weak var emailButton: UIButton!
#IBOutlet weak var phoneButton: UIButton!
#IBOutlet weak var userAvatar: UIImageView!
#IBOutlet weak var userProfile: UIButton!
#IBOutlet weak var userName: UILabel!
#IBOutlet weak var menuTable: UITableView!
var service: AuthenticationService!
var cdc: CoreDataController!
var items: [MenuItem] = []
var currentUser: User?
override func viewDidLoad() {
super.viewDidLoad()
setupSidebar()
initSidebarData()
setupUserHeader()
setupTableViews()
}
func setupUserHeader() {
if currentUser != nil {
if currentUser?.name != nil {
userName.text = currentUser?.name
} else if currentUser?.role != nil {
userName.text = "urTutors " + (currentUser?.role ?? "")
}
if currentUser?.avatarUrl != nil {
userAvatar.downloaded(from: (currentUser?.avatarUrl)!)
}
}
}
func initSidebarData() {
service = AuthenticationServiceProvider()
cdc = CoreDataController()
items = cdc.getNavigationData()
currentUser = cdc.getUserData()
}
func setupSidebar() {
self.view.backgroundColor = UIColor.hexColor("#fff")
navigationContainer.backgroundColor = UIColor.hexColor("#2a2a2a")
SideMenuController.preferences.basic.statusBarBehavior = .hideOnMenu
SideMenuController.preferences.basic.position = .above
SideMenuController.preferences.basic.direction = .left
SideMenuController.preferences.basic.enablePanGesture = true
SideMenuController.preferences.basic.menuWidth = 275
sideMenuController?.delegate = self
}
static func createViewController() -> NavigationViewController {
let sb = UIStoryboard(name: "StudentHomeModuleStoryboard", bundle: nil)
let vc = sb.instantiateViewController(withIdentifier: "NavigationViewController")
return vc as! NavigationViewController
}
}
--UPDATE--
updated setupTableLayout function -
func setupTableViews() {
let bundle = Bundle(for: type(of: self))
let cellNib = UINib(nibName: "SideMenuTableItem", bundle: bundle)
menuTable.register(cellNib, forCellReuseIdentifier: "SideMenuTableItem")
menuTable.register(SideMenuTableItem.self, forCellReuseIdentifier: "SideMenuTableItem")
menuTable.reloadData()
}
After breaking into chat on this, we found that there were two issues.
The first issue was the missing reloadData call mentioned above. That was causing cellForRow to not be called. Adding reloadData corrected that issue, but then the custom cell class's outlets were nil, causing a crash in setItemData.
The second issue was that register(_:forCellReuseIdentifier:) was being called in code, but the custom cell was already setup as part of the Interface Builder UITableView declaration. Calling register again on the custom class re-registered the reuseIdentifier, disconnecting the outlets set up in the storyboard.
Removing the register call and adding reloadData solved all issues.
You are never calling setupTableViews(). You'r code should look like this:
class NavigationViewController: UIViewController, SideMenuControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
setupTableViews()
}
func setupTableViews() {
menuTable.reloadData()
}
}
extension NavigationViewController: UITableViewDataSource, UITableViewDelegate {
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SideMenuTableItem", for: indexPath as IndexPath) as! SideMenuTableItem
cell.setItemData(items[indexPath.row])
return cell
}
public func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
}
You are never calling the function, nor calling viewDidLoad. This should help. Also, where is the rest of your view controller code (is this all of it? It should not be!).
You don't need to register your cell because you requested it and make sure you reloadData().
Hope this helps!

Can't pass data via segue

I make app with news feed which has to open on other ViewController. But can't pass data via segue.
Viewcontroller with newsfeed
class SecondViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var titlenews = ""
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "newsfeedCell", for: indexPath) as! NewsFeedCell
cell.newsfeed_title.text = self.news?[indexPath.item].headline
cell.newsfeed_topic.text = self.news?[indexPath.item].topic
cell.newsfeed_time.text = timetime(from: (self.news?[indexPath.item].time)!)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("tableview")
let vc = storyboard?.instantiateViewController(withIdentifier: "newsBody") as? NewsBody
vc?.labeltext = (self.news?[indexPath.item].headline)!
print((self.news?[indexPath.item].headline)!)
self.navigationController?.pushViewController(vc!, animated: true)
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.news!.count
} //number of rows
#IBOutlet weak var tableview: UITableView!
var news: [Newsfeed]? = []
override func viewDidLoad() {
super.viewDidLoad()
getJSON()
}
func getJSON(){
///Here all do right
}
}
Viewcontroller which has to receive data from news feed
class NewsBody: UIViewController {
#IBOutlet weak var testLabel: UILabel!
var labeltext = ""
override func viewDidLoad() {
super.viewDidLoad()
print(labeltext)
testLabel.text = labeltext
}
}
print(labeltext) shows that NewsBody receive empty value or nothing.
But print((self.news?[indexPath.item].headline)!) inside of SecondViewController shows that I try to push proper value.
What I do incorrect between this actions? What wrong with segue and pass of data?
It seems that instantiateViewController(withIdentifier: "newsBody") triggers view load under the hood. It should not (in theory) but it might do just that in your case.
This means that viewDidLoad() will be called before the vc?.labeltext = (self.news?[indexPath.item].headline)! is executed.
I'd recommend you to do the following.
class NewsBody: UIViewController {
#IBOutlet weak var testLabel: UILabel!
var labeltext: String? {
didSet { updateUI() }
}
override func viewDidLoad() {
super.viewDidLoad()
updateUI()
}
private func updateUI() {
testLabel.text = labeltext
}
}
This way if you set the labeltext property after the view is loaded, it will still trigger the UI update. And if you set the labeltext property before the view is loaded, as soon as viewDidLoad() is called.
BTW, you are not using segues here. But even if you do, you can easily use the same method as I proposed, because it allows you to stop thinking about whether property updates will update the UI.
Also please note that I made the property optional. It will allow you to avoid force casts and just do
vc?.labeltext = self.news?[indexPath.item].headline
UILabel.text is also an optional String property, so they will play well together.

Swift 3 pass the cell data A view to B view, with fun didSelectRowAt indexPath crash after select row

I want to pass the data A view to B view, it can build and show data in A view, but after I selected the cell, it crashed. And it shows the problem on the code.
vcTwo.selectedzones.zones = [selectedCity]
fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)
my code
The struct mode:
struct Location {
var city: String!
var zones = [String]()
}
var city = ["KHT", "TPAP", "TNNY"]
let kh = Location.init(city: "KHT", zones: ["sami", "zami", "zomi", "komi", "shini"])
let tpa = Location.init(city: "TPAP", zones: ["mid", "east", "anci", "zochi"])
let tnn = Location.init(city: "TNNY", zones: ["TN1","TN2", "TN3", "TN4", "TN5"])
Here is the A viewController code:
import UIKit
class FirstViewTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return city.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! FirstCell
cell.firstLabel.text = city[indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedCity = city[indexPath.row]
let vcTwo = self.storyboard?.instantiateViewController(withIdentifier: "secondVC") as! secondViewController
vcTwo.selectedzones.zones = [selectedCity]
self.navigationController?.pushViewController(vcTwo, animated: true)
}
}
The B viewController:
import UIKit
class secondViewController: UITableViewController {
var selectedzones: Location!
override func viewDidLoad() {
super.viewDidLoad()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return selectedzones.zones.count
}
Is there any part wrong in the func didSelectRowAt indexPath?
here is the problem
vcTwo.selectedzones.zones = [selectedCity]
you need to init the selectedZone in first Controller
let kh = Location.init(city: "KHT", zones: ["sami", "zami", "zomi", "komi", "shini"])
vcTwo.selectedzones = kh
Try this
class secondViewController: UITableViewController {
var selectedzones = Location()
}
you are try to accesss zones but you have not allocate Location so it will crash.
Hope it will help you
Instead of Optional ! use Optional ?
class secondViewController: UITableViewController {
var selectedzones: Location?
NOT
class secondViewController: UITableViewController {
var selectedzones: Location!

swift - Method does not override any method from its superclass & 'UITableView' does not have a member named 'viewDidLoad'

I am very new to swift and when I say new, I mean I just started this morning, I am having an issue I tried googling for but can't seem to find a solution.
I have this swift file:
import UIKit
class ProntoController: UITableView {
var tableView:UITableView?
var items = NSMutableArray()
override func viewDidLoad() {
super.viewDidLoad()
}
func viewWillAppear(animated: Bool) {
NSLog("Here")
let url = "API.php"
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)!) { data, response, error in
NSLog("Success")
}.resume()
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("CELL") as? UITableViewCell
return cell!
}
}
My problem is with this section of code:
override func viewDidLoad() {
super.viewDidLoad()
}
I get these two errors:
'UITableView' does not have a member named 'viewDidLoad'
Method does not override any method from its superclass
You need to subclass UITableViewController, you're subclassing UITableView

Swift UITableView works in simulator but i'm facing an error when i run it on device

This is my code creating a UITableView using storyboard hten i update my ViewController.swift file like this. Its working fine in when i run it in simulator, but i an facing an error at the time of i run it in my device
ViewController.swift
import UIKit
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var tableViewObject: UITableView!
var foodNames: [String] = ["Food1","Food2","Food3","Food4","Food5","Food6","Food7","Food8"];
var foodImages: [String] = ["image1", "image2", "image3","image4","image5","image6","image7","image8"];
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return foodNames.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell:UITableViewCell=UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "mycell")
cell.textLabel.text = foodNames[indexPath.row]
var image : UIImage = UIImage(named: foodImages[indexPath.row])!
cell.imageView.image = image
cell.imageView.sizeToFit()
return cell
}
override func viewDidLoad()
{
super.viewDidLoad()
}
}
I am facing this error shown below
From your loge: dylib library not loaded libSwiftCore.
This means that you have issue with Frameworks(dynamic libraries).
Please check followin SO link
I think you will find which is your case.
Hope this will help.

Resources