Разработка мобильного приложения "Smarty CRM"

Теоретические аспекты использования CRM-систем для повышения эффективности бизнеса. Разработка программно-информационного компонента. Обоснование выбора среды разработки. Описание пользовательского интерфейса и программных модулей, разработка приложения.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 13.10.2016
Размер файла 2,1 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

func setupTableView(){

universalIndexs = []

profileCells.removeAll()

var titles:[String] = []

var colors:[String] = []

var stages:[Stage] = []

if let colorsJSON = UIDataProvider.instance.getUserProfile()?.confStageColors {

let json = JSON(colorsJSON)

colors = json["contacts"].arrayObject as? [String] ?? []

} else {

colors = Constants.defaultStagesColors

}

if let titlesJSON = contact?.group?.stages {

let json = JSON(titlesJSON)

for (index, _) in colors.enumerate() {

let title = json[index]["name"].string

if (title ?? "").isEmpty {

titles.append(Constants.defaultStagesTitles[index])

}

else{ titles.append(title!) }

}

} else {

titles = Constants.defaultStagesTitlesForAll

}

for (index, _) in colors.enumerate() {

let stage = Stage(color: UIColor(rgba: colors[index]), text: titles[index])

stages.append(stage)

}

stagesView.items = stages

stagesView.selectStageHandler = { [weak self] idx in

self?.contact?.stage = Int64(idx)

}

stagesView.multiSelect = false

if let contact = self.contact {

stagesView.selectedItems = [Int(contact.stage)]

}

stagesView.disabled = !editMode

stageCell.addSubview(stagesView)

stagesView.snp_makeConstraints { make in

make.edges.equalTo(stageCell)

}

profileCells.append(stageCell)

manOrganizationCell.customSC.selectedSegmentIndex = contact?.isOrganization ?? false ? 1 : 0

self.contactMode = Bool(contact?.isOrganization ?? false ? 1 : 0)

manOrganizationCell.segmentedValueChanged = { [weak self] index in

self?.contact?.isOrganization = Bool(index)

self?.contactMode = Bool(index)

self?.setupTableView()

self?.setupAdditionalInformation()

}

if editMode{

profileCells.append(manOrganizationCell)

}

photoContactCell.name.enabled = editMode

photoContactCell.email.enabled = editMode && InviteResponse(rawValue: Int(contact?.inviteStatus ?? 0)) == InviteResponse.NeverSend ? editMode : false

photoContactCell.backgroundColor = UIColor(red: 247/255.0 , green: 247/255.0, blue: 247/255.0, alpha: 1.0)

let user = UIDataProvider.instance.getUserProfile()

if let username = user?.username , imageSrc = contact?.imageSrc {

if flag{

photoContactCell.photo.setServerImage(username + imageSrc)

}

}

if let contact = contact{

contact.email = self.contact?.email ?? ""

photoContactCell.email.text = self.contact?.email ?? ""

let name = self.contactMode ? contact.organizationName : contact.name

if editMode{

if name == "" || name == nil {

photoContactCell.name.text = ""

photoContactCell.name.placeholder = self.contactMode ? "profileOrganizationName".localized : "clientCardFIO".localized

}else{

photoContactCell.name.text = self.contactMode ? contact.organizationName : contact.name

}

}else{

if name == "" || name == nil {

photoContactCell.name.text = "manager_no_name".localized

}else{

photoContactCell.name.text = self.contactMode ? contact.organizationName : contact.name

}

}

if editMode{

photoContactCell.sendEmail.hidden = true

photoContactCell.sendEmail.enabled = false

photoContactCell.email.hidden = false

photoContactCell.emailGrayLine.hidden = false

}else{

if (contact.email ?? "").isValidEmail(){

photoContactCell.sendEmail.enabled = true

photoContactCell.sendEmail.hidden = false

photoContactCell.email.hidden = false

photoContactCell.emailGrayLine.hidden = false

}else{

photoContactCell.sendEmail.hidden = true

photoContactCell.sendEmail.enabled = false

photoContactCell.email.hidden = true

photoContactCell.emailGrayLine.hidden = true

}

}

}

photoContactCell.nameDidEditingHandler = { [weak self] name in

if self?.contactMode ?? false{

self?.contact?.organizationName = name

}else{

self?.contact?.name = name

}

if let contact = self?.contact{

UIDataProvider.instance.saveCollectionObject(contact)

}

}

//TODO: убратьдублированиепроверкананачалена nil

photoContactCell.emailDidEditingHandler = { [weak self] email in //TODO: emailEditingHandler

let checkedContact = UIDataProvider.instance.getCollection(CDContact.self,predicate:NSPredicate(format: "email == %@", self?.photoContactCell.email.text ?? ""))

if self?.photoContactCell.email.text?.characters.count == 0{

self?.photoContactCell.emailErrorLabel.snp_updateConstraints{ make in

make.height.equalTo(0)

}

self?.photoContactCell.emailGrayLine.backgroundColor = UIColor(red: 237/255.0 , green: 237/255.0, blue: 237/255.0, alpha: 1.0)//TODO: вынестивконстанты

self?.photoContactCell.email.textColor = UIColor.blackColor()

self?.correctMail = (self?.photoContactCell.email.text?.isValidEmail())!

self?.contact?.email = self?.photoContactCell.email.text

self?.correctMail = true

}else if self?.photoContactCell.email.text?.isValidEmail() == false {

self?.photoContactCell.emailErrorLabel.snp_updateConstraints{ make in

make.height.equalTo(20)

}

// TODO: форматирование

self?.photoContactCell.emailErrorLabel.text = "importErrorMailParse".localized

self?.photoContactCell.emailGrayLine.backgroundColor = UIColor(rgba: "#F58282")

self?.photoContactCell.email.textColor = UIColor(rgba: "#F58282")

self?.correctMail = false

self?.contact?.email = ""

} else if checkedContact.count == 0{

self?.photoContactCell.emailErrorLabel.snp_updateConstraints{ make in

make.height.equalTo(0)

}

self?.photoContactCell.emailGrayLine.backgroundColor = UIColor(red: 237/255.0 , green: 237/255.0, blue: 237/255.0, alpha: 1.0)//TODO: вынестивконстанты

self?.photoContactCell.email.textColor = UIColor.blackColor()

self?.correctMail = (self?.photoContactCell.email.text?.isValidEmail())!

self?.contact?.email = self?.photoContactCell.email.text

self?.correctMail = true

}else{

self?.photoContactCell.emailErrorLabel.snp_updateConstraints{ make in

make.height.equalTo(20)// TODO: константы

}

self?.photoContactCell.emailGrayLine.backgroundColor = UIColor(rgba: "#F58282")

self?.photoContactCell.email.textColor = UIColor(rgba: "#F58282")

self?.correctMail = false

self?.photoContactCell.emailErrorLabel.text = "emailErrorKontakt".localized

}

}

photoContactCell.sendEmailTappedHandler = { [weak self] in

if !(self?.editMode ?? false){

let picker = MFMailComposeViewController()

picker.mailComposeDelegate = self

picker.setToRecipients([self?.contact?.email ?? ""])

self?.findViewController(ContactRootViewController)?.presentVCFromRootVC(picker)

}

}

photoContactCell.changePhotoHandler = { [weak self] in

let status = ConnectionStatusManager.instance.status

if self?.editMode ?? false{

if status == ConnectionStatus.Offline{

let errorAlert = UIAlertController(title: "internetNoConnection".localized, message: nil, preferredStyle: UIAlertControllerStyle.Alert)

let cancelAction: UIAlertAction = UIAlertAction(title: "Ok".localized , style: .Cancel) { action -> Void in

}

errorAlert.addAction(cancelAction)

self?.presentViewController(errorAlert, animated: true, completion: nil)

}else{

let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)

optionMenu.modalPresentationStyle = .Popover

optionMenu.popoverPresentationController?.sourceRect = self?.photoContactCell.bounds ?? CGRect(origin: CGPoint(x:0,y:0),size: CGSize(width: 0,height: 0))

optionMenu.popoverPresentationController?.sourceView = self?.photoContactCell ?? self?.view

optionMenu.addAction(UIAlertAction(title: "takePhotoFromCamera".localized, style: .Default, handler: { [weak self] (action) -> Void in

let imagePicker = UIImagePickerController()

imagePicker.sourceType = .Camera

imagePicker.delegate = self

imagePicker.allowsEditing = false

imagePicker.sourceType = UIImagePickerControllerSourceType.Camera

imagePicker.cameraCaptureMode = .Photo

self?.findViewController(ContactRootViewController)?.presentVCFromRootVC(imagePicker)

}))

optionMenu.addAction(UIAlertAction(title:"loadPhotoFromGallery".localized, style: .Default, handler: { [weak self] (action) -> Void in

let imagePicker = UIImagePickerController()

imagePicker.delegate = self

imagePicker.allowsEditing = false

imagePicker.sourceType = .PhotoLibrary

self?.findViewController(ContactRootViewController)?.presentVCFromRootVC(imagePicker)

}))

optionMenu.addAction(UIAlertAction(title:"addCategoryCancel".localized, style: .Default, handler: { [weak self] (action) -> Void in

}))

self?.navigationController?.presentViewController(optionMenu, animated: true, completion: nil)

}

}

}

profileCells.append(photoContactCell)

photoCellPosition = profileCells.count - 1

phoneCell.valueField.enabled = editMode

phoneCell.typeField.enabled = editMode

phoneCell.callButton.enabled = !editMode

phoneCell.valueField.keyboardType = .PhonePad

phoneCell.backgroundColor = UIColor(red: 247/255.0 , green: 247/255.0, blue: 247/255.0, alpha: 1.0)

var dict = self.contact?.phone as? [String: AnyObject] ?? ["number":"","type": 0]

phoneCell.textEditingHandler = { phone in

dict?["number"] = phone

self.contact?.phone = dict

if let contact = self.contact{

UIDataProvider.instance.saveCollectionObject(contact)

}

}

phoneCell.callTappedHandler = {

if !self.editMode{

if let phoneNumber = (((self.contact?.phone as? [String: AnyObject])?["number"]) as? String) {

let phone = "tel:\(phoneNumber)"

if let url = NSURL(string: phone ) {

if UIApplication.sharedApplication().canOpenURL(url) {

UIApplication.sharedApplication().openURL(url)

}

}

}

}

}

phoneCell.phoneTypeTappedHandler = {

let universalController = UniversalController(title: "phoneType".localized, variants: Constants.phoneTypes)

self.navigationController?.pushViewController(universalController , animated: true)

universalController.buttonTappedHandler = { [weak self] index in

self?.phoneCell.typeField.titleLabel?.text = Constants.phoneTypes[index]

dict?["type"] = index

self?.contact?.phone = dict

if let contact = self?.contact{

UIDataProvider.instance.saveCollectionObject(contact)

}

}

}

if let contact = contact{

let phone = (contact.phone as? [String: AnyObject])?["number"] as? String ?? ""

let phoneType = (contact.phone as? [String: AnyObject])?["type"] as? Int ?? 0

dict!["number"] = phone

self.contact?.phone = dict

if (phone == "") && (!editMode) {

phoneCell.valueField.hidden = true

}else{

if phone == "" {

phoneCell.valueField.hidden = false

phoneCell.valueField.placeholder = "clientPhones".localized

phoneCell.typeField.setTitle(convertPhoneType(phoneType), forState: .Normal)

profileCells.append(phoneCell)

}else{

phoneCell.valueField.hidden = false

phoneCell.valueField.text = phone

phoneCell.typeField.setTitle(convertPhoneType(phoneType), forState: .Normal)

profileCells.append(phoneCell)

}

}

}

groupCell.accessoryType = editMode ? .DisclosureIndicator : .None

if let contact = contact{

groupCell.name.text = "leftBarMenuGroupTitle".localized

if group?.title == nil{

groupCell.status.text = contact.group?.title ?? "this_all".localized

}else{

groupCell.status.text = group?.title ?? "this_all".localized

}

}

profileCells.append(groupCell)

self.universalIndexs?.append(profileCells.count - 1)

typeContactCell.accessoryType = editMode ? .DisclosureIndicator : .None

if let contact = contact{

typeContactCell.name.text = "clientCardTypeContact".localized

typeContactCell.status.text = contact.isImportant ?? false ? "clientCardTypeKey".localized : "clientCardTypeNormal".localized

}

profileCells.append(typeContactCell)

self.universalIndexs?.append(profileCells.count - 1)

typeCell.separatorInset = UIEdgeInsetsMake(0.0, typeCell.bounds.size.width, 0.0, 0.0)

if let contact = contact{

typeCell.customSC.selectedSegmentIndex = Int(contact.status)

typeCell.customSC.enabled = !(contact.isOverLimit ?? false)

}

typeCell.segmentedValueChanged = { [weak self]index in

self?.contact?.status = Int64(index)

if let contact = self?.contact{

UIDataProvider.instance.saveCollectionObject(contact)

}

}

profileCells.append(typeCell)

for (index,_) in relatedElemetsCount.enumerate() {

let relatedCell = setupRelatedCell(index)

profileCells.append(relatedCell)

}

countryCell.accessoryType = editMode ? .DisclosureIndicator : .None

if let contact = contact{

countryCell.name.text = "clientCardPersonalDataCountry".localized

countryCell.status.text = contact.country?.localized ?? "clientCardPersonalDataCountryEmpty".localized

}

profileCells.append(countryCell)

self.universalIndexs?.append(profileCells.count - 1)

let cityCell = InformationCell()

cityCell.valueField.textColor = UIColor.blackColor()

cityCell.callButton.hidden = true

cityCell.backgroundColor = UIColor.whiteColor()

cityCell.typeField.hidden = self.contact?.city?.isEmpty ?? true

cityCell.typeField.setTitle("clientCardPersonalDataCity".localized, forState: .Normal)

cityCell.valueField.userInteractionEnabled = editMode

if let contact = contact{

if (contact.city ?? "").isEmpty && (!editMode) {

cityCell.hidden = true

} else{

if contact.city == "" || contact.city == nil {

cityCell.valueField.placeholder = "clientCardPersonalDataCity".localized

profileCells.append(cityCell)

}else{

cityCell.valueField.text = contact.city

profileCells.append(cityCell)

}

}

}

cityCell.textEditingHandler = { text in

self.contact?.city = text

if self.contact?.city == "" || self.contact?.city == nil {

cityCell.valueField.placeholder = "clientCardPersonalDataCity".localized

}

cityCell.typeField.hidden = self.contact?.city?.isEmpty ?? true

if let contact = self.contact {

UIDataProvider.instance.saveCollectionObject(contact)

}

}

if let contact = contact{

if (contact.notes ?? "").isEmpty && (!editMode) {

noteCell.hidden = true

} else{

if contact.notes == "" || contact.notes == nil {

noteCell.descriptionField.placeholder = "tasksPreReminderDesc".localized

}else{

noteCell.descriptionField.text = contact.notes

}

noteCell.hidden = false

profileCells.append(noteCell)

noteCellPosition = profileCells.count - 1

}

}

noteCell.descriptionField.userInteractionEnabled = editMode

noteCell.beginEditingHandler = {

if let indexPath = self.tableView.indexPathForCell(self.noteCell){

self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Bottom, animated: true)

}

}

noteCell.descriptionChanged = { [weak self] text in

self!.contact?.notes = text

self!.textViewHeight = self!.noteCell.descriptionField.contentSize.height + CGFloat(Constants.additionalHeightForMultiLineFields)

print(self!.noteCell.descriptionField.contentSize.height)

self!.tableView.beginUpdates()

self!.scrollToCursorForTextView(self!.noteCell.descriptionField)

self!.tableView.endUpdates()

}

}

func scrollToCursorForTextView(textView: UITextView) {

var cursorRect = textView.caretRectForPosition(textView.selectedTextRange!.start)

cursorRect = self.tableView.convertRect(cursorRect, fromView: textView)

if !self.rectVisible(cursorRect) {

cursorRect.size.height += 8

// To add some space underneath the cursor

self.tableView.scrollRectToVisible(cursorRect, animated: true)

}

}

func setupRelatedCell(index: Int) -> RelatedCell{

let relatedCell = RelatedCell()

relatedCell.badge.text = editMode ? "+" : String(relatedElemetsCount[index])

relatedCell.titleLabel.text = Constants.relatedTitles[index]

self.universalIndexs?.append(profileCells.count - 1)

return relatedCell

}

func rectVisible(rect: CGRect) -> Bool {

var visibleRect = CGRect()

visibleRect.origin = self.tableView.contentOffset

visibleRect.origin.y += self.tableView.contentInset.top

visibleRect.size = self.tableView.bounds.size

visibleRect.size.height -= self.tableView.contentInset.top+self.tableView.contentInset.bottom

return CGRectContainsRect(visibleRect, rect)

}

func imagePickerControllerDidCancel(picker: UIImagePickerController) {

picker.dismissViewControllerAnimated(true, completion: nil)

}

var flag = true

func imagePickerController(picker: UIImagePickerController,

didFinishPickingMediaWithInfo info: [String: AnyObject]){

let image = info[UIImagePickerControllerOriginalImage] as! UIImage?

if var theImage = image{

if let contact = self.contact{

if let syncManager = AuthorizationManager.instance.syncManager{

theImage = resizeImage(theImage,newWidth: 100)

syncManager.uploadImage(theImage, forObject: contact)

.then { imageSrc -> Promise<Void> in

contact.imageSrc = imageSrc

UIDataProvider.instance.saveCollectionObject(contact)

return Promise()

}

photoContactCell.photo.setImage(theImage, forState: .Normal)

flag = false

}

}

}

picker.dismissViewControllerAnimated(true, completion: nil)

}

func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage {

let newHeight = newWidth

UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight))

image.drawInRect(CGRectMake(0, 0, newWidth, newHeight))

let newImage = UIGraphicsGetImageFromCurrentImageContext()

UIGraphicsEndImageContext()

return newImage

}

func convertPhoneType(type: Int) -> String{

return Constants.phoneTypes[type]

}

func tapEditContact(sender: UIBarButtonItem) {

hide = false

editMode = true

let saveContact = UIBarButtonItem(title: "doneButton".localized, style: .Plain, target: self, action: #selector(saveChanges))

self.navigationItem.rightBarButtonItem = saveContact

setupTableView()

setupAdditionalInformation()

commentsCellPosition = additionalInformation.count

tableView.reloadData()

}

func saveChanges(sender: UIBarButtonItem) {

self.view.endEditing(true)

editMode = false

contact!.additionalComment = contact!.additionalComment ?? ""

self.saveAdditionalInformation()

setupAdditionalInformation()

hide = additionalInformationCells.count == 1

if !correctMail {

self.contact?.email = ""

photoContactCell.email.text = ""

}

self.photoContactCell.emailErrorLabel.snp_updateConstraints{ make in

make.height.equalTo(0)

}

self.photoContactCell.emailGrayLine.backgroundColor = UIColor(red: 237/255.0 , green: 237/255.0, blue: 237/255.0, alpha: 1.0)

setupTableView()

tableView.reloadData()

self.navigationItem.rightBarButtonItem = editContact

}

private func editDeadline() {

let alert = UIAlertController(title: "", message: "\n\n\n\n\n\n\n\n\n\n", preferredStyle: .ActionSheet)

let picker = UIDatePicker()

picker.datePickerMode = .Date

picker.date = NSDate(timeIntervalSince1970: contact!.additionalBirthday)

alert.view.addSubview(picker)

alert.addAction(UIAlertAction(title: "clientCardPersonalDataPhoneAdd".localized, style: .Default, handler: { [weak self] _ -> Void in

self!.endEditingDeadline(picker.date.timeIntervalSince1970)

}))

let popover = alert.popoverPresentationController

let cell: UITableViewCell?

if let dateOfBirthdayIndexPath = dateOfBirthdayIndexPath {

cell = tableView.cellForRowAtIndexPath(dateOfBirthdayIndexPath)

} else {

cell = nil

}

popover?.sourceRect = cell?.bounds ?? view.bounds

popover?.sourceView = cell ?? view

self.view.endEditing(true)

self.presentViewController(alert, animated: true, completion: nil)

}

private func endEditingDeadline(newDeadline: Double) {

contact!.additionalBirthday = newDeadline

setupTableView()

setupAdditionalInformation()

tableView.reloadData()

}

override func viewDidDisappear(animated: Bool) {

super.viewDidDisappear(true)

photoContactCell.photo.setImage(UIImage(named: "ava"), forState: .Normal)

NSNotificationCenter.defaultCenter().removeObserver(self)

}

let maxHeightTextView = CGFloat(164)

override func viewDidLayoutSubviews() {

if let note = contact?.notes {

if textViewHeight < 0{

textViewHeight = maxHeightTextView > textViewHeight ? (note.heightWithWidth(view.frame.width , font: UIFont.systemFontOfSize(17))) + 48 : maxHeightTextView

}

}

if let comment = contact?.additionalComment {

if textViewComments < 0{

textViewComments = maxHeightTextView > textViewComments ? (comment.heightWithWidth(view.frame.width , font: UIFont.systemFontOfSize(17))) + 48 : maxHeightTextView

}

}

if let contact = self.contact {

self.stagesView.collectionView.scrollToItemAtIndexPath(NSIndexPath(forItem: Int(contact.stage), inSection: 0), atScrollPosition: .CenteredHorizontally, animated: true)

}

phoneCell.typeField.titleLabel!.frame = CGRectMake(0, 0,120, 34)

}

func socketsChanges() {

if let newContact = CoreDataManager.instance.getObject(CDContact.self, id: contact?.id ?? ""){

contact = newContact

setupTableView()

setupAdditionalInformation()

}

}

override func viewWillAppear(animated: Bool) {

super.viewWillAppear(true)

if let contact = contact{

self.findViewController(ContactRootViewController)?.commentsButton.enabled = !(contact.isOverLimit ?? false)

}

setupTableView()

self.tableView.reloadData()

if let contact = self.contact {

if let name = contact.name where name != "" && !contact.isOrganization {

navigationItem.title = name

} else if let orgName = contact.organizationName where orgName != "" {

navigationItem.title = orgName

} else {

navigationItem.title = "manager_no_name".localized

}

if let isOverLimit = contact.isOverLimit {

self.navigationItem.rightBarButtonItem = editMode ? saveContact : editContact

navigationItem.rightBarButtonItem?.enabled = !isOverLimit

stagesView.disabled = !isOverLimit || editMode

}

}

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(socketsChanges), name: DataChangedBySocketConnection, object: nil)

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillShow), name: UIKeyboardWillShowNotification, object: nil)

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillHide), name: UIKeyboardWillHideNotification, object: nil)

self.navigationItem.rightBarButtonItem = editMode ? saveContact : editContact

if (contact?.email ?? "").isEmpty {

self.correctMail = true

}else if contact?.email?.isValidEmail() == false {

self.correctMail = false

}else{

self.correctMail = true

}

self.findViewController(ContactRootViewController)?.tabBar.selectedItem = nil

self.findViewController(ContactRootViewController)?.editingContact = false

relatedElemetsCount = [self.relatedContacts.count,self.relatedNotes.count,self.relatedTasks.count]

}

override func viewWillDisappear(animated: Bool) {

self.navigationItem.title = ""

super.viewWillDisappear(animated)

ContactRootViewController.instance.editingContact = true

flag = true

self.saveAdditionalInformation()

if let contact = self.contact{

contact.additionalComment = contact.additionalComment ?? ""

hide = additionalInformationCells.count == 1

var rContactsIds:[String] = []

var relatedCon: [String] = []

let notes = UIDataProvider.instance.getCollection(CDNote.self)

let tasks = UIDataProvider.instance.getCollection(CDTask.self)

for relatedContact in relatedContacts{

if relatedContact.id != contact.id! {

rContactsIds.append(relatedContact.id!)

}

}

contact.relatedContacts = rContactsIds

for note in notes {

if relatedNotes.contains(note){

if let relatedList = note.relatedContacts{

relatedCon = relatedList as! [String]

}else{

relatedCon = []

}

if !relatedCon.contains(contact.id!){

relatedCon.append(contact.id!)

}

note.relatedContacts = relatedCon

UIDataProvider.instance.pushCollectionObject(note)

}else{

if deltaRelatedNotes.contains(note){

if let relatedList = note.relatedContacts{

relatedCon = relatedList as! [String]

}else{

relatedCon = []

}

if !relatedCon.contains(contact.id!){

}else{

relatedCon.removeAtIndex(relatedCon.indexOf(contact.id!)!)

}

note.relatedContacts = relatedCon

UIDataProvider.instance.pushCollectionObject(note)

}

}

}

for task in tasks {

if relatedTasks.contains(task){

if let relatedList = task.relatedContacts{

relatedCon = relatedList as! [String]

}else{

relatedCon = []

}

if !relatedCon.contains(contact.id!){

relatedCon.append(contact.id!)

}

task.relatedContacts = relatedCon

UIDataProvider.instance.pushCollectionObject(task)

}else{

if deltaRelatedTasks.contains(task){

if let relatedList = task.relatedContacts{

relatedCon = relatedList as! [String]

}else{

relatedCon = []

}

if !relatedCon.contains(contact.id!){

}else{

relatedCon.removeAtIndex(relatedCon.indexOf(contact.id!)!)

}

task.relatedContacts = relatedCon

UIDataProvider.instance.pushCollectionObject(task)

}

}

}

if !correctMail {

self.contact?.email = ""

photoContactCell.email.text = ""

}

self.photoContactCell.emailErrorLabel.snp_updateConstraints{ make in

make.height.equalTo(0)

}

self.photoContactCell.emailGrayLine.backgroundColor = UIColor(red: 237/255.0 , green: 237/255.0, blue: 237/255.0, alpha: 1.0)

contact.relatedContacts = contact.relatedContacts ?? []

UIDataProvider.instance.pushCollectionObject(contact)

}

}

func mailComposeController(controller: MFMailComposeViewController, didFinishWithResult result: MFMailComposeResult, error: NSError?) {

controller.dismissViewControllerAnimated(true, completion: nil)

}

func keyboardWillShow(notification: NSNotification) {

if let userInfo = notification.userInfo {

if let keyboardSize = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {

tableView.contentInset.bottom = keyboardSize.height

}

}

}

func keyboardWillHide(notification: NSNotification) {tableView.contentInset.bottom = 0}

}

Размещено на Allbest.ru

...

Подобные документы

  • Создание, изучение и разработка приложение на Android. Среда разработки приложения DelphiXE5. Установка и настройка среды программирования. Этапы разработки приложения. Инструменты для упрощения конструирования графического интерфейса пользователя.

    курсовая работа [1,6 M], добавлен 19.04.2017

  • Обзор подходов к разработке музейных приложений с элементами дополненной реальности, формирование требований к ним. Выбор методов разработки приложения, разработка пользовательского интерфейса. Принципы тестирования. Реализация раздела "Распознавание".

    дипломная работа [2,8 M], добавлен 03.07.2017

  • Общая характеристика и структурная схема приложения, требования к нему и функциональные особенности, сферы практического применения. Обоснование выбора языка программирования. Описание интерфейса и инструкция пользователя. Проведение листинга программы.

    дипломная работа [1,0 M], добавлен 10.07.2017

  • Разработка адресных и технических требований к игре. Написание сценария. Общая концепция разработки приложения. Разработка схем алгоритмов приложения. Игровые технологии. Выбор среды и программированного языка. Описание пользовательского интерфейса.

    курсовая работа [1,6 M], добавлен 14.06.2014

  • Разработка программного продукта для экспорта спецификации из приложения PartList. Выбор метода передачи информации в файл, формата для представления. Разработка конвертера, реализация пользовательского интерфейса. Обоснование актуальности разработки.

    дипломная работа [2,6 M], добавлен 25.09.2014

  • Современное состояние рынка мобильных приложений. Основные подходы к разработке мобильных приложений. Обоснование выбора целевой группы потребителей приложения. Этапы проектирования и разработки мобильного приложения для операционной системы Android.

    курсовая работа [987,1 K], добавлен 27.06.2019

  • Разработка программного решения по созданию мобильного приложения. Изучение технологий для разработки приложений. Анализ работы торговых агентов. Обоснование выбора языка программирования. Проектирование интерфейса структуры и верстка, листинг программы.

    дипломная работа [2,2 M], добавлен 08.06.2017

  • Обзор мобильной ОС Android. Выбор инструментов и технологий. Проектирование прототипа графического интерфейса. Характеристика и описание пользовательского интерфейса. Проектирование и разработка базы данных. Определение списка необходимых разрешений.

    курсовая работа [376,6 K], добавлен 13.09.2017

  • Проектирование вариантов использования приложения. Анализ существующей версии приложения. Обоснование выбора инструментальных программных средств. Проектирование интерфейса пользователя. Адаптация под мобильные устройства. Описание программного продукта.

    курсовая работа [2,8 M], добавлен 25.06.2017

  • Проектирование структуры программы, принцип ее работы, сферы практического использования и оценка возможностей. Выбор и обоснование среды программирования. Разработка пользовательского интерфейса и модулей приложения. Проведение тестирования программы.

    курсовая работа [637,7 K], добавлен 14.01.2015

  • Создание автоматизированного рабочего места заместителя заведующего складом. Проектирование базы данных. Разработка программно-информационного ядра системы. Методика разработки клиентского приложения. Разработка организационного компонента системы.

    курсовая работа [1,1 M], добавлен 05.06.2015

  • Обоснование выбора программно-технических средств. Надежность программы и состав технических средств. Разработка структурной схемы программы, алгоритмического и программного интерфейса. Технология разработки интерфейса пользователя и программных модулей.

    дипломная работа [3,2 M], добавлен 22.01.2013

  • Разработка приложения для проверки использования времен глаголов в английском языке. Создание базы данных. Анализ используемых средств для реализации автоматического разбора текста. Проектирование мобильного приложения с помощью диаграмм деятельности.

    дипломная работа [2,6 M], добавлен 13.09.2017

  • Разработка и реализация демонстрационного многопоточного приложения. Выбор основных средств реализации. Описание логики работы приложения и разработка программного обеспечения. Описание пользовательского интерфейса. Реализация потоков в Delphi.

    курсовая работа [462,5 K], добавлен 10.08.2014

  • Исследование спецификации логической игры "Сапёр". Системное и функциональное проектирование приложения. Разработка программных модулей. Обзор классов, необходимых для создания интерфейса данного приложения. Инструменты для реализации логической игры.

    курсовая работа [1,2 M], добавлен 13.01.2016

  • Разработка программного продукта - приложения, позволяющего заносить данные анкетирования в базу данных MS SQL. Описание логики работы приложения, особенности пользовательского интерфейса. Формы просмотра анкет, описание процедур и функций программы.

    курсовая работа [1,2 M], добавлен 16.08.2012

  • Основные инструменты построения Web-приложения. Язык сценариев PHP. Системный анализ предметной области базы данных. Коды SQL запросов на создание таблиц. Разработка Web-приложения. Описание функциональности модулей. Система управления содержимым статей.

    курсовая работа [4,8 M], добавлен 28.04.2014

  • Проектирование удобного приложения для комфортной навигации по файлам облачного хранилища в одном файловом менеджере. Выбор интегрированной среды разработки. Выбор инструментов для визуализации приложения. Выбор средств отслеживания HTTPзапросов.

    курсовая работа [3,6 M], добавлен 16.07.2016

  • Анализ целевой аудитории. Функциональные характеристики пользовательского приложения. Разработка алгоритмов и интерфейса программного продукта, функций рабочей области. Написание скриптов на языке C#. Тестирование программы методом чёрного ящика.

    дипломная работа [1,5 M], добавлен 09.11.2016

  • Требования к аппаратным и операционным ресурсам. Логическая и физическая организация. Состав основных классов проекта. Технико-экономическое обоснование разработки программного средства. Задержки при обработке данных. Разработка интерфейса приложения.

    дипломная работа [4,4 M], добавлен 16.06.2017

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.