Розбираємося з NSURL / NSURLComponents

       Від перекладача: У світлі останніх подій бути розробником на Objective-С стало вже не так модно, деякі вже біжать здавати його в утиль, але я вважаю, що це робити ще зарано, тому дозволю собі поділитися перекладом. Почавши читати оригінал, не ждав нічого нового в, здавалося б, простий і очевидною темі, але в підсумку виніс досить корисних моментів.
 
 
Існують, давайте їх назвемо «одновимірними», типи даних: числа, рядки, що містять в собі по суті кілька значень, які можуть бути вилучені за допомогою математичних дій або простим парсинга. Як приклад можна привести шестнадцатеричную запис кольору # EE8262 , яка містить компоненти для червоного, синього і зеленого кольору, або, наприклад, регулярний вираз, яке за допомогою пари символів повзоляет шукати складні підрядка.
 
Серед всіх «одновимірних» типів даних безумовним переможцем є URI . Посудіть самі, тут в одній человекочітаемой сходинці перебуває достатньо даних, щоб зрозуміти де знаходиться та чи інша інформація, яка була, є або коли-небудь буде на комп'ютері.
 
Зазвичай URI включає в себе наступні компоненти: схему, деяку ієрархічну частина, запит і фрагмент:
 
<scheme name> : <hierarchical part> [ ? <query> ] [ # <fragment> ]

 
Багато протоколи, як наприклад HTTP , описують деяку задану структуру таку як ім'я користувача, пароль, порт і шлях в ієрархічній частини:
                        
foo :/ / username: password @example.com : 8042 / over / there / index . dtb ? type = animal & name = narwhal # nose
scheme username password hostname port path extension query fragment
Для впевненої роботи з мережевим взаємодією необхідно добре знання URL компонентів. Для програміста це означає вільне використання URI компонентів стандартної бібліотеки.
 
У Foundation URL'и представлені класом NSURL .
 
 NSURL зазвичай інстанцірует за допомогою класового методу URLWithString :
 
NSURL *url = [NSURL URLWithString:@"http://example.com"];

Якщо рядок, яку віддаємо, є не валідним URL , то отримаємо nil .
 
 NSString має якийсь рудиментарний функціонал для маніпуляцій з шляхами, про це можна почитати тут (там в тому числі розповідається про те, що Apple радить переходити від NSString до NSURL-like API для таких класів як NSFileManager ). На жаль, міграція від NSString до NSURL не йде так гладко, як хотілося б. Hecмотря на те, що перетворення з NSString в NSURL не найзручніший крок, це — правильно. Якщо значення — URL , воно повинно зберігатися і передаватися як NSURL ; використання класу не за призначенням — ознака ліні і приклад поганого дизайну API .
 
 
речі, що думаєте щодо використання @ @ як литерала для NSURL (тобто @ @ «example.com »)?
Також у NSURL є класовий метод + URLWithString: relativeToURL: , який використовується для створення URL з рядка відносного деякого базового URL. Поведінка цього методу може бути не завжди очевидним у випадку, коли відносний шлях кінчається на `/`
 
Ось кілька прикладів, які покажуть як цей метод працює:
 
 
NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"];

[NSURL URLWithString:@"foo" relativeToURL:baseURL];
// http://example.com/v1/foo

[NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL];
// http://example.com/v1/foo?bar=baz

[NSURL URLWithString:@"/foo" relativeToURL:baseURL];
// http://example.com/foo

[NSURL URLWithString:@"foo/" relativeToURL:baseURL];
// http://example.com/v1/foo

[NSURL URLWithString:@"/foo/" relativeToURL:baseURL];
// http://example.com/foo/

[NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL];
// http://example2.com/

 
 URL Components
 NSURL надає методи доступу до всіх URL компонентам, описаним в RFC 2396 :
 
     
absoluteString
 absoluteURL
 baseURL
 fileSystemRepresentation
 fragment
 host
 lastPathComponent
 parameterString
 password
 path
 pathComponents
 pathExtension
 port
 query
 relativePath
 relativeString
 resourceSpecifier
 scheme
 standardizedURL
 user
 
 
Документацію та приклади можна подивитися в докуменентаціі — це непоганий спосіб познайомитися з усіма компонентами.
 
 
Окремо треба сказати, що хоч ім'я користувача та пароль можна зберігати в URL , краще використовувати NSURLCreditnal або зберігати їх у зв'язці ключів.
 
 NSURLComponents
 NSURLComponents з'явилися в iOS 7 і Mac OS 10.9, чесно кажучи, кращим назвою для цього класу було б NSMutableURL . Через відсутність документації, цей клас став одним з найбільш «секретних» доповнень до Foundation .
 
Інстанси NSURLComponents створюються за допомогою: (+ componentsWithString: і + componentsWithURL: resolvingAgainstBaseURL: ). Само собою можна просто послати alloc і init , без яких або аргументів, щоб створити порожній контейнер.
 
Різниця між NSURL і NSURLComponents в тому, що в останнього властивості змінювані. Це надає безпечний і простий спосіб змінити окремі компоненти в URL :
 
     
scheme
 user
 password
 host
 port
 path
 query
 fragment
 
 
Спроба встановити неправильну схему або вибрати негативне число для порту закінчиться винятком.
Також у NSURLComponents є змінювані percent-encoded варіанти кожного компонента.
 
     
percentEncodedUser
 percentEncodedPassword
 percentEncodedHost
 percentEncodedPath
 percentEncodedQuery
 percentEncodedFragment
 
 
При отриманні цих властивостей ми отримаємо їх в percent-encoded вигляді. Змінюючи ці властивості потрібно віддавати вже заенкоженную сходинку, інакше — виключення. `;` — Є коректним символом, але рекомендується його також енкод для кращої своместімості з NSURL . (-stringByAddingPercentEncodingWithAllowedCharacters: заенкодіт все `;` якщо передати URLPathAllowedCharacterSet )
 
 Percent-Encoding
 NSURL toll-free bridged для CFURLRef . Останній є низькорівневим API на З , який ефективно повторює функціональність NSURL , але за винятком CFURLCreateStringByAddingPercentEscapes і CFURLCreateStringByReplacingPercentEscapesUsingEncoding :
 
 - CFURLCreateStringByAddingPercentEscapes: створює копію рядки, замінюючи конкретні символи на відповідні їм заескейпенние послідовності у відповідній кодуванні.
 
CFStringRef CFURLCreateStringByAddingPercentEscapes (
   CFAllocatorRef   allocator,
   CFStringRef      originalString,
   CFStringRef      charactersToLeaveUnescaped,
   CFStringRef      legalURLCharactersToBeEscaped,
   CFStringEncoding encoding
);

 
 - CFURLCreateStringByReplacingPercentEscapesUsingEncoding: робить все навпаки замінює заескейпенние послідовності на відповідні символи.
 
 
CFStringRef CFURLCreateStringByReplacingPercentEscapesUsingEncoding (
   CFAllocatorRef   allocator,
   CFStringRef      origString,
   CFStringRef      charsToLeaveEscaped,
   CFStringEncoding encoding
);

 
 URL для закладок
Останнє питання, яке хотілося б обговорити — URL'и для закладок, це ті шляхи, які можна використовувати, щоб безпечно посилатися на файли між запусками програми. Можна думати про них як про файлових дескрипторах .
 
 
Закладка — закрита файлова структура, яка укладена в об'єкт NSData , вона описує місце розташування файлу. У той час як шлях і контрольний URL потенційно ненадійні, закладка може бути використана щоб відтворити URL , якщо навіть файл був переміщений або перейменований.
 
Більше про посилання можна прочитати в «Locating Files Using Bookmarks» з яблучної документації.
  
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.