2014-10-22 18 views
6

adında bir üye yok. Rozetteki değeri bir uzak bildirimin userInfo sözlüğünden çıkarmaya çalışıyorum. Pek çok gönderi okudum ve sorunumun bir çözümünü buldum ama kesinlikle memnun değilim! Ben aşağıdakileri yapmak istiyorum { aps = { badge = 7 } }Swift: '(NSObject, AnyObject)' 'subscript'

bu numarayı çıkarmak için '7' benim userInfo üzerinden: Yani burada

benim veri yapısı (kötünün çizgiler kaldırılmış) 'dir

self.updateAppIcon(userInfo["aps"]["badge"] as? Int) 

Ama

Swift: tabii aşağıdaki hatayı alıyorum

'(NSObject, AnyObject)' adlı bir üye sahip değil 'simge'

Yanılmıyorsam, [], başka bir sözlük olarak yorumlanamayan bir AnyObject döndürmesidir. Daha seksi bir şekilde

func handleRemoteNotifiation(userInfo: [NSObject : AnyObject]) { 

    if let aps: AnyObject = userInfo["aps"] { 
     if let apsDict = aps as? [String : AnyObject]{ 
      if let badge: AnyObject = apsDict["badge"] { 
       self.updateAppIconBadgeNumber(badge as? Int) 
      } 
     } 
    } 
} 

func updateAppIconBadgeNumber(number: Int?) { 
    // do stuff here 
} 

Ama ciddi ... Ben yapabilirdi: Aşağıdaki yapmak olacaktır

bir çalışma çözüm? Daha az satır, daha az cümle, daha az atış, vb. Bu kolay bir şeyin "kod-karmaşık" bir çözümdür.

Teşekkür

cevap

9

kısa biridir: "Optional Chaining" adlandırılır

// Xcode 6.0.1 
func handleRemoteNotifiation(userInfo: [NSObject : AnyObject]) { 
    if let badge = [userInfo["aps"]?["badge"]][0] as? Int { 
     self.updateAppIconBadgeNumber(badge) 
    } 
} 

// Xcode 6.1 
func handleRemoteNotifiation(userInfo: [NSObject : AnyObject]) { 
    if let badge = userInfo["aps"]?["badge"] as? Int { 
     self.updateAppIconBadgeNumber(badge) 
    } 
} 

?["aps"] ile ["badge"]. userInfo["aps"]nil'u döndüğünden buna ihtiyacınız var. Ve her AnyObject her biri 'subscript' üyesine sahip olduğundan [String : AnyObject]'a yüklemeniz gerekmez. Biz Xcode 6.0.1 yılında [ ... ][0] ihtiyaç Neden

Ve ... Bilmiyorum edilir :(.a hata belki. Cevabınız için

+1

Çok teşekkürler!Bu "İsteğe Bağlı Zincirleme" hakkında hiçbir fikrim yoktu. Çözümünüzün ve bağlantınızın her ikisi için teşekkürler! –

3

Sen coleascing operatör nil kullanabilir ve kısa hale ancak okunabilirliği gevşek olabilir başladı. Böyle yöntemin tek satırı sürümü,

func handleRemoteNotification(userInfo: [NSObject : AnyObject]) { 
    if let badge = ((userInfo["aps"] as? [String: AnyObject]) ?? ([String: AnyObject]()))["badge"] as? Int{ 
     self.updateAppIconBadgeNumber(badge) 
    } 
} 

varsa Sen typealias [Dize: AnyObject] olabilir ve onu biraz daha okunabilir görünmesi.

typealias Dict = [String: AnyObject] 
func handleRemoteNotifiation(userInfo: [NSObject : AnyObject]) { 
    if let badge = ((userInfo["aps"] as? Dict) ?? Dict())["badge"] as? Int{ 
     self.updateAppIconBadgeNumber(badge) 
    } 
} 
+0

Teşekkür, bu aslında hem mükemmel çalışıyor ama vardır diyelim ki, daha az okunabilir… @rintaro tarafından verilen cevap bana göre daha iyi görünüyor, ama bana açıklayabilir ya da bu “nil coleascing operatörü” ile ilgili bir bağlantıyı paylaşabilir mi? ”, bunun ne hakkında olduğu hakkında hiçbir fikrim yok. –

+0

The nil birleştirme operatörü: '' Apple'ın iBook'unda ayrıntılı olarak açıklanmıştır.Ben SO yorumunda alıntı yapamıyorum, ama kitabın ne dediğine dair doğrudan bir kopya: Nil birleştirme operatörü '(a ?? b) 'bir değer içeriyorsa isteğe bağlı bir a açar veya bir sıfır ise bir varsayılan değer b döndürür. a ifadesi her zaman isteğe bağlı bir türdür. İçinde a. Nil birleştirme işleci aşağıdaki kod için kısaltılmıştır: 'a! = Nil? Bir! : b' – ArtSabintsev