Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
With objective-c you obviously have to build against newer versions of the SDK to take advantage of any new features, but you can generally link a library built with an ancient version of Xcode without issues. With Swift obviously you have to rebuild all libraries every version.

Adbot
ADBOT LOVES YOU

Kallikrates
Jul 7, 2002
Pro Lurker
Wouldn't use the word obviously. Someone just coming into this platform might not know anything that makes using a library across operating systems possible, or impossible with swift.

Doctor w-rw-rw-
Jun 24, 2008

Dog on Fire posted:

I’d use this topic of frameworks to make a remarkably clumsy segue to my own question, albeit actually about libraries: are there any limitations on the iOS SDK version that was used to build a library that is used in a project?

To be more specific, we have a library that was built using Xcode 8.3.3. Will we have to rebuild it using Xcode 9 at some point? If so, will we have to do it when iOS 11 SDK will become required in July?

I think what you have to worry about is the ABI.

Objective-C’s ABI is stable; your codegen may be different but the interface should be compatible.

Swift’s ABI is obviously *not* stable yet (and is probably being prematurely stabilized), so it’s going to be incompatible between releases.

Objective-C++ is technically not a standard and defined pretty much entirely by implementation, but thankfully both C++ and Objective-C are stable enough anyhow.

blorpy
Jan 5, 2005

I'm a total swift newb. If I'm calling an Obj-C function that takes a `NSMutableData*` argument, is there any way to pass a Swift `Data`? I've tried several different things (`var`/`let`, type coercion) but nothing seems to make the compiler happy. Do I just need to use an `NSMutableData` instead?

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

blorpy posted:

I'm a total swift newb. If I'm calling an Obj-C function that takes a `NSMutableData*` argument, is there any way to pass a Swift `Data`? I've tried several different things (`var`/`let`, type coercion) but nothing seems to make the compiler happy. Do I just need to use an `NSMutableData` instead?

I believe you’re stuck with
code:
NSMutableData(data: yourSwiftData)

blorpy
Jan 5, 2005

pokeyman posted:

I believe you’re stuck with
code:
NSMutableData(data: yourSwiftData)

I see, thanks.

I'm maintaining an Obj-C library that has this NSMutableData argument. Will Swift devs chafe at having to instantiate an NSMutableData here instead of a Data, or is it pretty common to use these in Swift still?

FAT32 SHAMER
Aug 16, 2012



I’m probably going to be porting the android app I just built to iOS soon, except with the iOS look and feel etc instead of android. A friend told me that objective c is the way to go, however, I already mostly know swift thanks to spending three months writing UI and unit tests for a different app.

Is objective c still the best way to go for an app that is mostly just simple layouts pulling data from firebase or will swift suffice? I want it to be the best it can be while also maintainable and up to date

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

blorpy posted:

I'm maintaining an Obj-C library that has this NSMutableData argument. Will Swift devs chafe at having to instantiate an NSMutableData here instead of a Data, or is it pretty common to use these in Swift still?

Working with Foundation types as mutable reference types is something we're trying to move away from in Swift. If the argument isn't actually mutated by the library, demoting it to NSData will let Swift import it as Data and make your Swift users a lot happier.


FAT32 SHAMER posted:

I’m probably going to be porting the android app I just built to iOS soon, except with the iOS look and feel etc instead of android. A friend told me that objective c is the way to go, however, I already mostly know swift thanks to spending three months writing UI and unit tests for a different app.

Is objective c still the best way to go for an app that is mostly just simple layouts pulling data from firebase or will swift suffice? I want it to be the best it can be while also maintainable and up to date

I'm a biased source here, but I would definitely encourage you to write new projects in Swift.

blorpy
Jan 5, 2005

rjmccall posted:

Working with Foundation types as mutable reference types is something we're trying to move away from in Swift. If the argument isn't actually mutated by the library, demoting it to NSData will let Swift import it as Data and make your Swift users a lot happier.

The argument is passed in write-only, basically. This function lets the user get some data into a buffer without needing a new allocation. What's the idiomatic way of doing that?

Doctor w-rw-rw-
Jun 24, 2008

FAT32 SHAMER posted:

Is objective c still the best way to go for an app that is mostly just simple layouts pulling data from firebase or will swift suffice? I want it to be the best it can be while also maintainable and up to date

I’m a hardcore Objective-C zealot who thinks Swift isn’t up to par with Objective-C and won’t be for years.

With that said: Swift is a good enough fit for this. A simple app that pulls and lays out data will be fine, and maintainable and easy to update.

Just avoid CocoaPods. Use Carthage if you must to pull in external deps.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

blorpy posted:

The argument is passed in write-only, basically. This function lets the user get some data into a buffer without needing a new allocation. What's the idiomatic way of doing that?

I think the idiomatic API (that preserves that optimization) would take an inout Data. There's no way to get the importer to do that, so you'd have to write a bit of wrapper Swift.

blorpy
Jan 5, 2005

rjmccall posted:

I think the idiomatic API (that preserves that optimization) would take an inout Data. There's no way to get the importer to do that, so you'd have to write a bit of wrapper Swift.

That's sort of lousy. There's no annotation I can add to the Obj-C? Why isn't there a mechanism for this relatively common pattern?

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
At this point if you do not use Swift for a new project people will assume you are a weirdo and demand a justification.

blorpy
Jan 5, 2005

There's a pretty good reason /not/ to use Swift which is if you are interfacing with one or more C/C++ libraries. Having seen the syntax for both, I'd say you'd be crazy to interface extensively with C with Swift when Obj-C is already C.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

blorpy posted:

That's sort of lousy. There's no annotation I can add to the Obj-C? Why isn't there a mechanism for this relatively common pattern?

Feel free to ask for one; it's a reasonable enough request, because you're right, it's not an uncommon pattern.

On the other hand, if you're serious about supporting Swift clients, our experience has been that writing a little bit of wrapper code is basically inevitable; there's almost something that doesn't feel quite right in Swift as naturally imported, like a function that takes an out-parameter and returns a BOOL or an int status or something that should probably just return an optional. Accepting that sooner rather than later and just whipping up a little shim library will make both you and your users happier.

blorpy
Jan 5, 2005

rjmccall posted:

Feel free to ask for one; it's a reasonable enough request, because you're right, it's not an uncommon pattern.

On the other hand, if you're serious about supporting Swift clients, our experience has been that writing a little bit of wrapper code is basically inevitable; there's almost something that doesn't feel quite right in Swift as naturally imported, like a function that takes an out-parameter and returns a BOOL or an int status or something that should probably just return an optional. Accepting that sooner rather than later and just whipping up a little shim library will make both you and your users happier.

I'm not against the idea, but the Obj-C wrapper is already a binding for my C lib, so supporting another language on top just further reduces my leverage and removes my ability to support other bindings. Not to mention, it adds more surface area for things that can break and need tested and possible places where users experience headaches as things drift.

But your second paragraph makes me wonder if perhaps Swift users are actually just allocating a lot more than they need to. My lib has functions that do just return a new NSData* every time, and yes, it's certainly a nicer world to live in. But it also comes at some cost.

Stringent
Dec 22, 2004


image text goes here

Doctor w-rw-rw- posted:

I’m a hardcore Objective-C zealot who thinks Swift isn’t up to par with Objective-C and won’t be for years.

I hear Stockholm is lovely this time of year.

Seriously though, would you mind expanding on this? I'd love to hear more about Objective-C's strengths relative to Swift, I don't see it discussed that much.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

blorpy posted:

I'm not against the idea, but the Obj-C wrapper is already a binding for my C lib, so supporting another language on top just further reduces my leverage and removes my ability to support other bindings. Not to mention, it adds more surface area for things that can break and need tested and possible places where users experience headaches as things drift.

But your second paragraph makes me wonder if perhaps Swift users are actually just allocating a lot more than they need to. My lib has functions that do just return a new NSData* every time, and yes, it's certainly a nicer world to live in. But it also comes at some cost.

Your ObjC API is almost certainly doing a lot of extra allocations, yes, if you've made all your types ObjC classes and you're pervasively returning data by copying things into NSMutableData buffers. Importing that API into Swift doesn't add more allocation, but of course you still have all the allocation that ObjC is doing underneath. If you actually care about providing an optimal API to Swift users, idiomatic Swift does not require (or encourage) class allocation as a basic abstraction tool, so you would be much better served by "skipping the middle-man" and making a native Swift wrapper directly over your C library. Of course that's more work for you, both to write it initially and to maintain it, and I'm not going to lecture you and insist that any responsible API maintainer has to do it.

blorpy
Jan 5, 2005

rjmccall posted:

Your ObjC API is almost certainly doing a lot of extra allocations, yes, if you've made all your types ObjC classes and you're pervasively returning data by copying things into NSMutableData buffers. Importing that API into Swift doesn't add more allocation, but of course you still have all the allocation that ObjC is doing underneath. If you actually care about providing an optimal API to Swift users, idiomatic Swift does not require (or encourage) class allocation as a basic abstraction tool, so you would be much better served by "skipping the middle-man" and making a native Swift wrapper directly over your C library. Of course that's more work for you, both to write it initially and to maintain it, and I'm not going to lecture you and insist that any responsible API maintainer has to do it.

Can you clarify what you mean by 'class allocation'? My intention here was just that the user would allocate one NSMutableData and reuse it for the life of the program - the objc layer just sends mutableBytes down to C land. Would it make more sense to just ask for a raw uint8_t* (and length) instead?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
An NSMutableData allocates its buffer separately from the class instance — it has to, because the buffer can be resized, but you're still passing around the same NSMutableData pointer. That's an extra allocation that, say, Swift's Data type doesn't have to do. Of course, if the user can reuse a single NSMutableData for the entire their program, that overhead doesn't really matter.

If your API returns an unknown number of bytes, returning it by writing into a provided NSMutableData or returning an immutable NSData or whatever is a perfectly reasonable way of doing it. Someone who needs higher performance than that can always drop down to the C API.

It's hard to provide specific advice here about your API because you've carefully avoided telling me anything about it. That said, it sounds like your C API is a pretty low-level read API, like the read syscall, that reads the available data up to some arbitrary buffer size and then expects the caller to do something sensible if there's more data than fits in the buffer. I would expect an API that reads into an NSMutableData to read a complete "thing", which might be of arbitrary size, into the NSMutableData's buffer: it's not really designed to be a fixed-size buffer for an arbitrary data stream, so if that's what you're using it for, then yeah, I think you might be better served just taking a pointer and capacity and letting your callers worry about where that buffer comes from.

EDIT: What I'm getting at here is that the most important thing NSData adds is ownership of the buffer. It's useful for a function to know that it's specifically reading into an NSData if the function is going to read an unbounded amount of data and therefore can't promise to fit it in a pre-allocated buffer — if it needs to grow the buffer, something needs to know that that's happened and manage the buffer ownership, and that thing is the NSData object. If the function is just going to read some arbitrary chunk of bytes into a buffer of whatever size, it doesn't need to care about buffer ownership, so it might as well just take a raw buffer pointer and capacity instead of forcing its caller to mess around with NSData unnecessarily. The only reason to provide an NSData-specific interface in that case would be as a convenience if you know that your callers will frequently want the buffer wrapped in an NSData for some other reason.

rjmccall fucked around with this message at 08:47 on May 14, 2018

blorpy
Jan 5, 2005

Thanks, that's a lot to think about. And straight from the horse's mouth :D

withUnsafeMutableBytes looks like it would do what i want pretty nicely, though it feels sort of unwieldy. But I guess that's the point, scare the dev for what's about to happen?

tbh my reasoning for wrapping in NSMutableData was just because it seemed like there's no other mechanism to get a RC/ARC buffer of bytes in the standard library. I'm certainly not gonna make someone call malloc/free!

blorpy fucked around with this message at 08:51 on May 14, 2018

Doctor w-rw-rw-
Jun 24, 2008

Stringent posted:

I hear Stockholm is lovely this time of year.

Seriously though, would you mind expanding on this? I'd love to hear more about Objective-C's strengths relative to Swift, I don't see it discussed that much.
*shrug*

I'm partially disclosed on some stuff so getting super specific probably isn't something I can do. In broad strokes it's a good but not yet mature language; some of its best parts were ported to ObjC before its public release anyways (i.e. ObjC generics), the compiler needs some work, the package manager needs some work, the ABI needs some work, the toolchain needs some work, until recently its branching needed to sync up, etc. It's ready enough to use but it hasn't settled down yet.

ObjC is boring, predictable, decades old, and there's not a whole lot of mystery to it. Being a boring stable language with mostly boring stable tooling is part of what makes it 'superior' to me.

A project that is going to be boring and stable anyways can afford to use something new and Shiny.

FAT32 SHAMER
Aug 16, 2012



rjmccall posted:

I'm a biased source here, but I would definitely encourage you to write new projects in Swift.
Haha I'll make sure to bother you if i experience any exciting problems :D

Doctor w-rw-rw- posted:

I’m a hardcore Objective-C zealot who thinks Swift isn’t up to par with Objective-C and won’t be for years.

With that said: Swift is a good enough fit for this. A simple app that pulls and lays out data will be fine, and maintainable and easy to update.

Just avoid CocoaPods. Use Carthage if you must to pull in external deps.


What are some common QoL libraries I would want to check out anyways? Are there things like Butterknife or whatever for iOS?

Doctor w-rw-rw-
Jun 24, 2008

FAT32 SHAMER posted:

What are some common QoL libraries I would want to check out anyways? Are there things like Butterknife or whatever for iOS?
Android is harder to work with so those QoL libraries are more necessary. Use Swift and AutoLayout*. AutoLayout will only bite you in the rear end once you have enough of an rear end to be bitten, then you'll either start just writing code to do it (it's not that hard, and unlike Android, translating visual interface building -> code maps much better), start using a library to manage it (SnapKit, Cartography), stare into the abyss and use React Native, or go off the complete deep end and use Theolodite (ex-fb major contributor to CK rebuilt something like it in Swift).

Alamofire has been cited for a network library. Dunno, if you're just doing network and data, you don't need much.

* I also hate AutoLayout. It beat me as a child (early iOS developer). I avoid it whenever possible because doing it the code way is way easier to me. If I weren't asian I would have a neckbeard.

LP0 ON FIRE
Jan 25, 2006

beep boop

Doh004 posted:

Why are you mixing JS with Swift?

Because the Giphy Swift SDK does not seem to have any upload functionality, and at the same time Giphy wants to see screenshots of my implementation, using their code. Only JavaScript upload functionality seems to be available.

pokeyman posted:

Yeah you’re overcomplicating this. Grab Alamofire (iOS doesn’t have multipart/form-data), play with its request serialization options, and aim at the giphy endpoint until it works.

I'll check it out, thanks.. Ever since someone responded last week from Giphy that they'd send it to the right department, they never got back to me.

I'm not sure if I should go through all the work only for them to reject it.

blorpy
Jan 5, 2005

Did the behavior of pthread_cond_timedwait_relative_np change from iOS 9 to iOS 10? In the iOS 9 sim, I'm seeing it wait almost exactly twice as long as requested, while in the 10 sim it waits as long as requested.

Doh004
Apr 22, 2007

Mmmmm Donuts...

LP0 ON FIRE posted:

Because the Giphy Swift SDK does not seem to have any upload functionality, and at the same time Giphy wants to see screenshots of my implementation, using their code. Only JavaScript upload functionality seems to be available.

I take it this is for a job interview? If so, I know people would get a ton of extra points if they extended my SDK and added additional functionality to it. Maybe that's the point? :iiam:

*edit* Also, please stop writing new projects in Objective-C people.

LP0 ON FIRE
Jan 25, 2006

beep boop

Doh004 posted:

I take it this is for a job interview? If so, I know people would get a ton of extra points if they extended my SDK and added additional functionality to it. Maybe that's the point? :iiam:

Nope. I'm tempted, but at the same time they might not like what I did because it doesn't follow their documentation.

Toady
Jan 12, 2009

We're well past the point where Objective-C, as fond as I am of it, could be considered something other than legacy technology. It's clear where the focus is.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
To be clear, we do a lot more work on Swift in part because there’s a lot more work still to be done there. We don’t consider ObjC to be legacy; it’s just stable and complete enough that it doesn’t need massive new work at the language level. But we are filling in a few things.

Tools, well, you can always do more work on tools. But if we do tools work and it benefits Swift as well as ObjC, everyone treats it like it was just done for Swift.

We encourage people to write things in Swift because we think it’s a better language and you’ll be a happier, more conscientious, and more productive developer in it, and so users will get more and better apps.

FAT32 SHAMER
Aug 16, 2012



As long as I never have to look at pointers I’ll be extremely happy

blorpy
Jan 5, 2005

I am tearing my hair out on this `pthread_cond_timedwait_relative_np` thing. If I copy the code in question into a new test suite and run it just on its own, without even so much as including my Framework, it waits much longer than it should. But if I put it in a new project and test it there on its own, it's fine. I'm testing these against the same simulator.

The only way I can even imagine this being possible is that somehow loading my Framework is causing strange behavior. But it's hard to imagine how loading my framework could interfere with a core function like that. When I pause the debugger, the threads running are just the basic threads set up by iOS/the test runner. It doesn't include anything of mine. Wtf :confused:

Doc Block
Apr 15, 2003
Fun Shoe
IDK about that specific wait function, but isn’t the rule generally that wait/sleep/delay functions will wait for at least the requested amount of time, but may wait longer (due to being run on a preemptive multitasking operating system etc)?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

blorpy posted:

I am tearing my hair out on this `pthread_cond_timedwait_relative_np` thing. If I copy the code in question into a new test suite and run it just on its own, without even so much as including my Framework, it waits much longer than it should. But if I put it in a new project and test it there on its own, it's fine. I'm testing these against the same simulator.

The only way I can even imagine this being possible is that somehow loading my Framework is causing strange behavior. But it's hard to imagine how loading my framework could interfere with a core function like that. When I pause the debugger, the threads running are just the basic threads set up by iOS/the test runner. It doesn't include anything of mine. Wtf :confused:

Are you somehow using a different SDK in your existing project?

Toady
Jan 12, 2009

rjmccall posted:

To be clear, we do a lot more work on Swift in part because there’s a lot more work still to be done there. We don’t consider ObjC to be legacy; it’s just stable and complete enough that it doesn’t need massive new work at the language level. But we are filling in a few things.

Tools, well, you can always do more work on tools. But if we do tools work and it benefits Swift as well as ObjC, everyone treats it like it was just done for Swift.

We encourage people to write things in Swift because we think it’s a better language and you’ll be a happier, more conscientious, and more productive developer in it, and so users will get more and better apps.

I should have specified that "legacy" is what I think is the conventional wisdom among developers and employers.

blorpy
Jan 5, 2005

rjmccall posted:

Are you somehow using a different SDK in your existing project?

I don't think so, but I'm not quite familiar enough with Xcode to tell. Both projects have the same Base SDK and Deployment Target values though (or at least, the GUI reports as much).

Doc Block posted:

IDK about that specific wait function, but isn’t the rule generally that wait/sleep/delay functions will wait for at least the requested amount of time, but may wait longer (due to being run on a preemptive multitasking operating system etc)?

Yes but that's a broad rule of thumb. We're talking about a sleep that consistently adds on 100ms and only in a specific context. That's a bug.

blorpy
Jan 5, 2005

So it gets weirder. It turns out that /all/ sleeps are sleeping for longer than they should. It's not constrained to this one.

For example, [NSThread sleepForTimeInterval:0.001] sleeps for 50 ms, while [NSThread sleepForTimeInterval: 0.1] sleeps for 200ms and [NSThread sleepForTimeInterval: 1] sleeps for 1.1 seconds.

I can't imagine what could cause this, but it's fairly unfortunate when your tests need short sleeps for various tasks. :\

Doctor w-rw-rw-
Jun 24, 2008
Maybe it tells the runloop to wait on the next runloop run? Or something is blocking on a thread that waits on a runloop?

CeciPipePasPipe
Aug 18, 2004
This pipe not pipe!!

blorpy posted:

So it gets weirder. It turns out that /all/ sleeps are sleeping for longer than they should. It's not constrained to this one.

For example, [NSThread sleepForTimeInterval:0.001] sleeps for 50 ms, while [NSThread sleepForTimeInterval: 0.1] sleeps for 200ms and [NSThread sleepForTimeInterval: 1] sleeps for 1.1 seconds.

I can't imagine what could cause this, but it's fairly unfortunate when your tests need short sleeps for various tasks. :\

Could it be "timer coalescing" kicking in? I remember it being a "new cool feature bullet point" for a macOS release quite a few versions ago, https://www.apple.com/media/us/osx/2013/docs/OSX_Power_Efficiency_Technology_Overview.pdf

Maybe iOS 9 and 10 have different heuristics for how timers are coalesced? (and/or something on your iOS10 device causes timers to trigger more frequently/accurately)?

Adbot
ADBOT LOVES YOU

blorpy
Jan 5, 2005

CeciPipePasPipe posted:

Could it be "timer coalescing" kicking in? I remember it being a "new cool feature bullet point" for a macOS release quite a few versions ago, https://www.apple.com/media/us/osx/2013/docs/OSX_Power_Efficiency_Technology_Overview.pdf

Maybe iOS 9 and 10 have different heuristics for how timers are coalesced? (and/or something on your iOS10 device causes timers to trigger more frequently/accurately)?

That does seem plausible, but the paper suggests that running applications get 1ms timer granularity. Maybe Xcode has a bug that causes the wrong window to apply to unit tests in same cases? But still unclear why it happens in some projects and not in others.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply