Stripe - single method prebuit UI, STPAPIClient.shared().publishableKey iOS Swift UiKit - ios

I followed this Doc : https://stripe.com/docs/payments/accept-a-payment?platform=ios&ui=payment-sheet
I am getting these from my backend.
"clientSecret" : "pi_3JUrPkLW44AR......7WElFl",
"stripecustomerid" : "cus_K8......pLu4",
"paymentids" : "pi_3JVA.....R9VmA"
"EphemeralKey" : "ephkey_1JV......kEtnlw"
//PaymentSheet Configuration
let clientSecret = response["clientSecret"].stringValue
let ephemeralSecret = response["EphemeralKey"].stringValue
let cusId = response["stripecustomerid"].stringValue
// MARK: Set your Stripe publishable key - this allows the SDK to make requests to Stripe for your account
STPAPIClient.shared.publishableKey = self.publishableKey
// MARK: Create a PaymentSheet instance
var configuration = PaymentSheet.Configuration()
configuration.merchantDisplayName = "Z*****"
configuration.customer = .init( id: cusId, ephemeralKeySecret: ephemeralSecret)
configuration.returnURL = "payments-example://stripe-redirect"
self.paymentSheet = PaymentSheet(
paymentIntentClientSecret: clientSecret,
configuration: configuration)
after this(payment initiation) I am getting log from stripe :
LOG ANALYTICS: ["product_usage": ["PaymentSheet"], "app_name": "Zucraz", "additional_info": [], "bindings_version": "21.8.1", "apple_pay_enabled": 0, "ocr_type": "none", "os_version": "14.4", "analytics_ua": "analytics.stripeios-1.0", "ui_usage_level": "partial", "publishable_key": "pk_test_51J9Te0LW.........tRQbRP2", "device_type": "iPhone12,1", "event": "mc_complete_init_customer", "app_version": "3.4"]
While calling this method - presenting PaymentSheet
func openPaymentSheet(){
// MARK: Start the checkout process
paymentSheet?.present(from: self) { paymentResult in
// MARK: Handle the payment result
switch paymentResult {
case .completed:
self.displayAlert("Your order is confirmed!")
case .canceled:
print("Canceled!")
case .failed(let error):
print(error)
self.displayAlert("Payment failed: \n\(error.localizedDescription)")
}
}
}
Getting this error
Error Domain=com.stripe.lib Code=50 "There was an unexpected error -- try again in a few seconds" UserInfo={NSLocalizedDescription=There was an unexpected error -- try again in a few seconds, com.stripe.lib:ErrorMessageKey=No valid API key provided. Set `STPAPIClient.shared().publishableKey` to your publishable key, which you can find here: https://stripe.com/docs/keys, com.stripe.lib:StripeErrorTypeKey=invalid_request_error, com.stripe.lib:StripeErrorCodeKey=}
There is nowhere defined in documentation to set STPAPIClient.shared().publishableKey.
still, I tried to set STPAPIClient.shared.publishableKey in my viewcontroller, still getting the error.
Thanks in advance
complete class code:
import UIKit
import SwiftyJSON
import FirebaseAnalytics
import Stripe
import PassKit
class ReviewOrderViewC: UIViewController,UITableViewDelegate,UITableViewDataSource{
#IBOutlet weak var viewForEmptyCart: UIView!
#IBOutlet weak var lblCity: UILabel!
#IBOutlet weak var lblNsmr: UILabel!
#IBOutlet weak var lblAdress: UILabel!
#IBOutlet weak var lblMobile: UILabel!
var responseData : JSON = []
#IBOutlet weak var tblReview: UITableView!
#IBOutlet weak var btnCod: UIButton!
#IBOutlet weak var btnOnlinePayment: UIButton!
#IBOutlet weak var lblApplyCoupon: UILabel!
#IBOutlet weak var viewForApplyCoupon: UIView!
#IBOutlet weak var txtCouponCode: UITextField!
#IBOutlet weak var lblCartTotalAmount: UILabel!
#IBOutlet weak var lblTotalAmount: UILabel!
#IBOutlet weak var viewBlankForCoupn: UIView!
var paymentType = "cod"
var couponCode = ""
#IBOutlet weak var lblEmptyCartText: UILabel!
#IBOutlet weak var lblAddInCartText: UILabel!
#IBOutlet weak var btnContinueSaida: CustomButton!
#IBOutlet weak var lblReviewOrder: UILabel!
#IBOutlet weak var lblMobileText: UILabel!
#IBOutlet weak var btnEditChange: UIButton!
#IBOutlet weak var lblOnlineText: UILabel!
#IBOutlet weak var lblCODText: UILabel!
#IBOutlet weak var lblPaymentMethodText: UILabel!
#IBOutlet weak var lblPriceDetailsText: UILabel!
#IBOutlet weak var lblCartTotalText: UILabel!
#IBOutlet weak var lblTotalAmountText: UILabel!
#IBOutlet weak var btnProcedd: CustomButton!
#IBOutlet weak var lblCouponText: UILabel!
#IBOutlet weak var btnApplyCoupon: UIButton!
#IBOutlet weak var lblDelivery: UILabel!
#IBOutlet weak var lblDeliveryText: UILabel!
#IBOutlet weak var lblDelTime: UILabel!
#IBOutlet weak var lblDiscountText: UILabel!
#IBOutlet weak var lblDiscount: UILabel!
#IBOutlet weak var lblFreeDel: UILabel!
#IBOutlet weak var lblCreditText: UILabel!
#IBOutlet weak var lblCreditPointText: UILabel!
#IBOutlet weak var btnRemoveCoupon: UIButton!
var addressData : JSON = []
var couponAmt = "0"
//For Stripe
var customerContext : STPCustomerContext?
var paymentContext : STPPaymentContext?
var isSetShipping = false
var paymentSheet: PaymentSheet?
var clientSecret = ""
var ephemeralKeySecret = ""
var paymentSheetFlowController: PaymentSheet.FlowController!
#IBOutlet weak var buyButton: UIButton!
#IBOutlet weak var paymentMethodButton: UIButton!
#IBOutlet weak var paymentMethodImage: UIImageView!
let publishableKey = "pk_test_51J***************bRP2"
override func viewDidLoad() {
super.viewDidLoad()
self.orderReview()
viewForApplyCoupon.isHidden = true
viewBlankForCoupn.isHidden = true
//Add Tap Gesture on Blank view to hide apply Coupon
let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
viewBlankForCoupn.addGestureRecognizer(tap)
viewForApplyCoupon.layer.cornerRadius = 8
viewForApplyCoupon.clipsToBounds = true
btnCod.setImage(#imageLiteral(resourceName: "radio"), for: .normal)
// viewForEmptyCart.isHidden = true
lblReviewOrder.text = "reviewOrder".localizableSting()
lblMobileText.text = "mobile".localizableSting() + " :"
btnEditChange.setTitle("edit".localizableSting(), for: .normal)
lblPaymentMethodText.text = "paymentMethod".localizableSting()
lblCODText.text = "cod".localizableSting()
lblOnlineText.text = "online".localizableSting()
lblApplyCoupon.text = "applyCoupon".localizableSting()
lblPriceDetailsText.text = "priceDetails".localizableSting()
lblCartTotalText.text = "cartTotal".localizableSting()
lblTotalAmountText.text = "total".localizableSting()
btnProcedd.setTitle("proceedReview".localizableSting(), for: .normal)
lblEmptyCartText.text = "blankCartText".localizableSting()
lblAddInCartText.text = "addInCartText".localizableSting()
btnContinueSaida.setTitle("continueSaida".localizableSting(), for: .normal)
lblCouponText.text = "coupon".localizableSting()
txtCouponCode.placeholder = "txtCoupon".localizableSting()
btnApplyCoupon.setTitle("apply".localizableSting(), for: .normal)
btnOnlinePayment.isEnabled = true
self.lblDeliveryText.text = "deliveryCharges".localizableSting()
self.lblNsmr.text = self.addressData["fname"].stringValue + " " + self.addressData["lname"].stringValue
self.lblAdress.text = "\(self.addressData["address"].stringValue), \(self.addressData["state"].stringValue), \(self.addressData["city"].stringValue)"
self.lblMobile.text = self.addressData["mobileno"].stringValue
if NetworkManeger.getWalletStatus() == "0" {
lblCreditText.isHidden = true
lblCreditPointText.isHidden = true
}else{
lblCreditText.isHidden = false
lblCreditPointText.isHidden = false
}
self.intiateStripePayment()
}
#objc func handleTap(_ sender: UITapGestureRecognizer? = nil) {
// handling code
viewForApplyCoupon.isHidden = true
viewBlankForCoupn.isHidden = true
}
#IBAction func btnCODAction(_ sender: Any) {
paymentType = "cod"
btnCod.setImage(#imageLiteral(resourceName: "radio"), for: .normal)
btnOnlinePayment.setImage(#imageLiteral(resourceName: "contact_us_icon-1"), for: .normal)
}
#IBAction func btnOnlineAction(_ sender: Any) {
if self.responseData["totalcost"].floatValue > 0 {
paymentType = "online"
btnOnlinePayment.setImage(#imageLiteral(resourceName: "radio"), for: .normal)
btnCod.setImage(#imageLiteral(resourceName: "contact_us_icon-1"), for: .normal)
}
}
#IBAction func btnApplyCouponAction(_ sender: Any) {
//Show blank view and coupon code view
viewForApplyCoupon.isHidden = false
viewBlankForCoupn.isHidden = false
}
#IBAction func btnApplyCouponCode(_ sender: Any) {
//Call after response from API
couponCode = txtCouponCode.text ?? ""
txtCouponCode.resignFirstResponder()
//orderReview()
addCoupon()
viewForApplyCoupon.isHidden = true
viewBlankForCoupn.isHidden = true
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.responseData["productdetails"].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ReviewOrderTableViewCell", for: indexPath) as! ReviewOrderTableViewCell
let imgURLString = self.responseData["productdetails"][indexPath.row]["imageurl"].stringValue
let newImageUrlStr = imgURLString.replacingOccurrences(of: " ", with: "%20")
let imageUrl = URL(string:newImageUrlStr)
cell.imgCartProduct.af_setImage(withURL:imageUrl!)
cell.lblCartProductName.text = self.responseData["productdetails"][indexPath.row]["productname"].stringValue
cell.lblPrice.text = self.responseData["productdetails"][indexPath.row]["sellingprice"].stringValue + " " + "JD".localizableSting()
cell.lblQuantity.text = self.responseData["productdetails"][indexPath.row]["qty"].stringValue
cell.lblBySaidaText.text = "bySaida".localizableSting()
cell.lblSizeText.text = "size".localizableSting() + " : "
cell.lblSize.text = self.responseData["productdetails"][indexPath.row]["size"].stringValue
cell.lblQtyText.text = "qty".localizableSting() + " : "
cell.btnRemove.addTarget(self, action: #selector(remove(sender:)), for: .touchUpInside)
cell.btnRemove.tag = indexPath.row
return cell
}
#objc func remove(sender: UIButton) {
let altMessage = UIAlertController(title: "ZUCRAZ", message: "Remove this item from cart.", preferredStyle: UIAlertController.Style.alert)
altMessage.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: {
_ in
if NetworkManeger.isConnectedToNetwork(){
let cartId = NetworkManeger.getCartId()
let productId = self.responseData["productdetails"][sender.tag]["pid"].stringValue
NetworkManeger.postRequest(remainingUrl: "deleteCartProduct.php", parameters: ["cartid": cartId, "pid": productId]) { (response) in
if response["status"].intValue == 200 {
self.orderReview()
}else{
NetworkManeger.showAlertWithMsg(vc: self, msg: response["msg"].stringValue)
}
}
}else{
let altMessage = UIAlertController(title: "ZUCRAZ", message: "Please check internet connection!", preferredStyle: UIAlertController.Style.alert)
altMessage.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
self.present(altMessage, animated: true, completion: nil)
}
}))
altMessage.addAction(UIAlertAction(title: "Cancel", style: UIAlertAction.Style.default, handler: nil))
self.present(altMessage, animated: true, completion: nil)
}
#IBAction func btnBack(_ sender: UIButton) {
self.navigationController?.popViewController(animated: true)
}
#IBAction func btnProceed(_ sender: UIButton) {
self.openPaymentSheet()
}
//MARKS: API HIT
func intiateStripePayment(){
NetworkManeger.postRequest(remainingUrl: "stripepaymentinitiate.php", parameters: ["cartid": NetworkManeger.getCartId(), "user_id" : NetworkManeger.getUserId()]) { (response) in
if response["status"].intValue == 200 {
//Get ephmeral Key and clientSecret
self.clientSecret = response["clientSecret"].stringValue
// self.clientSecret = response["paymentintent"][0]["secret"].stringValue
self.ephemeralKeySecret = response["EphemeralKey"][0]["id"].stringValue
let cusId = NetworkManeger.getStripCustomerId()
// MARK: Set your Stripe publishable key - this allows the SDK to make requests to Stripe for your account
STPAPIClient.shared.publishableKey = self.publishableKey
// MARK: Create a PaymentSheet instance
var configuration = PaymentSheet.Configuration()
configuration.merchantDisplayName = "Zucraz"
configuration.customer = .init(
id: cusId, ephemeralKeySecret: self.ephemeralKeySecret)
configuration.returnURL = "payments-example://stripe-redirect"
self.paymentSheet = PaymentSheet(
paymentIntentClientSecret: self.clientSecret,
configuration: configuration)
DispatchQueue.main.async {
self.buyButton.isEnabled = true
}
}
}
}
func openPaymentSheet(){
// MARK: Start the checkout process
self.paymentSheet?.present(from: self) { paymentResult in
// MARK: Handle the payment result
switch paymentResult {
case .completed:
self.displayAlert("Your order is confirmed!")
case .canceled:
print("Canceled!")
case .failed(let error):
print(error)
self.displayAlert("Payment failed: \n\(error.localizedDescription)")
}
}
}
func displayAlert(_ message: String) {
let alertController = UIAlertController(title: "", message: message, preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default) { (action) in
alertController.dismiss(animated: true) {
self.navigationController?.popViewController(animated: true)
}
}
alertController.addAction(OKAction)
present(alertController, animated: true, completion: nil)
}
func orderReview(){
self.responseData = []
NetworkManeger.postRequest(remainingUrl: "orderReviewAPI.php", parameters: ["cartid": NetworkManeger.getCartId(), "user_id" : NetworkManeger.getUserId() , "coupondiscount" : couponCode, "applang" : NetworkManeger.getAppLang(), "iswalletused" : NetworkManeger.getWalletStatus(), "address_id" : self.addressData["address_id"].stringValue]) { }
}
func addCoupon(){
NetworkManeger.postRequest(remainingUrl: "cartcouponapply.php", parameters: ["cartid": NetworkManeger.getCartId(), "user_id" : NetworkManeger.getUserId() , "promocode" : couponCode, "cartvalue" : self.responseData["subtotal"].stringValue]) { }
}

Don't get confused by Error : "Set STPAPIClient.shared().publishableKey to your publishable key".
Nothing to do with this.
Check your keys if got this kind of error.
The EphemeralKey must look like: ek_test_xxx (secret).

Related

How can I get values of response variable in other view in swift ...when I try to access this variable it returns nil...need to solve this

I just want to get all the values of response variable in (Agent view controller class) when I try to get using object it returns nil I have tried in many ways but still getting nil....in agent view controller I'm assigning all those runtime values to uitextview
import UIKit
class LoginViewController: UIViewController {
weak var delegateL:AgentprofileViewController!
var user : [UserModel] = []
let mm = Usersmanager()
//MARK:-- Outlets
#IBOutlet public weak var txtPhoneNumber: UITextField!
#IBOutlet public weak var txtPassword: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
//Functions
#IBAction func btnLogin(_ sender: Any) {
//below is the response variable which I want in other (Agent view controller class)
let response = mm.alluser(phoneNo: txtPhoneNumber.text!, Password: txtPassword.text!)
if response.count ?? 0 > 0
{
//uncom
delegateL.runtimeid? = response[0].u_id
delegateL.runtimename? = response[0].u_name!
delegateL.runtimephone? = response[0].phoneNumber!
delegateL.runtimepassword? = response[0].password!
delegateL.runtimeaddress? = response[0].address!
delegateL.runtimerid? = response[0].r_id!
delegateL.runtimername? = response[0].r_name!
print(response[0].u_id)
print(response[0].u_name)
print(response[0].password)
print(response[0].phoneNumber)
print(response[0].address)
print(response[0].r_id)
print(response[0].r_name)
if response[0].r_name=="Agent"
{
let next : tabViewController = self.storyboard?.instantiateViewController(withIdentifier: "tabViewController") as! tabViewController
self.navigationController?.pushViewController(next, animated: true)
showalertforloginsuccess()
print("Login Successfull")
//Passing view to the next view if login is succesfull
// let next : HomeViewController = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
// self.navigationController?.pushViewController(next, animated: true)
}
else{
print("Login Succesfull but login person is not agent")
}
}
else
{
showalertforloginfail()
print("Not Login")
}
}
This one is Agent Controller class where I want to access response variable values
import UIKit
class AgentprofileViewController: UIViewController {
#IBOutlet weak var txtid: UITextView!
#IBOutlet weak var txtname: UITextView!
#IBOutlet weak var txtphone: UITextView!
#IBOutlet weak var txtrid: UITextView!
#IBOutlet weak var txtpass: UITextView!
#IBOutlet weak var txtrname: UITextView!
#IBOutlet weak var txtaddress: UITextView!
var runtimeid:Int? = 0
var runtimename:String?=""
var runtimepassword:String?=""
var runtimeaddress:String?=""
var runtimephone:String?=""
var runtimerid:Int? = 0
var runtimername:String?=""
override func viewDidLoad() {
super.viewDidLoad()
//below all runtime variables contain nil
print(runtimeid)
print(runtimename)
print(runtimeaddress)
print(runtimepassword)
print(runtimephone)
print(runtimerid)
print(runtimername)
result()
}
override func viewWillAppear(_ animated: Bool) {
self.tabBarController?.navigationItem.title = "Profile"
}
func result() {
//uncom
//below is the error(txtid...contain nill while wrapping)
txtid.text = "\(String(describing: runtimeid))"
txtname.text = runtimename
txtpass.text = runtimepassword
txtphone.text = runtimephone
txtaddress.text = runtimeaddress
txtrid.text = "\(String(describing: runtimerid))"
txtrname.text = runtimername
}
}

Am i using CallKit framwork of Apple for Voip call and how ever it work not work in background state when user accept call using callkit button

when the user gets from CallKit at that time I am switching root on accept button click of Call but somehow root controller object always found nil and application crashed
Case : this is happing when the application running in the background and phone state is locked.
func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
endCallTimer()
guard let call = callManager.callWithUUID(uuid: action.callUUID) else {
action.fail()
return
}
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let incomingCall = mainStoryboard.instantiateViewController(withIdentifier: "CallConnectedVC") as! IncomingController
incomingCall.connectToCalling(duration:self.callDict["duration"] as! Int, consumerId: "\(self.callDict["consumerId"] as! Int)", categoryName: self.callDict["categoryTopic"] as! String, categoryImage: "", callId: self.callDict["callId"] as! String)
let nav = UINavigationController(rootViewController: incomingCall)
UIApplication.shared.keyWindow?.makeKeyAndVisible()
UIApplication.shared.keyWindow?.rootViewController = nav
configureAudioSession()
call.answer()
action.fulfill()
}
IncomingController code -
import UIKit
import TwilioVideo
import AVFoundation
import SDWebImage
import FirebaseAnalytics
class IncomingController: UIViewController {
var camera: TVICameraCapturer?
#IBOutlet weak var img_user: UIImageView!
#IBOutlet weak var lblName: UILabel!
#IBOutlet weak var lbltopic: UILabel!
#IBOutlet weak var lblTimer: UILabel!
#IBOutlet weak var btn_speaker : UIButton!
#IBOutlet weak var btn_video: UIButton!
#IBOutlet weak var btn_mute: UIButton!
#IBOutlet weak var btn_extendcall: UIButton!
#IBOutlet weak var btn_endcall: UIButton!
//Video
#IBOutlet weak var btn_toogleMic : UIButton!
#IBOutlet weak var btnConnectAudio : UIButton!
#IBOutlet weak var btnFlipCamera : UIButton!
#IBOutlet weak var view_video: UIView!
#IBOutlet weak var lblviedoName: UILabel!
#IBOutlet weak var lblvideoTimer: UILabel!
#IBOutlet weak var lblvideoTopic: UILabel!
#IBOutlet weak var provider_previewView: TVIVideoView!
#IBOutlet weak var provider_remoteView: TVIVideoView!
#IBOutlet weak var provider_previewViewShadow: UIView!
#IBOutlet weak var btnView : UIView!
#IBOutlet weak var constrain_btnView: NSLayoutConstraint!
//UpdatedVideo
#IBOutlet weak var viewDisableVideo: UIView!
#IBOutlet weak var lblDisableViedoName: UILabel!
#IBOutlet weak var lblDisableVideoTimer: UILabel!
#IBOutlet weak var lblDisableTopic: UILabel!
#IBOutlet weak var lblDisableText: UILabel!
#IBOutlet weak var imgUserDisable: UIImageView!
var NotificationDict = NSMutableDictionary()
var Calltimer: Timer? = Timer()
var sec = 60
var min = 6
var audioDevice: TVIDefaultAudioDevice = TVIDefaultAudioDevice(block: {
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, mode: AVAudioSessionModeVoiceChat, options: .mixWithOthers)
try AVAudioSession.sharedInstance().setPreferredSampleRate(48000)
try AVAudioSession.sharedInstance().setPreferredIOBufferDuration(0.01)
} catch {
print(error)
}
})
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
TwilioVideo.audioDevice = self.audioDevice
self.prepareLocalMedia()
connectToCalling(duration:NotificationDict["duration"] as! Int, consumerId: "\(NotificationDict["consumerId"] as! Int)", categoryName: NotificationDict["categoryTopic"] as! String, categoryImage: "", callId: NotificationDict["callId"] as! String)
}
//MARK:- Speaker Method
func setAudioOutputSpeaker(_ enabled: Bool) {
let session = AVAudioSession.sharedInstance()
try? session.setCategory(AVAudioSessionCategoryPlayAndRecord)
try? session.setMode(AVAudioSessionModeVoiceChat)
if enabled {
try? session.overrideOutputAudioPort(AVAudioSessionPortOverride.speaker)
} else {
try? session.overrideOutputAudioPort(AVAudioSessionPortOverride.none)
}
try? session.setActive(true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK:- Custom Method
func connectToCalling(duration:Int, consumerId:String, categoryName:String, categoryImage:String, callId:String)
{
let Url = "\(Constant.tokenUrl)"
let Param = ["duration":duration, "consumerId":consumerId, "categoryName":categoryName, "categoryImage":categoryImage, "callId":callId] as [String:Any]
ApiResponse.onResponseKeyPost(url: Url, parms: Param as NSDictionary, completion: { (dict, errr) in
print("dict responce",dict)
if(errr == ""){
OperationQueue.main.addOperation {
accessToken = dict["providerToken"] as! String
let connectOptions = TVIConnectOptions.init(token: accessToken) { (builder) in
if let videoTrack = ProvideCallObject.localVideoTrack {
builder.videoTracks = [videoTrack]
}
// We will share a local audio track only if ExampleAVAudioEngineDevice is selected.
if let audioTrack = ProvideCallObject.localAudioTrack {
builder.audioTracks = [audioTrack]
}
userDef.set("\(dict["roomId"]!)", forKey: "roomId")
builder.roomName = "\(dict["roomId"]!)"
}
ProvideCallObject.Provideroom = TwilioVideo.connect(with: connectOptions, delegate: self)
}
}
})
}
#objc func updateCountDown() {
if btn_endcall.isUserInteractionEnabled == false
{
btn_endcall.isUserInteractionEnabled = true
}
if sec == 0 {
if min == 0
{
sec = 0
min = 0
goToFeedback()
Calltimer?.invalidate()
}else
{
sec = 59
min = min - 1
if min == 0 {
SystemSoundID.playFileNamed(fileName: "60 Seconds v2", withExtenstion: "m4a")
}
}
}else
{
var timeString = ""
sec = sec - 1
if min < 10
{
timeString = timeString + "0" + String(min)
if min == 2 && sec == 0{
SystemSoundID.playFileNamed(fileName: "2 Mins v2", withExtenstion: "m4a")
}
}
else
{
timeString = timeString + String(min)
}
if sec < 10
{
timeString = timeString + ":0" + String(sec)
}
else
{
timeString = timeString + ":" + String(sec)
}
lblTimer.text = "\(timeString) Free Minutes"
lblvideoTimer.text = "\(timeString) Free Minutes"
lblDisableVideoTimer.text = "\(timeString) remaining"
}
}
func prepareLocalMedia() {
if (ProvideCallObject.localAudioTrack == nil) {
ProvideCallObject.localAudioTrack = TVILocalAudioTrack.init(options: nil, enabled: true, name: "Microphone")
if (ProvideCallObject.localAudioTrack == nil) {
print("Failed to create audio track")
}
}
if (ProvideCallObject.localVideoTrack == nil) {
self.startPreview()
}
changeButtonImage(isVideoEnable: true)
}
//Video
func setupRemoteVideoView() {
self.provider_previewViewShadow.frame = CGRect(x: self.view_video.bounds.width - 132, y: self.view_video.bounds.height - 239, width: 112, height: 149)
self.provider_previewView.frame = self.provider_previewViewShadow.bounds
self.provider_remoteView.bringSubview(toFront: self.provider_previewViewShadow)
self.provider_remoteView.isHidden = false
}
// MARK: Private
func startPreview() {
if PlatformUtils.isSimulator {
return
}
camera = TVICameraCapturer(source: .frontCamera, delegate: self)
ProvideCallObject.localVideoTrack = TVILocalVideoTrack.init(capturer: camera!, enabled: true, constraints: nil, name: "Camera")
if (ProvideCallObject.localVideoTrack == nil) {
print("Failed to create video track")
} else {
ProvideCallObject.localVideoTrack!.addRenderer(self.provider_previewView)
let tap = UITapGestureRecognizer(target: self, action: #selector(IncomingController.flipCamera))
self.provider_previewView.addGestureRecognizer(tap)
}
}
#objc func flipCamera() {
if (self.camera?.source == .frontCamera) {
self.camera?.selectSource(.backCameraWide)
} else {
self.camera?.selectSource(.frontCamera)
}
}
func cleanupRemoteParticipant() {
if ((ProvideCallObject.remoteParticipant) != nil) {
if ((ProvideCallObject.remoteParticipant?.videoTracks.count)! > 0) {
let remoteVideoTrack = ProvideCallObject.remoteParticipant?.remoteVideoTracks[0].remoteTrack
remoteVideoTrack?.removeRenderer(self.provider_remoteView!)
self.provider_remoteView?.isHidden = true
}
}
ProvideCallObject.remoteParticipant = nil
}
}
// MARK:- TVIRoomDelegate
extension IncomingController : TVIRoomDelegate {
func callDetails(room_sid:String,callID:String) {
let params = ["room_sid":room_sid,"callId": callID,"isCallEnd":0] as [String : Any]
ApiResponse.onResponsePost(url: Constant.callDetailsTwilio, parms: params as NSDictionary) { (response, error) in
}
}
func didConnect(to room: TVIRoom) {
ProvideCallObject.localParticipant = ProvideCallObject.Provideroom?.localParticipant
ProvideCallObject.localParticipant?.delegate = self
Calltimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateCountDown), userInfo: nil, repeats: true)
NotificationDict["roomsid"] = room.sid
btn_video.isUserInteractionEnabled = true
-----------------------------------------
if (room.remoteParticipants.count > 0) {
ProvideCallObject.remoteParticipant = room.remoteParticipants[0]
ProvideCallObject.remoteParticipant?.delegate = self
self.callDetails(room_sid: room.sid, callID: NotificationDict["callId"] as! String)
}
if !isHeadPhoneAvailabel(){
self.setAudioOutputSpeaker(true)
}
}
func room(_ room: TVIRoom, didDisconnectWithError error: Error?) {
self.cleanupRemoteParticipant()
}
func room(_ room: TVIRoom, didFailToConnectWithError error: Error) {
}
func room(_ room: TVIRoom, participantDidConnect participant: TVIRemoteParticipant) {
if (ProvideCallObject.remoteParticipant == nil) {
ProvideCallObject.remoteParticipant = participant
ProvideCallObject.remoteParticipant?.delegate = self
}
// print("Participant \(participant.identity) connected with \(participant.remoteAudioTracks.count) audio and \(participant.remoteVideoTracks.count) video tracks")
}
func room(_ room: TVIRoom, participantDidDisconnect participant: TVIRemoteParticipant) {
if (ProvideCallObject.remoteParticipant == participant) {
cleanupRemoteParticipant()
}
goToFeedback()
}
}
// MARK: TVIRemoteParticipantDelegate
extension IncomingController : TVILocalParticipantDelegate {
func localParticipant(_ participant: TVILocalParticipant, publishedVideoTrack: TVILocalVideoTrackPublication) {
ProvideCallObject.localVideoTrack = publishedVideoTrack.videoTrack as? TVILocalVideoTrack
}
}
// MARK: TVIRemoteParticipantDelegate
extension IncomingController : TVIRemoteParticipantDelegate {
func subscribed(to videoTrack: TVIRemoteVideoTrack,
publication: TVIRemoteVideoTrackPublication,
for participant: TVIRemoteParticipant) {
if (ProvideCallObject.remoteParticipant == participant) {
setupRemoteVideoView()
videoTrack.addRenderer(self.provider_remoteView!)
}
}
func remoteParticipant(_ participant: TVIRemoteParticipant,
enabledVideoTrack publication: TVIRemoteVideoTrackPublication) {
// print("Participant \(participant.identity) enabled \(publication.trackName) video track")
self.viewDisableVideo.isHidden = true
changeButtonImage(isVideoEnable: true)
}
func remoteParticipant(_ participant: TVIRemoteParticipant,
disabledVideoTrack publication: TVIRemoteVideoTrackPublication) {
self.viewDisableVideo.isHidden = false
changeButtonImage(isVideoEnable: false)
// print("Participant \(participant.identity) disabled \(publication.trackName) video track")
}
}
extension IncomingController : TVICameraCapturerDelegate {
func cameraCapturer(_ capturer: TVICameraCapturer, didStartWith source: TVICameraCaptureSource) {
// Layout the camera preview with dimensions appropriate for our orientation.
self.provider_previewView.shouldMirror = (source == .frontCamera)
}
}
// MARK: TVIVideoViewDelegate
extension IncomingController : TVIVideoViewDelegate {
func videoView(_ view: TVIVideoView, videoDimensionsDidChange dimensions: CMVideoDimensions) {
self.view.setNeedsLayout()
}
}
so it is possible to switch or change root controller in define case?
Thanks

print .get in my label using alamofire json swift 3.0

Is being a few weeks and I'm still stuck with this problem here. I'm having a mind block with Api. I'm quite new on this and I really need help.
I have those lines done. The single task is: Get data from my API and post it in my label. I've 4 files/classes being used.
UserProfile
import Foundation
import SwiftyJSON
class UserProfileWork: NSObject {
var workHistoryId = String()
var jobSeekerId = String()
var jobPosition = String()
var employer = String()
var workHistoryName = String()
var responsabilities = String()
var reasonForLeaving = String()
var currentPosition = Int()
var startMonth = String()
var startYear = String()
var endMonth = String()
var endYear = String()
init?(workDict: [String: JSON]){
guard let workHistoryId = workDict["work_history_id"]?.string,
let jobSeekerId = workDict["job_seeker_id"]?.string,
let jobPosition = workDict["position"]?.string,
let employer = workDict["employer"]?.string,
let workHistoryName = workDict["work_history_name"]?.string,
let responsabilities = workDict["responsibilities"]?.string,
let reasonForLeaving = workDict["reason_for_leaving"]?.string,
let currentPosition = workDict["is_current_position"]?.toInt,
let startMonth = workDict["start_month"]?.string,
let startYear = workDict["start_year"]?.string,
let endMonth = workDict["end_month"]?.string,
let endYear = workDict["end_year"]?.string else { return nil}
self.workHistoryId = workHistoryId
self.jobSeekerId = jobSeekerId
self.jobPosition = jobPosition
self.employer = employer
self.workHistoryName = workHistoryName
self.responsabilities = responsabilities
self.reasonForLeaving = reasonForLeaving
self.currentPosition = currentPosition
self.startMonth = startMonth
self.startYear = startYear
self.endMonth = endMonth
self.endYear = endYear
}
}
Api + Userprofile
import Foundation
import Alamofire
import SwiftyJSON
extension API {
class func userProfile(completion: #escaping(_ error: Error?, _ userProfile: [UserProfile]?) ->Void) {
let url = URLs.jobSeekerTest90
guard let api_token = helper.getApiToken() else {
completion(nil, nil)
return
}
let headers: HTTPHeaders = [
"Authorization": "Bearer \(api_token)",
"Accept": "application/json"
]
let parameters = [
"api_token": api_token
]
Alamofire.request(url, method: .get, parameters: parameters, encoding: URLEncoding.default, headers: headers)
.responseJSON{ response in
switch response.result{
case .failure(let error):
completion(error, nil)
print(error)
case .success(let value):
let json = JSON(value)
print(json)
guard let dataDict = json["data"]["jobSeeker"].array else{
completion(nil, nil)
return
}
var userProfile = [UserProfile]()
for data in dataDict {
if let data = data.dictionary, let profileData = UserProfile.init(dict: data){
userProfile.append(profileData)
}
completion(nil, userProfile)
}
}
}
}
}
And my view Controller ( I had tableview before but I decided to use only scrollView + labeles because I just need to display those single data)
import UIKit
import Alamofire
class ProfileViewController: UIViewController{
#IBOutlet weak var leadingConstraint: NSLayoutConstraint!
#IBOutlet weak var menuView: UIView!
#IBOutlet weak var menuProfilePicture: UIImageView!
#IBOutlet weak var myAccountImageMenu: UIImageView!
#IBOutlet weak var switchProfileImageMenu: UIImageView!
#IBOutlet weak var signOutImageMenu: UIImageView!
//User profile
#IBOutlet weak var userProfilePicture: UIImageView!
#IBOutlet weak var userNameLabel: UILabel!
#IBOutlet weak var userNameJobPositionLabel: UILabel!
//quick facts
#IBOutlet weak var quickFactsLabel: UILabel!
#IBOutlet weak var userLocationImage: UIImageView!
#IBOutlet weak var userLocationLabel: UILabel!
#IBOutlet weak var userWorkExpImage: UIImageView!
#IBOutlet weak var userWorkExpLabel: UILabel!
#IBOutlet weak var educationImage: UIImageView!
#IBOutlet weak var educationLabel: UILabel!
#IBOutlet weak var infoImage: UIImageView!
#IBOutlet weak var infoAboutLabel: UILabel!
// most recent jobs
#IBOutlet weak var recentJobTitleLabel: UILabel!
#IBOutlet weak var userJobTitleLabel: UILabel!
#IBOutlet weak var companyNameLabel: UILabel!
#IBOutlet weak var startFinishLabel: UILabel!
//Education
#IBOutlet weak var highestEducLabel: UILabel!
#IBOutlet weak var programNameLabel: UILabel!
#IBOutlet weak var schoolNameLabel: UILabel!
#IBOutlet weak var startFinishEducLabel: UILabel!
var iconArray: [String]!
var userProfileData : [UserProfile] = []
var userProfileEducation : [UserProfileEducation] = []
var userProfileWork : [UserProfileWork] = []
var menuShowing = false
override func viewDidLoad() {
super.viewDidLoad()
iconArray = ["currentLocationIcon", "dataIcon", "educationIcon", "infiIcon"]
leadingConstraint.constant = -520
menuView.layer.shadowOpacity = 1
menuView.layer.shadowRadius = 5
menuProfilePicture.layer.cornerRadius = 35
menuProfilePicture.clipsToBounds = true
userProfilePicture.layer.cornerRadius = 55
userProfilePicture.clipsToBounds = true
handleRefresh()
userData()
}
private func userData(){
self.userNameLabel.text = ""
self.userNameJobPositionLabel.text = "Job Title"
self.userLocationLabel.text = "User Location"
self.userWorkExpLabel.text = "Work Experience"
self.educationLabel.text = "Education"
self.infoAboutLabel.text = "About me. More about me"
self.userJobTitleLabel.text = "Job title again"
self.companyNameLabel.text = "Company Name"
self.startFinishLabel.text = "12 sep 2010 - 11 sep 2017"
self.programNameLabel.text = "web and mobile app dev"
self.schoolNameLabel.text = "school name"
self.startFinishEducLabel.text = "finished at"
}
//reusable cells
private func handleRefresh(){
API.userProfile { (error: Error?, userProfileData: [UserProfile]?) in
if let userProfileData = userProfileData {
self.userProfileData = userProfileData
}
}
API.userEducation { (error: Error?, userEducation : [UserProfileEducation]?) in
if let userEducation = userEducation {
self.userProfileEducation = userEducation
}
}
API.userWork { (error: Error?, userWork: [UserProfileWork]?) in
if let userWork = userWork {
self.userProfileWork = userWork
}
}
}
//Scroll hidden menu
#IBAction func scrollMenu(_ sender: Any) {
if(menuShowing){
leadingConstraint.constant = -520
UIView.animate(withDuration: 0.5, animations: {
self.view.layoutIfNeeded()
})
}else{
leadingConstraint.constant = 0
UIView.animate(withDuration: 0.5, animations: {
self.view.layoutIfNeeded()
})
}
menuShowing = !menuShowing
}
override func dismissKeyboard() {
view.endEditing(true)
}
}
I really need help on this guys. Please, help me!
I made some changes and It worked.
import UIKit
import SwiftyJSON
class UserProfile: NSObject{
var userID = String()
var JobSeekerId = String()
var userFstName = String()
var userLstName = String()
var userFullName = String()
var userJobTitle = String()
var userAbout = String()
var userLocation = String()
var userRecentSalary = String()
var userSalaryHiExpect = String()
var userSalaryLoExpect = String()
var userWebsiteUrl = String()
var userEmail = String()
var userMobile = String()
init?(dict: [String: Any]){
guard let userID = dict["user_id"] as? String,
let jobSeekerId = dict["job_seeker_id"] as? String,
let userFstName = dict["first_name"] as? String,
let userLstName = dict["last_name"] as? String,
let userFullName = dict["job_seeker_name"] as? String,
let userJobTitle = dict["personal_job_title"] as? String,
let userAbout = dict["about"] as? String,
let userLocation = dict["seekingLocations"] as? String,
let userRecentSalary = dict["most_recent_salary"] as? String,
let userSalaryHiExpect = dict["salary_expectation_high"] as? String,
let userSalaryLoExpect = dict["salary_expectation_low"] as? String,
let userWebsiteUrl = dict["website_url"] as? String,
let userEmail = dict["contact_email"] as? String,
let userMobile = dict["contact_mobile"] as? String else { return nil }
self.userID = userID
self.JobSeekerId = jobSeekerId
self.userFstName = userFstName
self.userLstName = userLstName
self.userFullName = userFullName
self.userJobTitle = userJobTitle
self.userAbout = userAbout
self.userLocation = userLocation
self.userRecentSalary = userRecentSalary
self.userSalaryHiExpect = userSalaryHiExpect
self.userSalaryLoExpect = userSalaryLoExpect
self.userWebsiteUrl = userWebsiteUrl
self.userEmail = userEmail
self.userMobile = userMobile
}
}
API+userProfile
import Foundation
import Alamofire
import SwiftyJSON
extension API {
class func userProfile(completion: #escaping(_ error: Error?, _ userProfile: UserProfile?) ->Void) {
let url = URLs.jobSeekerTest90
guard let api_token = helper.getApiToken() else {
completion(nil, nil)
return
}
let headers: HTTPHeaders = [
"Authorization": "Bearer \(api_token)",
"Accept": "application/json"
]
let parameters = [
"api_token": api_token
]
Alamofire.request(url, method: .get, parameters: parameters, encoding: URLEncoding.default, headers: headers)
.responseJSON{ response in
switch response.result{
case .failure(let error):
completion(error, nil)
print(error)
case .success(let value):
let json = JSON(value)
print(json)
guard let dataDict = json["data"]["jobSeeker"].dictionaryObject else{
completion(nil, nil)
return
}
var userProfile = UserProfile(dict: dataDict)
completion(nil, userProfile)
}
}
}
}
ViewController
import UIKit
import Alamofire
class ProfileViewController: UIViewController{
#IBOutlet weak var leadingConstraint: NSLayoutConstraint!
#IBOutlet weak var menuView: UIView!
#IBOutlet weak var menuProfilePicture: UIImageView!
#IBOutlet weak var menuProfileName: UILabel!
#IBOutlet weak var myProfileJobTitle: UILabel!
#IBOutlet weak var myAccountImageMenu: UIImageView!
#IBOutlet weak var switchProfileImageMenu: UIImageView!
#IBOutlet weak var signOutImageMenu: UIImageView!
//User profile
#IBOutlet weak var userProfilePicture: UIImageView!
#IBOutlet weak var userNameLabel: UILabel!
#IBOutlet weak var userNameJobPositionLabel: UILabel!
//quick facts
#IBOutlet weak var quickFactsLabel: UILabel!
#IBOutlet weak var userLocationImage: UIImageView!
#IBOutlet weak var userLocationLabel: UILabel!
#IBOutlet weak var userWorkExpImage: UIImageView!
#IBOutlet weak var userWorkExpLabel: UILabel!
#IBOutlet weak var educationImage: UIImageView!
#IBOutlet weak var educationLabel: UILabel!
#IBOutlet weak var infoImage: UIImageView!
#IBOutlet weak var infoAboutLabel: UILabel!
// most recent jobs
#IBOutlet weak var recentJobTitleLabel: UILabel!
#IBOutlet weak var userJobTitleLabel: UILabel!
#IBOutlet weak var companyNameLabel: UILabel!
#IBOutlet weak var startFinishLabel: UILabel!
//Education
#IBOutlet weak var highestEducLabel: UILabel!
#IBOutlet weak var programNameLabel: UILabel!
#IBOutlet weak var schoolNameLabel: UILabel!
#IBOutlet weak var startFinishEducLabel: UILabel!
var iconArray: [String]!
var userProfileData : [UserProfile] = []
var userProfileEducation : [UserProfileEducation] = []
var userProfileWork : [UserProfileWork] = []
var menuShowing = false
override func viewDidLoad() {
super.viewDidLoad()
iconArray = ["currentLocationIcon", "dataIcon", "educationIcon", "infiIcon"]
leadingConstraint.constant = -520
menuView.layer.shadowOpacity = 1
menuView.layer.shadowRadius = 5
menuProfilePicture.layer.cornerRadius = 35
menuProfilePicture.clipsToBounds = true
userProfilePicture.layer.cornerRadius = 55
userProfilePicture.clipsToBounds = true
userData()
userWorkProfileData()
userEducationProfileData()
}
private func userData(){
API.userProfile { (error: Error?, userProfileData: UserProfile?) in
if let userProfileData = userProfileData {
self.myProfileJobTitle.text = userProfileData.userFullName
self.menuProfileName.text = userProfileData.userJobTitle
self.userNameLabel.text = userProfileData.userFullName
self.userNameJobPositionLabel.text = userProfileData.userJobTitle
self.userLocationLabel.text = userProfileData.userLocation
self.infoAboutLabel.text = userProfileData.userAbout
self.userJobTitleLabel.text = userProfileData.userJobTitle
}
}
}
//Scroll hidden menu
#IBAction func scrollMenu(_ sender: Any) {
if(menuShowing){
leadingConstraint.constant = -520
UIView.animate(withDuration: 0.5, animations: {
self.view.layoutIfNeeded()
})
}else{
leadingConstraint.constant = 0
UIView.animate(withDuration: 0.5, animations: {
self.view.layoutIfNeeded()
})
}
menuShowing = !menuShowing
}
override func dismissKeyboard() {
view.endEditing(true)
}
}

How To Fix: "Expression is Ambiguous".

I am trying to create an app that can help you calculate sales tax on an item. Of course the app requires multiplication But I keep encountering the error:
"Type of expression is ambiguous without more context"
Can you help me? I'm new to swift so also try to explain why I am incorrect. This is my code so far:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var Item: UITextField!
#IBOutlet weak var Tax: UITextField!
#IBOutlet weak var Answer: UITextField!
#IBAction func Calculate(_ sender: Any) {
let a = Item.text
let conversionRate = Tax
let b = Int(a!)! * conversionRate
Answer.text = ("\(b)")
}
}
Thanks!!
Your primary issue is your attempt to multiply an Int and a UITextField.
You attempt to create an Int from Item.text but you make no similar attempt to convert Tax.text to a number.
There are also many other issues with your code. You are using the ! operator too much and your app will crash as a result.
And your naming conventions need to be improved. Variables and methods should start with lowercase letters.
Here's your code as it should be written:
class ViewController: UIViewController {
#IBOutlet weak var item: UITextField!
#IBOutlet weak var tax: UITextField!
#IBOutlet weak var answer: UITextField!
#IBAction func calculate(_ sender: Any) {
if let itemStr = item.text, let taxStr = tax.text, let itemVal = Int(itemStr), let taxVal = Int(taxStr) {
let result = itemVal * texVal
answer.text = "\(result)"
} else {
answer.text = "Invalid values"
}
}
}
You're trying to multiply a variable of UITextField type with a variable of Int. Try this:
class ViewController: UIViewController {
#IBOutlet weak var Item: UITextField!
#IBOutlet weak var Tax: UITextField!
#IBOutlet weak var Answer: UITextField!
#IBAction func Calculate(_ sender: Any) {
guard let a = Int(Item.text ?? "0") else { return }
guard let conversionRate = Int(Tax.text ?? "0") else { return }
let b = a * conversionRate
Answer.text = ("\(b)")
}
}

How avoid duplication of rows when populating data from core data on a tableView

I'm working on a project that is written in swift 3.0. My requirement is to retrieve and populate the data on a table view which is saved on CoreData that I enter on some text fields, thus once a row is selected I wants to update that record (re-assign values on my text fields and save).
Basically I have an entity named "UserIncome" and it got few attributes. Thus, when I wants to edit the data that I entered, I tap on a row and it'll direct me to the ViewController where I initially entered those data. However when I click the add button and save the data im getting duplicated data and they get populate in my table view. how can I stop this. The code of the class where i save data as follow.
import UIKit
import CoreData
class AddIncomeViewController:UIViewController,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var toDateView: UIView!
#IBOutlet weak var setDateFromView: UIView!
#IBOutlet weak var datePickerTo: UIDatePicker!
#IBOutlet weak var datePickerFrom: UIDatePicker!
#IBOutlet weak var dropDowntableView: UITableView!
#IBOutlet weak var fromTextField: UITextField!
#IBOutlet weak var toTextField: UITextField!
#IBOutlet weak var amountTextField: UITextField!
#IBOutlet weak var incomeTypeLabel: UILabel!
#IBOutlet weak var incomeNameTextField: UITextField!
var myArray = ["Recurring Income", "Other Income"]
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var store : UserIncome?
var otherInc : UserIncome?
override func viewDidLoad() {
super.viewDidLoad()
if let s = store {
incomeNameTextField.text = s.incomeName
amountTextField.text = s.amount
fromTextField.text = s.fromDate
toTextField.text = s.toDate
incomeTypeLabel.text = s.incomeType
}
if let o = otherInc {
incomeNameTextField.text = o.incomeName
amountTextField.text = o.amount
fromTextField.text = o.fromDate
toTextField.text = o.toDate
incomeTypeLabel.text = o.incomeType
}
}
#IBAction func cancelButtonPressed(_ sender: AnyObject) {
navigationController!.popViewController(animated: true)
}
#IBAction func addButtonPressed(_ sender: AnyObject) {
if store == nil{
let storeDesciption = NSEntityDescription.entity(forEntityName: "UserIncome", in: context)
store = UserIncome(entity:storeDesciption! , insertInto: context)
//otherInc = UserIncome(entity:storeDesciption! , insertInto: context)
}
if otherInc == nil{
let storeDesciption = NSEntityDescription.entity(forEntityName: "UserIncome", in: context)
otherInc = UserIncome(entity:storeDesciption! , insertInto: context)
}
store?.incomeName = incomeNameTextField.text
store?.amount = amountTextField.text
store?.fromDate = fromTextField.text
store?.toDate = toTextField.text
store?.incomeType = incomeTypeLabel.text
otherInc?.incomeName = incomeNameTextField.text
otherInc?.amount = amountTextField.text
otherInc?.fromDate = fromTextField.text
otherInc?.toDate = toTextField.text
otherInc?.incomeType = incomeTypeLabel.text
var error : NSError?
(UIApplication.shared.delegate as! AppDelegate).saveContext()
if let err = error{
let a = UIAlertView(title: "Success", message: err.localizedFailureReason, delegate: nil, cancelButtonTitle: "OK")
a.show()
}else {
let a = UIAlertView(title: "Success", message: "Successfully saved", delegate: nil, cancelButtonTitle: "OK")
a.show()
// navigationController!.popViewController(animated: true)
}
You added two different UserIncome objects. You should add one, and share it for your table views.

Resources