tam. Jestem początkującym w Swift i próbuję przekonwertować starszy program na Swift3. Udało mi się naprawić kilka błędów, ale nie mogę uruchomić tej funkcji.
fileprivate func extractEntitlements(_ entitlementData: Data) -> NSDictionary? {
var originalEntitlementsData = entitlementData
let xmlStart = "<?xml".data(using: String.Encoding.ascii, allowLossyConversion: true)
let bytes = (originalEntitlementsData as NSData).bytes
for i in 0...(originalEntitlementsData.count - xmlStart!.count) {
if memcmp((xmlStart! as NSData).bytes, bytes + i, Int(xmlStart!.count)) == 0 {
let end = originalEntitlementsData.count - i
**originalEntitlementsData = originalEntitlementsData.subdata(in: NSMakeRange(i, end))**
break;
}
}
return NSString(data: originalEntitlementsData, encoding: String.Encoding.ascii.rawValue)?.propertyList() as? NSDictionary
}
Oto błąd, który otrzymuję:
Jest wiele pytań dotyczących tego błędu, ale nie udało mi się wdrożyć rozwiązania. Wszelkie wskazówki dotyczące dalszego postępowania?
Dzięki chłopaki!
Odpowiedzi:
3 dla odpowiedzi № 1Zakresy są bardziej skomplikowane i prostsze jednocześnie.
Chcesz subdata(in: start..<end)
, co sprawia, że Range<Int>
, jakiego typu potrzebujesz. Jednak w tym przypadku start
i end
odnoszą się do początkowych i końcowych indeksów zakresu, a nie do lokalizacji i długości, gdy przechodzisz do NSMakeRange()
.
2 dla odpowiedzi nr 2
Jak już powiedział @jrturton, subdata(in:)
bierze Range<Int>
argument, tak powinno być
originalEntitlementsData = originalEntitlementsData.subdata(in: i..<i+end)
w Twoim przypadku. Pamiętaj jednak, że wszystkie konwersje do NSData
, biorąc .bytes
, wyraźna pętla i memcmp
nie są potrzebne, jeśli ty skorzystać z istniejącego range(of:)
metoda Data
:
var originalEntitlementsData = entitlementData
let xmlStart = "<?xml".data(using: .utf8)!
if let range = originalEntitlementsData.range(of: xmlStart) {
originalEntitlementsData = originalEntitlementsData.subdata(in: range.lowerBound..<originalEntitlementsData.endIndex)
// Alternatively:
// originalEntitlementsData.removeSubrange(0..<range.lowerBound)
}