2016-10-30 7 views
0

Ich habe meine App auf Swift 3 und Xcode 8.1 aktualisiert. Es gibt einen verblüffenden Fehler nach dieser Aktualisierung noting: Command failed due to signal: Segmentation fault: 11 auf der FriendsViewController.swift, aber es gibt keine anderen Anzeichen von Fehler.Xcode 8.1 Befehl fehlgeschlagen wegen Signal: Segmentierungsfehler: 11

Wie kann das gelöst werden?

Aktualisiert: Added FriendsViewController-Code

import UIKit 
import Contacts 
import ContactsUI 
import Firebase 
import FBSDKCoreKit 

// Allowing clean removal of objects 
extension RangeReplaceableCollection where Iterator.Element : Equatable { 

    // Remove first collection element that is equal to the given `object`: 
    mutating func removeObject(_ object : Iterator.Element) { 
     if let index = self.index(of: object) { 
      self.remove(at: index) 
     } 
    } 
} 

// For searching 
extension FriendsViewController: UISearchResultsUpdating { 

    // must implement to conform to the UISearchResultsUpdating protocol. 
    // As well as the scope narrowing 
    func updateSearchResults(for searchController: UISearchController) { 
     let searchBar = searchController.searchBar 
     let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex] 
     filterContentForSearchText(searchController.searchBar.text!, scope: scope) 
    } 
} 

extension FriendsViewController: UISearchBarDelegate { 
    // This delegate methods gets called when the user switches the scope in the scope bar. 
    // When that happens, you want to redo the filtering, 
    func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) { 
     filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope]) 
    } 
} 

class FriendsViewController: UITableViewController, CNContactPickerDelegate { 

    // MARK: Properties 
    var firebaseMainURL: String! 
    @IBOutlet weak var menuButton: UIBarButtonItem! 
    var contacts = [CNContact]() 
    var friends: [Friend] = [] 
    var mappedFriends: [Friend] = [] 
    var filterMappedFriends: [Friend] = [] 
    var feastGlobalRef = FeastGlobal.sharedInstance 
    let rootRef = FIRDatabase.database().reference() 

    // Ensuring Serial queue 
    let queue = DispatchQueue(label: "DISPATCH_QUEUE_SERIAL", attributes: []) 

    // Adding search 
    let searchController = UISearchController(searchResultsController: nil) 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     if revealViewController() != nil { 
      menuButton.target = revealViewController() 
      menuButton.action = #selector(SWRevealViewController.revealToggle(_:)) 
      view.addGestureRecognizer(self.revealViewController().panGestureRecognizer()) 

     } 

     // Creating the search bar, decides when to show and hide results 
     searchController.searchResultsUpdater = self 
     searchController.dimsBackgroundDuringPresentation = false 
     definesPresentationContext = true 
     tableView.tableHeaderView = searchController.searchBar 

     // Adding the scope bar and buttons: 
     searchController.searchBar.scopeButtonTitles = ["All", "Friend", "A User", "Not User"] 
     searchController.searchBar.delegate = self 

     // Main mapping action 
     self.mapContactsToPresentFriends(feastGlobalRef.userID) 

    } 

    override func viewWillAppear(_ animated: Bool) { 
     //self.clearsSelectionOnViewWillAppear = self.splitViewController!.collapsed 
     super.viewWillAppear(animated) 
    } 

    func findContacts() -> [CNContact] { 
     let store = CNContactStore() 

     let keysToFetch = [CNContactFormatter.descriptorForRequiredKeys(for: .fullName), 
          CNContactImageDataKey, 
          CNContactPhoneNumbersKey] as [Any] 

     let fetchRequest = CNContactFetchRequest(keysToFetch: keysToFetch as! [CNKeyDescriptor]) 

     var contacts = [CNContact]() 

     do { 
      try store.enumerateContacts(with: fetchRequest, usingBlock: { (contact, stop) -> Void in 
       contacts.append(contact) 
      }) 
     } 
     catch let error as NSError { 
      print(error.localizedDescription) 
     } 

     return contacts 
    } 

    // MARK: - Table View 

    override func numberOfSections(in tableView: UITableView) -> Int { 
     return 1 
    } 

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

     if searchController.isActive && searchController.searchBar.text != "" { 
      return filterMappedFriends.count 
     } 

     return self.mappedFriends.count 
    } 

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 
     let friend: Friend 

     //let contact = contacts[indexPath.row] as CNContact 
     let contact = mappedFriends[indexPath.row] as Friend 

     // Getting phone number (default to first phone number present): 
     let phoneNumber = contact.phoneNumber 

     // If searching, then replace 
     if searchController.isActive && searchController.searchBar.text != "" { 
      friend = filterMappedFriends[indexPath.row] 
     } else { 
      friend = mappedFriends[indexPath.row] 
     } 

     // Conditional given relationship: 
     var status: String! 

     status = { 
      switch friend.statusSort { 
      case 0: 
       return "Invite to Feast" 
      case 1: 
       return "Friend them" 
      default: 
       return "" // they are a friend 
      } 
     }() 

     // Update the rows with the proper object 
     cell.textLabel!.text = "\(friend.name) \(friend.userName)" 
     cell.detailTextLabel?.text = "\(status)" 
     return cell 
    } 

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 

     // Ensure controller knows which dataset to pull from, 
     // so detail view is correct 
     var friendChat: Friend! 
     if searchController.isActive && searchController.searchBar.text != "" { 
      friendChat = filterMappedFriends[indexPath.row] 
     } else { 
      friendChat = mappedFriends[indexPath.row] 
     } 

     // Now set the conditional cases: if a friend then chat, if user then friend request if not user then can invite them: 
     if(friendChat.statusSort == 2) { 

      self.performSegue(withIdentifier: "showIndividualChat", sender: self) 

     } else if (friendChat.statusSort == 1) { 

      let formatterShortDate = Date().dateStringWithFormat("yyyy-MM-dd HH:mm:ss") 

      let myFriendPath = rootRef.child("friends").child(FeastGlobal.sharedInstance.userID) 

      let friendFriendsPath = rootRef.child("friends").child(friendChat.userID) 

      let friendInviteSync = rootRef.child("friendInviteNeedSync").child(friendChat.userID) 

      // 
      let friendsObject = [ 
       "confirmed" : true, 
       "phoneNumber" : friendChat.phoneNumber, 
       "selfSendRequest" : true, 
       "timeInvited": formatterShortDate, 
       "userName": friendChat.userName 
      ] 


      let myObject = [ 
       "confirmed" : true, 
       "phoneNumber" : FeastGlobal.sharedInstance.phoneNumber, 
       "selfSendRequest" : false, 
       "timeInvited": formatterShortDate, 
       "userName": FeastGlobal.sharedInstance.userName 
      ] 

      let friendInviteObject = [ 
       FeastGlobal.sharedInstance.userID : FeastGlobal.sharedInstance.userName 
      ] 

      queue.async { 
       myFriendPath.child(friendChat.userID).setValue(friendsObject) 
       friendFriendsPath.child(FeastGlobal.sharedInstance.userID).setValue(myObject) 
       friendInviteSync.setValue(friendInviteObject) 

      } 

      queue.async { 
       friendFriendsPath.child(FeastGlobal.sharedInstance.userID).setValue(myObject) 
      } 

      queue.async { 
       self.mapContactsToPresentFriends(self.feastGlobalRef.userID) 
      } 


      print("Can invite to be friend") 

     } else if (friendChat.statusSort == 0) { 

      print("Invite to Feast") 

     } 
    } 


    func contactPicker(_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty) { 
     let contact = contactProperty.contact 
     let phoneNumber = contactProperty.value as! CNPhoneNumber 

     print(contact.givenName) 
     print(phoneNumber.stringValue) 
    } 

    // Method to match contacts with Firebase db friends: 
    func mapContactsToPresentFriends(_ usersSyncID: String) { 

     // Reset the data: 
     self.mappedFriends.removeAll() 
     self.friends.removeAll() 

     // Use the queue (defined above) and "dispatch_async" to schedule the async actions, synchornously 
     // First 
     queue.async { 
      print("start 1") 

       self.contacts = self.findContacts() 

      print("end 1") 

     } 

     // Second 
     queue.async { 

      let friendsURL = self.rootRef.child("friends").child(usersSyncID) // Firebase(url: firebaseMainURL + "friends/" + usersSyncID) 

      var contactNumber: String? 

      friendsURL.observeSingleEvent(of: .value, with: { snapshot in 

       print("start 2") 
       for oneSnapshot in snapshot.children { 

        for oneContact in self.contacts { 

         for oneContactPhoneNum in oneContact.phoneNumbers { 

          let phoneNumber = oneContactPhoneNum.value 

          contactNumber = phoneNumber.stringValue 

          // Clean the number 
          let stringArray = contactNumber!.components(
           separatedBy: CharacterSet.decimalDigits.inverted) 
          let newString = "1" + stringArray.joined(separator: "") 

          let firebaseFriendNumber = (oneSnapshot as AnyObject).value["phoneNumber"] as! String 
          print("Contacts number: " + newString) 

          print("Firebase number: " + firebaseFriendNumber) 

          if newString == firebaseFriendNumber { 
           print("friend added") 

           self.friends.append(Friend(userName: oneSnapshot.value["userName"] as! String,phoneNumber: firebaseFriendNumber, status: "Friend", statusSort: 2, name: oneContact.givenName, userID: oneSnapshot.key)) 

           // Remove that contact 
           self.contacts.removeObject(oneContact) 
          } 
         } 
        } 
       } 
       print("end 2") 

       print("start 3") 
       // Now do the users search: 
       for oneContact in self.contacts { 

        var contactNumber: String 

        let phoneNumber = oneContact.phoneNumbers[0].value 

        contactNumber = phoneNumber.stringValue 

        let stringArray = contactNumber.components(
         separatedBy: CharacterSet.decimalDigits.inverted) 
        let newString = "1" + stringArray.joined(separator: "") 

        //let usersURL: Firebase! = Firebase(url: firebaseMainURL + "presentUserIDUserNameByPhoneNumber/" + newString) 
        let usersURL = self.rootRef.child("presentUserIDUserNameByPhoneNumber").child(newString) 

        // Check db: 
        usersURL.observeSingleEvent(of: .value, with: { snapshot in 
         print("start 3") 

         if snapshot.childrenCount > 1 { 

          // They are users (but not your friends), and remove yourself: 
          if(snapshot.value!["userID"] as! String != FeastGlobal.sharedInstance.userID) { 

           self.friends.append(Friend(userName: snapshot.value!["userName"] as! String, phoneNumber: snapshot.key, status: "A User", statusSort: 1, name: oneContact.givenName, userID: snapshot.value!["userID"] as! String)) 

           let userName = snapshot.value!["userName"] as! String 

           print("Friends name: " + userName) 

          } 

         } else { 

          self.friends.append(Friend(userName: "", phoneNumber: phoneNumber.stringValue, status: "Not User", statusSort: 0, name: oneContact.givenName, userID: "")) 

         } 

         // Remove that contact 
         self.contacts.removeObject(oneContact) 

         // If all done, then sort and load main screen 
         if self.contacts.isEmpty { 

          self.mappedFriends = self.friends.sorted(by: {$0.statusSort > $1.statusSort}) 

          self.tableView.reloadData() 

         } 

         print("end 3") 

        }) 
       } 
      }) 
     } 
    } 

    func indexOfObject(_ object : AnyObject) -> NSInteger { 
     return self.indexOfObject(object) 
    } 

    func friendRequestAction() { 

     // TODO: Should siply be button to add friend, or request to feast. 


    } 

    // Results of search 
    func filterContentForSearchText(_ searchText: String, scope: String = "All") { 
     filterMappedFriends = mappedFriends.filter { Friend in 
      let categoryMatch = (scope == "All") || (Friend.status == scope) 
      return categoryMatch && Friend.name.lowercased().contains(searchText.lowercased()) 
     } 

     tableView.reloadData() 
    } 

    // MARK: - Segues 
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 

     if let indexPath = tableView.indexPathForSelectedRow { 

      // Ensure controller knows which dataset to pull from, 
      // so detail view is correct 
      let friendChat: Friend 
      if searchController.isActive && searchController.searchBar.text != "" { 
       friendChat = filterMappedFriends[indexPath.row] 
      } else { 
       friendChat = mappedFriends[indexPath.row] 
      } 

      // Now set the conditional cases: if a friend then chat, if user then friend request if not user then can invite them: 

      if segue.identifier == "showIndividualChat" { 

       let controller = segue.destination as! IndividualChatController 
       controller.friendChat = friendChat 
       controller.senderId = FeastGlobal.sharedInstance.userID 
       controller.senderDisplayName = FeastGlobal.sharedInstance.userName 
      } 
     } 
    } 


    func getFriends() { 

     let parametersfriend = ["fields": "name,picture.type(normal),gender"] 

     FBSDKGraphRequest(graphPath: "me/friends", parameters: parametersfriend).start(completionHandler: { (connection, user, requestError) -> Void in 
      if requestError != nil { 
       print(requestError) 
       return 
      } 

      print(user) 

     }) 

    } 
} 

Spezifische Objekte:

let friendsObject = [ 
    "confirmed" : true, 
    "phoneNumber" : friendChat.phoneNumber, 
    "selfSendRequest" : true, 
    "timeInvited": formatterShortDate, 
    "userName": friendChat.userName 
] 


let myObject = [ 
    "confirmed" : true, 
    "phoneNumber" : FeastGlobal.sharedInstance.phoneNumber, 
    "selfSendRequest" : false, 
    "timeInvited": formatterShortDate, 
    "userName": FeastGlobal.sharedInstance.userName 
] 
+0

Können Sie Screenshots oder etwas Nützliches anhängen, um diesen Fehler zu beheben? – sohnryang

+0

@sohnryang Ich habe den Fehler – Sauron

+0

hinzugefügt die Typen sind nicht korrekt, auf den Objekten friendsObject und myObject-Wörterbuch. Abhängig von Ihrer letzten Version von Swift haben sie es geändert und Ihr Code geht wahrscheinlich davon aus, dass der Wert dieses Objekts etwas anderes ist. Sie müssen den Wörterbuchwert jetzt explizit in das umsetzen, was Sie erwarten. Wenn Sie den Code aus dem FriendsViewController veröffentlichen, wird es Ihnen helfen, Ihnen zu sagen, wie man die Objekte richtig darstellt – JustinM

Antwort

0

Mit dem Typ Sicherheit schnell, jetzt Sie über Objekte sind vom Typ [String: Alles]. Wenn Sie versuchen, diese Objekte zu verwenden, müssen Sie dem Compiler mitteilen, wie die Typen aussehen.

let friendsObject: [String:Any] = [ 
     "confirmed" : true, 
     "phoneNumber" : friendChat.phoneNumber, 
     "selfSendRequest" : true, 
     "timeInvited": formatterShortDate, 
     "userName": friendChat.userName 
    ] 


    func doSomethingWith(FriendsObj: [String:Any] { 
     guard let confirmed = friendsObject["confirmed"] as? Bool, 
     let phone = friendsObject["phoneNumber"] as? Int, 
     let sendRequest = friendsObject["selfSendRequest"] as? Bool else { return } 

    //Now you can access confirmed, phone, and sendRequest as their native types. 
} 
+0

Vielen Dank für die Antwort, aber ich benutze sie nicht abgesehen von der 'myFriendPath.child (friendChat.userID) .setValue (FreundeObjekt)', es gibt keine anderen Aufrufe an diese Objekte – Sauron

+0

in Ordnung, Entschuldigung, ich könnte nicht mehr Hilfe sein. Du solltest die Fehler erneut posten, damit jemand anderes davon kommt. – JustinM

+0

Weitere Forschungshinweise Dies könnte ein Fehler in der Xcode-Version sein. Es gibt keinen Grund, dass dies fehlschlagen sollte ... – Sauron

Verwandte Themen