I have an IOS app successfully uploaded to iTunes, the app has also been testing successfully on both local simulator & real device.
however, when I download the app from App Store (with same device, same OS version), the app will load initially, and crash on a specific view.
I got the following error message from my NewRelic Crash Analytic:
SIGSEGV in 0x10024d050 0 + 4297379920
This seems to be a very unusual error, since the local copy should be exactly the same as the one I uploaded to App store.
Any advice is appreciated,
thanks!
Stack Trace:
Exception Type: EXC_CRASH (SIGTRAP)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Triggered by Thread: 1
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0:
0 MyXcodeProject 0x00000001000fbfe4 0x100098000 + 409572
1 UIKit 0x0000000188e90954 0x188e80000 + 67924
2 UIKit 0x0000000188e90664 0x188e80000 + 67172
3 UIKit 0x00000001895841cc 0x188e80000 + 7356876
4 UIKit 0x000000018918b78c 0x188e80000 + 3192716
5 UIKit 0x00000001891a6b4c 0x188e80000 + 3304268
6 UIKit 0x00000001891a8f64 0x188e80000 + 3313508
7 UIKit 0x0000000188f85b38 0x188e80000 + 1071928
8 UIKit 0x0000000188fb3ac0 0x188e80000 + 1260224
9 UIKit 0x0000000188fb2998 0x188e80000 + 1255832
10 UIKit 0x0000000188ee54b4 0x188e80000 + 414900
11 Foundation 0x000000018556cba0 0x185484000 + 953248
12 CoreFoundation 0x000000018463ac1c 0x18455c000 + 912412
13 CoreFoundation 0x000000018463a8cc 0x18455c000 + 911564
14 CoreFoundation 0x0000000184638318 0x18455c000 + 901912
15 CoreFoundation 0x00000001845651f0 0x18455c000 + 37360
16 GraphicsServices 0x000000018d9876f8 0x18d97c000 + 46840
17 UIKit 0x0000000188ef6108 0x188e80000 + 483592
18 MyXcodeProject 0x00000001001ed04c 0x100098000 + 1396812
19 libdyld.dylib 0x0000000195cd6a04 0x195cd4000 + 10756
The following will be where this error occurs:
import UIKit import CoreData
class ContactListViewController: UIViewController, NSFetchedResultsControllerDelegate, UICollectionViewDataSource, UICollectionViewDelegate, UIAlertViewDelegate, WYPopoverControllerDelegate, CreateGroupVcDelegate, ContactListDetailVcDelegate, SelectAddContactsTableVcDelegate, SelectContactsVcDelegate {
@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var btnEdit: UIButton!
var fetchedResultsController_Group: NSFetchedResultsController = NSFetchedResultsController()
var fetchedResultsController_Contact: NSFetchedResultsController = NSFetchedResultsController()
var fetchedResult_GroupAndContact = [GroupAndContact]()
// Select Group Index
var selectedGroupIndex = Int()
// Selected group ID
var selectedGroupId = Int()
var contactIndex = Int()
// BOOL indicator
var isEditMode : Bool = false
// Popover Controller
var popoverController_CreateGroupVc = WYPopoverController()
var popoverController_ContactListDetailVc = WYPopoverController()
var popoverController_SelectAddContactsTableVc = WYPopoverController()
override func viewDidLoad()
{
super.viewDidLoad()
MainMenuItem.setupMenuBtn(self)
self.navigationController?.navigationBar.topItem?.title = "Contact"
self.navigationController?.navigationBar.titleTextAttributes = [ NSFontAttributeName: UIFont(name: "Avenir Light", size: 18)!, NSForegroundColorAttributeName: UIColor.navigationBarTitle()]
// Do any additional setup after loading the view.
// Listeners
NSNotificationCenter.defaultCenter().addObserver(self, selector: "updateSavedDataContact_Success", name:"updateSavedDataContact_Success", object: nil)
// Default index 1 as the selected item for the colleciton view
selectedGroupIndex = 1
updateDataSource()
}
func updateDataSource ()
{
getFetchedResultController_Group()
let modIndexPath : NSIndexPath = NSIndexPath(forRow: selectedGroupIndex_data(), inSection: 0)
var result = self.fetchedResultsController_Group.objectAtIndexPath(modIndexPath) as? Group
selectedGroupId = result!.id as Int
getFetchedResultController_Contact(result!.id as Int)
self.collectionView.reloadData()
self.tableView.reloadData()
}
// #Listener Methods
func updateSavedDataContact_Success ()
{
updateDataSource()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func getFetchedResultController_Group ()
{
let appDel : AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
let moc: NSManagedObjectContext = appDel.managedObjectContext!
let fetchRequest = NSFetchRequest()
//3 - set the correct table
let entity = NSEntityDescription.entityForName("Group", inManagedObjectContext: moc)
fetchRequest.entity = entity
fetchRequest.fetchBatchSize = 20
/*
// Filter
let predicate1 : NSPredicate = NSPredicate(format: "is_incoming_all == \(mytaskValue)", argumentArray: nil)
let predicate12 : NSPredicate = NSPredicate(format: "name == \"Nice Group\"", argumentArray: nil)
let predicateArray : Array = [predicate1]
let compoundPredicate : NSPredicate = NSCompoundPredicate.andPredicateWithSubpredicates(predicateArray)
fetchRequest.predicate = compoundPredicate */
let sectionSortDescriptor = NSSortDescriptor(key: "sort_id", ascending: true)
let sortDescriptors = [sectionSortDescriptor] //, secondSortDescriptor]
fetchRequest.sortDescriptors = sortDescriptors
//4 - navigate in relationship to group by time
let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)
aFetchedResultsController.delegate = self
self.fetchedResultsController_Group = aFetchedResultsController
var error: NSError? = nil
if !self.fetchedResultsController_Group.performFetch(&error) {
abort()
}
}
func getFetchedResultController_Contact (groupId: Int)
{
getFetchedResultController_GroupAndContact(groupId)
let appDel : AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
let moc: NSManagedObjectContext = appDel.managedObjectContext!
let fetchRequest = NSFetchRequest()
//3 - set the correct table
let entity = NSEntityDescription.entityForName("Contact", inManagedObjectContext: moc)
fetchRequest.entity = entity
fetchRequest.fetchBatchSize = 20
// Filter
var strForPredicate = String()
strForPredicate = strForPredicate + "id == nil"
for (var i = 0; i < fetchedResult_GroupAndContact.count; i++)
{
strForPredicate = strForPredicate + " OR id == \(fetchedResult_GroupAndContact[i].contact_id)"
}
//"groupAndContact.group_id == \(groupId) AND groupAndContact.contact_id == id"
let predicate1 : NSPredicate = NSPredicate(format: strForPredicate, argumentArray: nil)
//let predicate1 : NSPredicate = NSPredicate(format: "id == SUBQUERY(groupAndContact, $gac, ANY $gac.group_id == \(groupId)).contact_id", argumentArray: nil)
//let predicate2 : NSPredicate = NSPredicate(format: "name == \"Nice Group\"", argumentArray: nil)
let predicateArray : Array = [predicate1]
let compoundPredicate : NSPredicate = NSCompoundPredicate.andPredicateWithSubpredicates(predicateArray)
fetchRequest.predicate = compoundPredicate
let sectionSortDescriptor = NSSortDescriptor(key: "name", ascending: true)
let sortDescriptors = [sectionSortDescriptor] //, secondSortDescriptor]
fetchRequest.sortDescriptors = sortDescriptors
//4 - navigate in relationship to group by time
let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)
aFetchedResultsController.delegate = self
self.fetchedResultsController_Contact = aFetchedResultsController
var error: NSError? = nil
if !self.fetchedResultsController_Contact.performFetch(&error) {
abort()
}
}
func getFetchedResultController_GroupAndContact (groupId: Int)
{
var managedObjectContext : NSManagedObjectContext? = {
let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
if let managedObjectContext = appDelegate.managedObjectContext {
return managedObjectContext
}
else {
return nil
}
}()
let fetchRequest1 = NSFetchRequest(entityName: "GroupAndContact")
// Filter
let predicate11 : NSPredicate = NSPredicate(format: "group_id == \(groupId)", argumentArray: nil)
//let predicate12 : NSPredicate = NSPredicate(format: "name == \"Nice Group\"", argumentArray: nil)
let predicateArray1 : Array = [predicate11]
let compoundPredicate1 : NSPredicate = NSCompoundPredicate.andPredicateWithSubpredicates(predicateArray1)
fetchRequest1.predicate = compoundPredicate1
if let fetchResults1 = managedObjectContext!.executeFetchRequest(fetchRequest1, error: nil) as? [GroupAndContact] {
fetchedResult_GroupAndContact = fetchResults1
}
}
// #Buttons
@IBAction func btnDeleteGroup(sender: AnyObject)
{
var indexPath = NSIndexPath()
indexPath = self.collectionView.indexPathForItemAtPoint(self.collectionView.convertPoint(sender.center, fromView: sender.superview))!
let modIndexPath : NSIndexPath = NSIndexPath(forRow: indexPath.row-1, inSection: indexPath.section)
var result = self.fetchedResultsController_Group.objectAtIndexPath(modIndexPath) as? Group
// Reset selectedItemIndex Logic : Delete
if (indexPath.row > selectedGroupIndex)
{
// selectedGroupIndex stays the same
}
else if (indexPath.row == selectedGroupIndex)
{
selectedGroupIndex = 1
}
else if (indexPath.row <= selectedGroupIndex)
{
selectedGroupIndex = selectedGroupIndex-1
}
/*
if(selectedGroupIndex == returnLastItemIndexInCollectionView())
{
selectedGroupIndex = 1
}
*/
AlertManager.instance.alertDeleteGroupConfirmation(result!.name, okBlock: {
// EXE
DataManager.instance.deleteSpecificGroup( Int(result!.id) )
}, cancelBlock: {})
btnEditSupport()
}
//temp
@IBAction func btnEdit(sender: AnyObject)
{
btnEditSupport()
}
func btnEditSupport()
{
isEditMode = !isEditMode
if(isEditMode)
{
btnEdit.setTitle("Done", forState: UIControlState.Normal)
}
else
{
btnEdit.setTitle("Edit", forState: UIControlState.Normal)
}
updateDataSource()
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
// #CollectionView Delegate
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
let sectionInfo = self.fetchedResultsController_Group.sections![section] as NSFetchedResultsSectionInfo
return sectionInfo.numberOfObjects + 1
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
var cell: ContactListVcCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("MyCell", forIndexPath: indexPath) as ContactListVcCollectionViewCell
/*
var isSelected = false
for (var i = 0; i < arySelectedItemsIndex.count; i++)
{
if(indexPath.row == arySelectedItemsIndex[i])
{
isSelected = true
}
}
*/
var isSelected = false
if(indexPath.row == selectedGroupIndex)
{
isSelected = true
}
// Display
var img = UIImage(named: "icon_delete.png")?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
cell.imgDeleteGroup.image = img
cell.imgDeleteGroup.tintColor = UIColor.MBHred()
if ( indexPath.row == 0)
{
var img = UIImage(named: "icon_add.png")?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
cell.imgGroupIcon.image = img
cell.imgGroupIcon.tintColor = UIColor.groupIconAddGroup()
cell.lbGroupName.text = "Add"
cell.lbGroupName.textColor = UIColor.groupIconAddGroup()
// hide delete button for [add group] & [All Contact]
cell.imgDeleteGroup.hidden = true
cell.btnDeleteGroup.hidden = true
}
else
{
let modIndexPath : NSIndexPath = NSIndexPath(forRow: indexPath.row-1, inSection: indexPath.section)
var result = self.fetchedResultsController_Group.objectAtIndexPath(modIndexPath) as? Group
cell.lbGroupName.text = result?.name
cell.lbGroupName.textColor = UIColor.groupIconNotSelected()
var img = UIImage(named: "group_\(result!.icon_id).png")?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
// Display
cell.imgGroupIcon.image = img
cell.imgGroupIcon.tintColor = UIColor.groupIconNotSelected()
// Cell selected or not
if (isSelected)
{
cell.lbGroupName.textColor = UIColor.groupIconSelected()
cell.imgGroupIcon.tintColor = UIColor.groupIconSelected()
}
else
{
cell.lbGroupName.textColor = UIColor.groupIconNotSelected()
cell.imgGroupIcon.tintColor = UIColor.groupIconNotSelected()
}
// show delete button for [add group] & [All Contact]
// if the editmode is true
if (isEditMode && indexPath.row > 1)
{
cell.imgDeleteGroup.hidden = false
cell.btnDeleteGroup.hidden = false
}
else
{
cell.imgDeleteGroup.hidden = true
cell.btnDeleteGroup.hidden = true
}
}
return cell
}
// NOTE: Since the first item is always "Add", remeber to use Index.row-1 to fetch from Array
/*
let modIndexPath : NSIndexPath = NSIndexPath(forRow: indexPath.row-1, inSection: indexPath.section)
*/
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
if ( indexPath.row == 0 )
{
// Add Group
let vc = self.storyboard?.instantiateViewControllerWithIdentifier("CreateGroupViewController") as CreateGroupViewController
vc.preferredContentSize = CGSizeMake(self.view.bounds.width-25, self.view.bounds.height*4/5)
vc.loadView()
vc.delegateCreateGroupVcDelegate = self
vc.title = "Create a Group"
vc.btnCancel.addTarget(self, action: Selector("dismissCreateGroupVc"), forControlEvents: UIControlEvents.TouchUpInside)
/*
self.navigationController?.pushViewController(vc, animated: true)
*/
popoverController_CreateGroupVc = WYPopoverController(contentViewController: vc)
popoverController_CreateGroupVc.delegate = self
popoverController_CreateGroupVc.presentPopoverFromRect(CGRectMake(self.collectionView.bounds.origin.x, self.collectionView.bounds.origin.y, self.collectionView.bounds.width, 50) , inView: self.view, permittedArrowDirections: WYPopoverArrowDirection.Any, animated: true)
}
else
{
selectedGroupIndex = indexPath.row
// Choose from existing group
let modIndexPath : NSIndexPath = NSIndexPath(forRow: indexPath.row-1, inSection: indexPath.section)
var result = self.fetchedResultsController_Group.objectAtIndexPath(modIndexPath) as? Group
selectedGroupId = result!.id as Int
getFetchedResultController_Contact(result!.id as Int)
collectionView.reloadData()
tableView.reloadData()
println("result?.id = \(result?.id)")
}
}
// #alertView Delegate
func alertView(alert: UIAlertView!, clickedButtonAtIndex buttonIndex: Int)
{
if (buttonIndex == 1)
{
if ((alert.textFieldAtIndex(0)?.text) != nil)
{
DataManager.instance.addGroup(alert.textFieldAtIndex(0)!.text, iconId: 1)
}
}
}
// #TableView Delegate
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int
{
let sectionInfo = self.fetchedResultsController_Contact.sections![section] as NSFetchedResultsSectionInfo
return sectionInfo.numberOfObjects + 1
}
func tableView(tableView: UITableView!,
cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
{
let sectionInfo = self.fetchedResultsController_Contact.sections![indexPath.section] as NSFetchedResultsSectionInfo
var cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath) as ContactListVcTableViewCell
/*
var isSelected = false
for (var i = 0; i < arySelectedItemsIndex.count; i++)
{
if(indexPath.row == arySelectedItemsIndex[i])
{
isSelected = true
}
}
*/
var isSelected = false
if(indexPath.row == selectedGroupIndex)
{
isSelected = true
}
/*
// Display
var img = UIImage(named: "icon_delete.png")?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
cell.imgDeleteGroup.image = img
cell.imgDeleteGroup.tintColor = UIColor.redColor()
*/
// Last Row of the TableView : Add Button
if (indexPath.row == sectionInfo.numberOfObjects)
{
var img = UIImage(named: "icon_add.png")?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
cell.imgAddContact.image = img
cell.imgAddContact.tintColor = UIColor.groupIconAddGroup()
cell.lbName.hidden = true
cell.imgAddContact.hidden = false
//cell.lbAddContact.hidden = false
/*
// hide delete button for [add group] & [All Contact]
cell.imgDeleteGroup.hidden = true
cell.btnDeleteGroup.hidden = true */
}
// Other Rows of the TableView : Display
else
{
let modIndexPath : NSIndexPath = NSIndexPath(forRow: indexPath.row, inSection: indexPath.section)
var result = self.fetchedResultsController_Contact.objectAtIndexPath(modIndexPath) as? Contact
cell.lbName.text = result?.name
cell.lbName.textColor = UIColor.groupIconNotSelected()
cell.lbName.hidden = false
cell.imgAddContact.hidden = true
/*
//temp
var img = UIImage(named: "group_\(result!.icon_url).png")?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
// Display
cell.imgGroupIcon.image = img
cell.imgGroupIcon.tintColor = UIColor.groupIconNotSelected()
*/
/*
// Cell selected or not
if (isSelected)
{
cell.lbGroupName.textColor = UIColor.groupIconSelected()
cell.imgGroupIcon.tintColor = UIColor.groupIconSelected()
}
else
{
cell.lbGroupName.textColor = UIColor.groupIconNotSelected()
cell.imgGroupIcon.tintColor = UIColor.groupIconNotSelected()
}
*/
/*
// show delete button for [add group] & [All Contact]
// if the editmode is true
if (isEditMode)
{
cell.imgDeleteGroup.hidden = false
cell.btnDeleteGroup.hidden = false
}
else
{
cell.imgDeleteGroup.hidden = true
cell.btnDeleteGroup.hidden = true
}
*/
}
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
let sectionInfo = self.fetchedResultsController_Contact.sections![indexPath.section] as NSFetchedResultsSectionInfo
// Last Row of the TableView : Add Button
if (indexPath.row == sectionInfo.numberOfObjects)
{
//tmp_0309
/*
let vc = self.storyboard?.instantiateViewControllerWithIdentifier("SelectAddContactsTableViewControllerNav") as UINavigationController
vc.preferredContentSize = CGSizeMake(self.view.bounds.width-20, self.view.bounds.height*1/2)
vc.loadView()
let vc2 = vc.viewControllers[0] as SelectAddContactsTableViewController
vc2.delegateSelectAddContactsTableVcDelegate = self
vc2.selectedGroupId = selectedGroupId
popoverController_SelectAddContactsTableVc = WYPopoverController(contentViewController: vc)
popoverController_SelectAddContactsTableVc.delegate = self
popoverController_SelectAddContactsTableVc.presentPopoverFromRect(CGRectMake(self.collectionView.bounds.origin.x, self.collectionView.bounds.origin.y, self.collectionView.bounds.width, 50) , inView: self.view, permittedArrowDirections: WYPopoverArrowDirection.Any, animated: true)
*/
self.performSegueWithIdentifier("toSelectContactsVc", sender: self)
}
else
{
let modIndexPath : NSIndexPath = NSIndexPath(forRow: indexPath.row, inSection: indexPath.section)
var result = self.fetchedResultsController_Contact.objectAtIndexPath(modIndexPath) as? Contact
contactIndex = indexPath.row
let myRect : CGRect = tableView.rectForRowAtIndexPath(indexPath)
var myRectMod : CGRect = CGRect(x: myRect.origin.x, y: myRect.origin.y, width: 20, height: myRect.height)
// Display ContactListDetailVc Popover
let vc = self.storyboard?.instantiateViewControllerWithIdentifier("ContactListDetailViewController") as ContactListDetailViewController
vc.loadView()
vc.delegateContactListDetailVcDelegate = self
vc.contactId = result!.id as Int
vc.title = "Contact Detail"
//vc.btnCancel.addTarget(self, action: Selector("dismissCreateGroupVc"), forControlEvents: UIControlEvents.TouchUpInside)
//vc.preferredContentSize = CGSizeMake( self.view.bounds.width-50, self.view.bounds.height-85)
vc.preferredContentSize = CGSizeMake( self.view.bounds.width-20, 270)
popoverController_ContactListDetailVc = WYPopoverController(contentViewController: vc)
popoverController_ContactListDetailVc.delegate = self
popoverController_ContactListDetailVc.presentPopoverFromRect(myRectMod, inView: self.tableView, permittedArrowDirections: WYPopoverArrowDirection.Up, animated: true)
//popoverController.presentPopoverAsDialogAnimated(true, options: WYPopoverAnimationOptions.FadeWithScale)
}
}
func tableView(tableView: UITableView!, canEditRowAtIndexPath indexPath: NSIndexPath!) -> Bool {
let sectionInfo = self.fetchedResultsController_Contact.sections![indexPath.section] as NSFetchedResultsSectionInfo
// Last Row of the TableView : Add Button
if (indexPath.row == sectionInfo.numberOfObjects)
{
return false
}
else
{
return true
}
}
func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) {
if (editingStyle == UITableViewCellEditingStyle.Delete) {
// handle delete (by removing the data from your array and updating the tableview)
let modIndexPath : NSIndexPath = NSIndexPath(forRow: indexPath.row, inSection: indexPath.section)
var result = self.fetchedResultsController_Contact.objectAtIndexPath(modIndexPath) as? Contact
DataManager.instance.deleteContactFromGroup(selectedGroupId, contactId: result?.id as Int)
/*
if (groupIndex != 0 )
{
DataManager.instance.deleteContactFromGroup(groupId, contactId: DataManager.instance.contact_id[indexPath.row])
}
else
{
DataManager.instance.deleteSpecificContact(DataManager.instance.contact_id[indexPath.row])
}
*/
//DataManager.instance.group_id.removeAtIndex(indexPath.row)
//DataManager.instance.group_name.removeAtIndex(indexPath.row)
//DataManager.instance.group_iconId.removeAtIndex(indexPath.row)
//tableView.reloadData()
}
}
...
It was my build setting...
Go to Edit Scheme > Archive > Build Configuration.
Simply change "release" to "debug" and the version for archive will be exactly the same as the version for local debugging.
Now the iTunes version works!!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.