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
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
}
}
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
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)
}
}
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)")
}
}
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.