2017-04-21 8 views
0

먼저 내 앱과 해당 흐름을 설명하겠습니다. 앱이 열리고 사용자가 프로필을 만듭니다 (모든 데이터는 [String: Any] 유형의 사전에 저장 됨). 사용자가 만들기를 클릭하면 콘솔 화면 (사용자가 입력 한 정보의 일부 (예 : segue을 통해 이름이 표시된 부분)을 표시)로 보냅니다. 그들의 프로필 (이름, 무게, 주소 등)을 편집 할 수있는 탭. 사용자가 정보 (이름, 체중 등을 변경하기 위해)를 편집하면 콘솔 페이지에 표시된 정보도 업데이트해야합니다.스위프트 : UITabViews 간 데이터 전달 및 데이터에 대한 전역 액세스 허용

내 주요 질문은 데이터를 모든 탭보기에서 보편적으로 사용할 수 있도록 구성하는 방법입니다. 보다 구체적으로, 데이터는 데이터의 인스턴스 또는 사본이 아닙니다. 모든 변수가 저장된 Person 클래스를 만들었습니다 (firstName, lastName 등). UIViewController 클래스 선언 전에 person 클래스의 인스턴스를 변수로 선언하려고했지만 UITextField.text 속성을 사용할 수 없습니다. 왜냐하면이 클래스는 아직 만들어지지 않았기 때문에 ...?). 여기

난 당신의 모든 것을이 viewController를 서브 클래스로 데이터를 전송하고 보편적으로 사용하도록 할 수 있습니다 읽었습니다 때문에 나는 또한 TabBarViewControllerUITabBarController를 서브 클래 싱 한

class Person { 

    var firstName: String 
    var lastName: String 
    var phoneNumber: String 
    var weight: Int 
    var gender: String 
    var streetAddress: String 
    var cityState: String 

    init(firstName: String, lastName: String, phoneNumber: String, weight: Int, gender: String, streetAddress: String, cityState: String) { 
     self.firstName = firstName 
     self.lastName = lastName 
     self.phoneNumber = phoneNumber 
     self.weight = weight 
     self.gender = gender 
     self.streetAddress = streetAddress 
     self.cityState = cityState 
    } 
} 

... 내 사람 클래스입니다 묻힌 탭. 나는 그것이 어떻게 작동하는지에 관해서는 손해보고있다.

나는 아마도 반복적 인 질문을하기 위해 사과합니다 ... 나는 이것을 보았고 이것에 대해 조사했는데 나의 특별한 경우에 적합한 해결책을 찾지 못했습니다.

이 ... CoreData로 데이터를 저장하는 코드를 업데이트

guard let appDelegate = 
     UIApplication.shared.delegate as? AppDelegate else { 
      return 
    } 
    let managedContext = appDelegate.persistentContainer.viewContext 
let userInfo = PInfo(firstName: firstNameField.text, lastName: lastNameField.text, cityState: cityStateField.text, streetAddress: streetAddressField.text, gender: genderInputField.text, userWeight: 200) 

save(withPersonInfo: userInfo, withContext: managedContext) 

나는 다양한 viewControllers의 데이터에 액세스 할 수있어, 그러나 이상적으로 ... 단일 항목 배열로 나에게 다시 제공, 나는 쉽게 그들을 표시하도록 설정할 수 있으며 Edit ProfileviewController에서 편집 할 수 있도록 key:value 쌍으로 지정하고 싶습니다.

감사합니다!

답변

0

하나의 솔루션은 Delegates입니다. 데이터를 가져 오는 클래스는 위임자와 해당 위임자를 구독하려는 다른 사용자를 설정합니다.

사실 : 나는 Delegate + CoreData을 사용하면 문제를 줄일 수 있다고 생각합니다. 데이터를 듣고 해당 데이터를 저장했습니다. 이제 다른 컨트롤러 할 것입니다 빠른

일부 코드 (핵심 데이터가 하나의 사용자 시나리오에 대한 너무 빨리 사람입니다 :)) 가져 오기 :

class PersonDetail: NSManagedObject { // this is how your coreData's Entity should look like 
    @NSManaged public var firstname: String? 
    @NSManaged public var lastname: String? 

    // add the other fields, such as weight 

    @nonobjc public class func fetchRequest() -> NSFetchRequest<PersonDetail> { 
     return NSFetchRequest<PersonDetail>(entityName: "PersonDetail") 
    } 
} 
// This struct would to get the data from the user 
struct PInfo { 
    var firstname:String? 
    var lastname:String? 
} 
// this function would get an instance of that PInfo 
// for example var p = PInfo(firstname:"Stack",lastname:"Overflow") 

func save(withPersonInfo p:PInfo, withContext context:NSManagedObjectContext) { 
    let entityDescription = NSEntityDescription.entity(forEntityName: "PersonDetail", in: context) 
    let managedObject = NSManagedObject(entity: entityDescription!, insertInto: context) as! PersonDetail 
    // this is where I am passing data into the entity 
    managedObject.firstname = p.firstname 
    managedObject.lastname = p.lastname 

    try? context.save() // use the proper do {} catch, I was saving time lol :) 

} 
// when you fetch from coreData you have an instance of PInfo 

func fetchSingleUser(withContext context:NSManagedObjectContext) -> PInfo { 
    let request:NSFetchRequest<PersonDetail> = PersonDetail.fetchRequest() 
    let coreData_items = try? context.fetch(request) 

    guard let items = coreData_items, 
     let firstItem = items.first // since we only have one user 
     else { fatalError("Error while querying") } 

    return PInfo(firstname: firstItem.firstname, lastname:firstItem.lastname) 
} 
+0

그래서 내가 CoreData' 내가 여러'attributes'이 있기 때문에 여기에 좋은 생각입니다'사용하여 생각 . 배열로 저장할 데이터를 가져 왔지만 사전으로 저장하려면 어떻게해야합니까? 나는 plist를 사용하기 위해 읽었지만'CoreData'가 사전을 다룰 수 있어야한다고 생각한다. 나는 원래 데이터를'CoreData' 배열에 저장하는 코드를 제공하기 위해 원래의 질문을 업데이트했다 ... – szady

+0

나는 약간의 코드를 추가했지만 대신 간단한'struct'를 사용했다. 당신은 그 구조체의 새로운 인스턴스 인 @RyanSady를 가져옵니다. – Lamar

+0

@Lamar! 데이터를 저장하려고 할 때'nil '을 찾는 문제가 있습니다. 코어 데이터가 새롭고 작동 원리가 어디에서 왔는지는 잘 모르겠습니다 ... 데이터를 저장하는 데 사용하는 코드로 원래 질문을 업데이트했습니다. 'PersonDetail'과'PInfo' 클래스에'cityState''streetAddress''gender'와'userWeight' 변수를 추가했습니다. – szady

1

한 아주 쉬운 해결책이 앱 대리자를 제공하는 것입니다 person 빈 상태 (empty)의 Person로서 초기화 된 프로퍼티. 이것은 모든 클래스는 해당 속성에 액세스 할 수 있습니다 때문에 문제 해결 :

let p = (UIApplication.shared.delegate as! AppDelegate).person 

또한, p은 참조로이 사람이 취득을, 그래서 그 속성에 대한 변경 사항은 (볼 준비가 다시 person 특성 자체에 반영됩니다 그리고 다음 뷰 컨트롤러에 의해 변이).구성 할 경우에만 사용자가 있기 때문에

더 정교한, 만족 솔루션은 Person 클래스 자체는 싱글로 shared 사람 인스턴스를 분배해야하는 것입니다. (. 스위프트의 싱글 톤을 구현하는 방법에 대한 자세한 내용은 SO에 대한 검색을 수행) 다시 말하지만,이 싱글은 보편적으로 사용할 수 있습니다 :

let p = Person.shared()