Pokazywanie postów oznaczonych etykietą XCode7. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą XCode7. Pokaż wszystkie posty

środa, 25 listopada 2015

Things I've learned while building an iOS SDK

There are times in programming when you think "I wish I knew that from the beginning". Building an SDK is quite different from making an app. You have more things to remember about and the distribution is more tricky. It's also a big responsibility, because if you screw something up, you can't just update right away - you might have a lot of users, and you don't control when they update your library and push to the store. This is a list of my i-wish-i-knews when building the Pulsate SDK. 

My SDK is too big!

I've started building the SDK with writing it from scratch, instead of refactoring the old code. One of my goals was to make the SDK smaller, as it was about 20 mb. When I finished an early version I was shocked to find out that the SDK still weighs the same. Only when I've educated myself about how does clang actually work - while writing this post - I realized that it's ok.

There's a big difference between a library and an executable. Library contains a lot of metadata that weighs a lot. Also, you want your static library to contain a lot of slices, including the simulator ones. The final executable strips all unneeded parts, making our demo executables with as much as 1 mb (with all the graphical assets etc.).

Also, Xcode 7 allows you to use bitcode which will reduce the executable on user's device even more. Remember to make sure you support bitcode in your library by using bitcode linker flags - if you don't, inform your users about that!

Watch out for symbol conflicts

Another big difference when building a library is that it's meant to be linked with someone else's code. Not only do you have to be careful to add prefixes to your classes to avoid symbol duplicates, but you have to make sure that you don't ship your dependencies (like AFNetworking) without making sure they're not going to clash with users using them too - It's not a problem if your code is open source and you're using CocoaPods, but it's a problem if you're shipping a compiled library. I've explained it in more detail in my other blog post.

Want to distribute compiled library through CocoaPods?

No problem! I didn't think it was possible, but it is and it's very easy. Our SDK is for commercial use only, so we couldn't open source it obviously. Check out our repo for the .podspec. 

Automate your process

It saves a lot of time to automate the building and distribution process. For a while I was using lipo to create a fat static library, commiting to GitHub and CocoaPods manually. I've written custom scripts that do that automatically now. It takes a couple of seconds to create a new release.

Here's my XCode script that builds both device and simulator, creating a fat library out of them and putting them in the release version folder.


Some things about the .bundle

If you need to ship your .framework with a .bundle (if you have some assets, or a CoreData model) there are some things you need to know.

The first thing that surprised me was that when we tried to publish an app with our SDK, it got rejected. Xcode automatically generates an executable and puts that executable info into the .plist file. You have to remove that executable, and .plist line from the .bundle in order for it to be accepted on iTunes. More here.

You can also distribute the .bundle file with CocoaPods.

Your users might not use some features. Create separate bundles, if you have a lot of assets, so users can choose which assets they need.

Some other tips

• Make sure you always distribute the release version
• Make sure you have a way to see what version of the SDK this is, just by looking into files. It's very useful
• Make sure you add the simulator slices
• If you're using a different server for testing, or any debug features and different for production use C macros and define a DEBUG identifier for debug builds so you make sure it won't get leaked into production like it just did for Vine.



piątek, 19 czerwca 2015

What's new in iOS9 and Xcode 7 - WWDC 2015

Objective C Nullability

This was actually introduced in XCode 6.3, but it's a failry new feature presented at WWDC 2015. You can set your parameter to be nonnull or nullable:



This code will produce a warning while building, and crash in runtime if the code that passes nil to name is executed.

It looks a lot nicer with property declarations.

You can use NS_ASSUME_NONNULL_BEGIN and NS_ASSUME_NONNULL_END macros to mark blocks of code where you want your parameters/properties to be nonnull at default.

There's also null_resetable that will mark your variable to be nullable, but will never return null.

Objective C Generics!

At last! The Apple gods have listened to us. I don't mind the fact that you can hold different object types in a collection. The worst thing about NSArray was that you never knew what it held, unless you... remembered. Now you can define a NSArray to hold a specific object and get a compiler warning if you try to put there something else.
That's not all! You can use generics in your own classes too!

UIStackView

It's a small great view. If you've ever programmed in some other frameworks with a WSIWYG you're probably already familiar with it: you put views inside this layout, and it places all the elements next to each other horizontally or vertically. It'll save us developers a lot of time. A great example is a form with 10 boxes: you've had to create so many constraints to keep all of them the way you wanted. Now you just put it in a UIStackView and that's it!

Here's a quick tutorial on UIStackView.

App Thining

If you have an iOS device with 8 GB of memory, you know the pain of disk management. That's why Apple introduced app thining. It's a group of operations that are supposed to make the bundle you download from the app store smaller.

Sliicing is used to make sure you only download assets needed for your particular device. It's that simple.

On-Demand Resources lets your assets to be downloaded dynamically, not initially with the bundle. It all works smoothly in the background so you get faster initial start, without any downsides.

BitCode is a powerful but invisible feature. You upload the intermediate LLVM code to Apple Store so they can recompile your code to machine code if they make some changes or add some new architecture.

Address Sanitizer


What do you do ? Sit down, and cry... Then sit down and cry some more trying to figure it out. That's the curse of unmanaged languages - low level memory errors are very hard to debug.

But in XCode 7 you can use the Address Sanitizer tool!


  • "You enable the address sanitizer in the build scheme. Once enabled, added instrumentation is built into the app to catch memory violations immediately, enabling you to inspect the problem right at the place where it occurs. Other diagnostic information is provided as well, such as the relationship between the faulty address and a valid object on the heap and allocation/deallocation information, which helps you pinpoint and fix the problem quickly. Address sanitizer is efficient—fast enough to be used regularly, as well as with interactive applications. It is supported on OS X, in the Simulator, and on iOS devices."